/**
* 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.hadoop.hive.ql.exec.vector;
import java.util.Arrays;
/**
* ColumnVector contains the shared structure for the sub-types,
* including NULL information, and whether this vector
* repeats, i.e. has all values the same, so only the first
* one is set. This is used to accelerate query performance
* by handling a whole vector in O(1) time when applicable.
*
* The fields are public by design since this is a performance-critical
* structure that is used in the inner loop of query execution.
*/
public abstract class ColumnVector {
/*
* The current kinds of column vectors.
*/
public static enum Type {
NONE, // Useful when the type of column vector has not be determined yet.
LONG,
DOUBLE,
BYTES,
DECIMAL,
TIMESTAMP,
INTERVAL_DAY_TIME,
STRUCT,
LIST,
MAP,
UNION
}
/*
* If hasNulls is true, then this array contains true if the value
* is null, otherwise false. The array is always allocated, so a batch can be re-used
* later and nulls added.
*/
public boolean[] isNull;
// If the whole column vector has no nulls, this is true, otherwise false.
public boolean noNulls;
/*
* True if same value repeats for whole column vector.
* If so, vector[0] holds the repeating value.
*/
public boolean isRepeating;
// Variables to hold state from before flattening so it can be easily restored.
private boolean preFlattenIsRepeating;
private boolean preFlattenNoNulls;
/**
* Constructor for super-class ColumnVector. This is not called directly,
* but used to initialize inherited fields.
*
* @param len Vector length
*/
public ColumnVector(int len) {
isNull = new boolean[len];
noNulls = true;
isRepeating = false;
preFlattenNoNulls = true;
preFlattenIsRepeating = false;
}
/**
* Resets the column to default state
* - fills the isNull array with false
* - sets noNulls to true
* - sets isRepeating to false
*/
public void reset() {
if (!noNulls) {
Arrays.fill(isNull, false);
}
noNulls = true;
isRepeating = false;
preFlattenNoNulls = true;
preFlattenIsRepeating = false;
}
/**
* Sets the isRepeating flag. Recurses over structs and unions so that the
* flags are set correctly.
* @param isRepeating
*/
public void setRepeating(boolean isRepeating) {
this.isRepeating = isRepeating;
}
abstract public void flatten(boolean selectedInUse, int[] sel, int size);
// Simplify vector by brute-force flattening noNulls if isRepeating
// This can be used to reduce combinatorial explosion of code paths in VectorExpressions
// with many arguments.
protected void flattenRepeatingNulls(boolean selectedInUse, int[] sel,
int size) {
boolean nullFillValue;
if (noNulls) {
nullFillValue = false;
} else {
nullFillValue = isNull[0];
}
if (selectedInUse) {
for (int j = 0; j < size; j++) {
int i = sel[j];
isNull[i] = nullFillValue;
}
} else {
Arrays.fill(isNull, 0, size, nullFillValue);
}
// all nulls are now explicit
noNulls = false;
}
protected void flattenNoNulls(boolean selectedInUse, int[] sel,
int size) {
if (noNulls) {
noNulls = false;
if (selectedInUse) {
for (int j = 0; j < size; j++) {
isNull[sel[j]] = false;
}
} else {
Arrays.fill(isNull, 0, size, false);
}
}
}
/**
* Restore the state of isRepeating and noNulls to what it was
* before flattening. This must only be called just after flattening
* and then evaluating a VectorExpression on the column vector.
* It is an optimization that allows other operations on the same
* column to continue to benefit from the isRepeating and noNulls
* indicators.
*/
public void unFlatten() {
isRepeating = preFlattenIsRepeating;
noNulls = preFlattenNoNulls;
}
// Record repeating and no nulls state to be restored later.
protected void flattenPush() {
preFlattenIsRepeating = isRepeating;
preFlattenNoNulls = noNulls;
}
/**
* Set the element in this column vector from the given input vector.
* This method can assume that the output does not have isRepeating set.
*/
public abstract void setElement(int outElementNum, int inputElementNum,
ColumnVector inputVector);
/**
* Initialize the column vector. This method can be overridden by specific column vector types.
* Use this method only if the individual type of the column vector is not known, otherwise its
* preferable to call specific initialization methods.
*/
public void init() {
// Do nothing by default
}
/**
* Ensure the ColumnVector can hold at least size values.
* This method is deliberately *not* recursive because the complex types
* can easily have more (or less) children than the upper levels.
* @param size the new minimum size
* @param preserveData should the old data be preserved?
*/
public void ensureSize(int size, boolean preserveData) {
if (isNull.length < size) {
boolean[] oldArray = isNull;
isNull = new boolean[size];
if (preserveData && !noNulls) {
if (isRepeating) {
isNull[0] = oldArray[0];
} else {
System.arraycopy(oldArray, 0, isNull, 0, oldArray.length);
}
}
}
}
/**
* Print the value for this column into the given string builder.
* @param buffer the buffer to print into
* @param row the id of the row to print
*/
public abstract void stringifyValue(StringBuilder buffer,
int row);
/**
* Shallow copy of the contents of this vector to the other vector;
* replaces other vector's values.
*/
public void shallowCopyTo(ColumnVector otherCv) {
otherCv.isNull = isNull;
otherCv.noNulls = noNulls;
otherCv.isRepeating = isRepeating;
otherCv.preFlattenIsRepeating = preFlattenIsRepeating;
otherCv.preFlattenNoNulls = preFlattenNoNulls;
}
}