Github user sachouche commented on a diff in the pull request:

    https://github.com/apache/drill/pull/1060#discussion_r162828863
  
    --- Diff: exec/vector/src/main/codegen/templates/NullableValueVectors.java 
---
    @@ -68,96 +85,441 @@
     
       private final UInt1Vector bits = new UInt1Vector(bitsField, allocator);
       private final ${valuesName} values = new ${minor.class}Vector(field, 
allocator);
    +  private final Mutator mutator      = new MutatorImpl();
    +  private final Accessor accessor    = new AccessorImpl();
    +
    +  <#if type.major == "VarLen" && minor.class == "VarChar">
    +  private final Mutator dupMutator   = new DupValsOnlyMutator();
    +  /** Accessor instance for duplicate values vector */
    +  private final Accessor dupAccessor = new DupValsOnlyAccessor();
    +  /** Optimization for cases where all values are identical */
    +  private boolean duplicateValuesOnly;
    +  /** logical number of values */
    +  private int logicalNumValues;
    +  /** logical value capacity */
    +  private int logicalValueCapacity;
    +  /** Mutator instance for duplicate values vector */
    +
    +  /** true if this vector holds the same value albeit repeated */
    +  public boolean isDuplicateValsOnly() {
    +    return duplicateValuesOnly;
    +  }
     
    -  private final Mutator mutator = new Mutator();
    -  private final Accessor accessor = new Accessor();
    +  /**
    +   * Sets this vector duplicate values mode; the {@link #clear()} method 
wil also be called as a side effect
    +   *  of this operation
    +   */
    +  public void setDuplicateValsOnly(boolean valsOnly) {
    +    clear();
    +    duplicateValuesOnly = valsOnly;
    +  }
     
    -  public ${className}(MaterializedField field, BufferAllocator allocator) {
    -    super(field, allocator);
    +  /** {@inheritDoc} */
    +  @Override
    +  public int getValueCapacity(){
    +    if (!isDuplicateValsOnly()) {
    +    return Math.min(bits.getValueCapacity(), values.getValueCapacity());
    +  }
    +    return logicalValueCapacity;
       }
     
    +  /** {@inheritDoc} */
       @Override
    -  public FieldReader getReader(){
    -    return reader;
    +  public void close() {
    +    bits.close();
    +    values.close();
    +    super.close();
       }
     
    +  /** {@inheritDoc} */
       @Override
    -  public int getValueCapacity(){
    -    return Math.min(bits.getValueCapacity(), values.getValueCapacity());
    +  public void clear() {
    +    bits.clear();
    +    values.clear();
    +    super.clear();
    +    if (isDuplicateValsOnly()) {
    +      logicalNumValues     = 0;
    +      logicalValueCapacity = 0;
    +      duplicateValuesOnly  = false;
    +    }
       }
     
    +  /** {@inheritDoc} */
       @Override
    -  public DrillBuf[] getBuffers(boolean clear) {
    -    final DrillBuf[] buffers = ObjectArrays.concat(bits.getBuffers(false), 
values.getBuffers(false), DrillBuf.class);
    -    if (clear) {
    -      for (final DrillBuf buffer:buffers) {
    -        buffer.retain(1);
    +  public int getBufferSizeFor(final int valueCount) {
    +    assert valueCount >= 0;
    +
    +    if (valueCount == 0) {
    +      return 0;
    +    }
    +    if (!isDuplicateValsOnly()) {
    +      return values.getBufferSizeFor(valueCount) + 
bits.getBufferSizeFor(valueCount);
    +    }
    +    return values.getBufferSizeFor(1) + bits.getBufferSizeFor(1);
    +  }
    +
    +  /** {@inheritDoc} */
    +  @Override
    +  public ${valuesName} getValuesVector() {
    +    if (!isDuplicateValsOnly()) {
    +      return values;
    +    }
    +    throw new UnsupportedOperationException();
    +  }
    +
    +  /** {@inheritDoc} */
    +  @Override
    +  public void setInitialCapacity(int numRecords) {
    +    assert numRecords >= 0;
    +    if (!isDuplicateValsOnly()) {
    +      bits.setInitialCapacity(numRecords);
    +      values.setInitialCapacity(numRecords);
    +    } else {
    +      bits.setInitialCapacity(numRecords > 0 ? 1 : 0);
    +      values.setInitialCapacity(numRecords > 0 ? 1 : 0);
    +      logicalValueCapacity = numRecords;
    +    }
    +  }
    +
    +  /** {@inheritDoc} */
    +  @Override
    +  public Accessor getAccessor() {
    +    if (!isDuplicateValsOnly()) {
    +      return accessor;
    +    }
    +    return dupAccessor;
    +  }
    +
    +  /** {@inheritDoc} */
    +  @Override
    +  public Mutator getMutator() {
    +    if (!isDuplicateValsOnly()) {
    +      return mutator;
    +    }
    +    return dupMutator;
    +  }
    +
    +  public void copyFrom(int fromIndex, int thisIndex, 
Nullable${minor.class}Vector from) {
    +    final Accessor fromAccessor = from.getAccessor();
    +    if (isDuplicateValsOnly()) {
    +      // We currently don't have a use-case where a target dup-vector is 
provisioned by a non-dup source vector
    +      assert isDuplicateValsOnly() == from.isDuplicateValsOnly();
    +
    +      if (logicalNumValues == from.logicalNumValues) {
    +        return; // NOOP as we only need to copy one entry
           }
    -      clear();
    +      getMutator().setValueCount(from.logicalNumValues);
    +      setInitialCapacity(from.logicalValueCapacity);
    +    }
    +
    +    if (!fromAccessor.isNull(fromIndex)) {
    +      fromIndex = !from.isDuplicateValsOnly() ? fromIndex : 0;
    +      mutator.fillEmpties(thisIndex);
    +      bits.copyFrom(fromIndex, thisIndex, from.bits);
    +      values.copyFrom(fromIndex, thisIndex, from.values);
    +    }
    +  }
    +
    +  public void copyFromSafe(int fromIndex, int thisIndex, 
${minor.class}Vector from) {
    +    // We currently don't have a use-case where a target dup-vector is 
provisioned by a non-dup source vector
    --- End diff --
    
    No error will occur as I added runtime rollback. I am also planning to 
support multiple different values using dictionary encoding.


---

Reply via email to