blob: 462ddf08d4f0899d41169e01e70527fc15b03ad5 [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.store.parquet.columnreaders.batchsizing;
import io.netty.buffer.DrillBuf;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.drill.common.map.CaseInsensitiveMap;
import org.apache.drill.exec.memory.BufferAllocator;
import org.apache.drill.exec.record.MaterializedField;
import org.apache.drill.exec.util.record.RecordBatchStats.RecordBatchStatsContext;
import org.apache.drill.exec.vector.ValueVector;
import org.apache.drill.exec.vector.VariableWidthVector;
/**
* Logic for handling batch record overflow; this class essentially serializes overflow vector data in a
* compact manner so that it is reused for building the next record batch.
*/
public final class RecordBatchOverflow {
/** Record Overflow Definition */
final RecordOverflowDefinition recordOverflowDef;
/** Buffer allocator */
final BufferAllocator allocator;
/**
* @param allocator buffer allocator
* @param batchStatsContext batch statistics context
* @return new builder object
*/
public static Builder newBuilder(BufferAllocator allocator, RecordBatchStatsContext batchStatsContext) {
return new Builder(allocator, batchStatsContext);
}
/**
* @return the record overflow definition
*/
public RecordOverflowDefinition getRecordOverflowDefinition() {
return recordOverflowDef;
}
/**
* Constructor.
*
* @param recordOverflowDef record overflow definition
* @param allocator buffer allocator
*/
private RecordBatchOverflow(RecordOverflowDefinition recordOverflowDef,
BufferAllocator allocator) {
this.recordOverflowDef = recordOverflowDef;
this.allocator = allocator;
}
// ----------------------------------------------------------------------------
// Inner Data Structure
// ----------------------------------------------------------------------------
/** Builder class to construct a {@link RecordBatchOverflow} object */
public static final class Builder {
/** Field overflow list */
private final List<FieldOverflowEntry> fieldOverflowEntries = new ArrayList<FieldOverflowEntry>();
/** Buffer allocator */
private final BufferAllocator allocator;
/** Batch statistics context */
private final RecordBatchStatsContext batchStatsContext;
/**
* Build class to construct a {@link RecordBatchOverflow} object.
* @param allocator buffer allocator
* @param batchStatsContext batch statistics context
*/
private Builder(BufferAllocator allocator, RecordBatchStatsContext batchStatsContext) {
this.allocator = allocator;
this.batchStatsContext = batchStatsContext;
}
/**
* Add an overflow field to this batch record overflow object; note that currently only
* variable numValues objects are supported.
*
* @param vector a value vector with overflow values
* @param firstValueIdx index of first overflow value
* @param numValues the number of overflow values starting at index "firstValueIdx"
*/
public void addFieldOverflow(ValueVector vector, int firstValueIdx, int numValues) {
assert vector instanceof VariableWidthVector;
fieldOverflowEntries.add(new FieldOverflowEntry(vector, firstValueIdx, numValues));
}
/**
* @return a new built {link BatchRecordOverflow} object instance
*/
public RecordBatchOverflow build() {
RecordOverflowContainer overflowContainer = OverflowSerDeUtil.serialize(fieldOverflowEntries, allocator, batchStatsContext);
RecordBatchOverflow result = new RecordBatchOverflow(overflowContainer.recordOverflowDef, allocator);
return result;
}
} // End of Builder
/** Field overflow entry */
static final class FieldOverflowEntry {
/** A value vector with overflow values */
final ValueVector vector;
/** index of first overflow value */
final int firstValueIdx;
/** The number of overflow values starting at index "firstValueIdx" */
final int numValues;
/**
* Field overflow entry constructor
*
* @param vector a value vector with overflow values
* @param firstValueIdx index of first overflow value
* @param numValues the number of overflow values starting at index "firstValueIdx"
*/
private FieldOverflowEntry(ValueVector vector, int firstValueIdx, int numValues) {
this.vector = vector;
this.firstValueIdx = firstValueIdx;
this.numValues = numValues;
}
} // End of FieldOverflowEntry
/** Record batch definition */
public static final class RecordOverflowDefinition {
private final Map<String, FieldOverflowDefinition> fieldOverflowDefs = CaseInsensitiveMap.newHashMap();
public Map<String, FieldOverflowDefinition> getFieldOverflowDefs() {
return fieldOverflowDefs;
}
} // End of RecordOverflowDefinition
/** Field overflow definition */
public static final class FieldOverflowDefinition {
/** Materialized field */
public final MaterializedField field;
/** Number of values */
public final int numValues;
/** Data byte length */
public final int dataByteLen;
/** DrillBuf where the serialized data is stored */
public final DrillBuf buffer;
/**
* Field overflow definition constructor
* @param field materialized field
* @param numValues number of values
* @param dataByteLen data byte length
* @param buffer DrillBuf where the serialized data is stored
*/
FieldOverflowDefinition(MaterializedField field, int numValues, int dataByteLen, DrillBuf buffer) {
this.field = field;
this.numValues = numValues;
this.dataByteLen = dataByteLen;
this.buffer = buffer;
}
} // End of FieldOverflowDefinition
/** Record overflow container */
static final class RecordOverflowContainer {
/** Record Overflow Definition */
final RecordOverflowDefinition recordOverflowDef = new RecordOverflowDefinition();
} // End of RecordOverflowContainer
}