blob: af4664cadb1f5c272555b08ced41fb31fa81f80c [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.drill.exec.vector.complex;
import org.apache.drill.common.types.TypeProtos;
import org.apache.drill.common.types.Types;
import org.apache.drill.exec.exception.OutOfMemoryException;
import org.apache.drill.exec.expr.holders.RepeatedDictHolder;
import org.apache.drill.exec.memory.BufferAllocator;
import org.apache.drill.exec.record.MaterializedField;
import org.apache.drill.exec.record.TransferPair;
import org.apache.drill.exec.util.CallBack;
import org.apache.drill.exec.util.JsonStringArrayList;
import org.apache.drill.exec.vector.ValueVector;
import org.apache.drill.exec.vector.complex.impl.RepeatedDictReaderImpl;
import org.apache.drill.exec.vector.complex.reader.FieldReader;
import java.util.List;
public class RepeatedDictVector extends BaseRepeatedValueVector {
public final static TypeProtos.MajorType TYPE = Types.repeated(TypeProtos.MinorType.DICT);
private final static String DICT_VECTOR_NAME = "$inner$";
private final static MaterializedField DICT_VECTOR_FIELD =
MaterializedField.create(DICT_VECTOR_NAME, DictVector.TYPE);
private final Accessor accessor = new Accessor();
private final Mutator mutator = new Mutator();
private final FieldReader reader = new RepeatedDictReaderImpl(this);
private final EmptyValuePopulator emptyPopulator;
public RepeatedDictVector(String path, BufferAllocator allocator) {
this(MaterializedField.create(path, TYPE), allocator, null);
}
public RepeatedDictVector(MaterializedField field, BufferAllocator allocator, CallBack callback) {
super(field, allocator, new DictVector(DICT_VECTOR_FIELD, allocator, callback));
emptyPopulator = new EmptyValuePopulator(getOffsetVector());
}
@Override
public void allocateNew() throws OutOfMemoryException {
if (!allocateNewSafe()) {
throw new OutOfMemoryException();
}
}
@Override
public TransferPair getTransferPair(String ref, BufferAllocator allocator) {
return makeTransferPair(new RepeatedDictVector(ref, allocator));
}
@Override
public TransferPair makeTransferPair(ValueVector target) {
return new RepeatedDictTransferPair((RepeatedDictVector) target);
}
public class RepeatedDictTransferPair extends BaseRepeatedValueVectorTransferPair<RepeatedDictVector> {
public RepeatedDictTransferPair(RepeatedDictVector target) {
super(target);
}
@Override
public void copyValueSafe(int srcIndex, int destIndex) {
final RepeatedDictHolder holder = new RepeatedDictHolder();
getAccessor().get(srcIndex, holder);
target.emptyPopulator.populate(destIndex+1);
copyValueSafe(destIndex, holder.start, holder.end);
}
}
@Override
public MaterializedField getField() {
MaterializedField field = this.field.clone();
field.addChild(vector.getField());
return field;
}
@Override
public Accessor getAccessor() {
return accessor;
}
@Override
public Mutator getMutator() {
return mutator;
}
@Override
public FieldReader getReader() {
return reader;
}
@Override
public void copyEntry(int toIndex, ValueVector from, int fromIndex) {
RepeatedDictTransferPair pair = (RepeatedDictTransferPair) from.makeTransferPair(this);
pair.copyValueSafe(fromIndex, toIndex);
}
public class Accessor extends BaseRepeatedValueVector.BaseRepeatedAccessor {
@Override
public Object getObject(int index) {
List<Object> list = new JsonStringArrayList<>();
int start = offsets.getAccessor().get(index);
int end = offsets.getAccessor().get(index + 1);
for (int i = start; i < end; i++) {
list.add(vector.getAccessor().getObject(i));
}
return list;
}
public void get(int index, RepeatedDictHolder holder) {
int valueCapacity = getValueCapacity();
assert index < valueCapacity :
String.format("Attempted to access index %d when value capacity is %d", index, valueCapacity);
holder.vector = RepeatedDictVector.this;
holder.reader = reader;
holder.start = getOffsetVector().getAccessor().get(index);
holder.end = getOffsetVector().getAccessor().get(index + 1);
}
}
public class Mutator extends BaseRepeatedValueVector.BaseRepeatedMutator {
@Override
public void startNewValue(int index) {
emptyPopulator.populate(index + 1);
offsets.getMutator().setSafe(index + 1, offsets.getAccessor().get(index));
}
@Override
public void setValueCount(int topLevelValueCount) {
emptyPopulator.populate(topLevelValueCount);
offsets.getMutator().setValueCount(topLevelValueCount == 0 ? 0 : topLevelValueCount + 1);
int childValueCount = offsets.getAccessor().get(topLevelValueCount);
vector.getMutator().setValueCount(childValueCount);
}
public int add(int index) {
int prevEnd = offsets.getAccessor().get(index + 1);
offsets.getMutator().setSafe(index + 1, prevEnd + 1);
return prevEnd;
}
}
}