/**
* 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;
/**
* The representation of a vectorized column of map objects.
*
* Each map is composed of a range of elements in the underlying child
* ColumnVector. The range for map i is
* offsets[i]..offsets[i]+lengths[i]-1 inclusive.
*/
public class MapColumnVector extends MultiValuedColumnVector {
public ColumnVector keys;
public ColumnVector values;
public MapColumnVector() {
this(VectorizedRowBatch.DEFAULT_SIZE, null, null);
}
/**
* Constructor for MapColumnVector
*
* @param len Vector length
* @param keys The keys column vector
* @param values The values column vector
*/
public MapColumnVector(int len, ColumnVector keys, ColumnVector values) {
super(len);
this.keys = keys;
this.values = values;
}
@Override
protected void childFlatten(boolean useSelected, int[] selected, int size) {
keys.flatten(useSelected, selected, size);
values.flatten(useSelected, selected, size);
}
@Override
public void setElement(int outElementNum, int inputElementNum,
ColumnVector inputVector) {
if (inputVector.isRepeating) {
inputElementNum = 0;
}
if (!inputVector.noNulls && inputVector.isNull[inputElementNum]) {
isNull[outElementNum] = true;
noNulls = false;
} else {
MapColumnVector input = (MapColumnVector) inputVector;
isNull[outElementNum] = false;
int offset = childCount;
int length = (int) input.lengths[inputElementNum];
int inputOffset = (int) input.offsets[inputElementNum];
offsets[outElementNum] = offset;
childCount += length;
lengths[outElementNum] = length;
keys.ensureSize(childCount, true);
values.ensureSize(childCount, true);
for (int i = 0; i < length; ++i) {
keys.setElement(i + offset, inputOffset + i, input.keys);
values.setElement(i + offset, inputOffset + i, input.values);
}
}
}
@Override
public void stringifyValue(StringBuilder buffer, int row) {
if (isRepeating) {
row = 0;
}
if (noNulls || !isNull[row]) {
buffer.append('[');
boolean isFirst = true;
for(long i=offsets[row]; i < offsets[row] + lengths[row]; ++i) {
if (isFirst) {
isFirst = false;
} else {
buffer.append(", ");
}
buffer.append("{\"key\": ");
keys.stringifyValue(buffer, (int) i);
buffer.append(", \"value\": ");
values.stringifyValue(buffer, (int) i);
buffer.append('}');
}
buffer.append(']');
} else {
buffer.append("null");
}
}
@Override
public void init() {
super.init();
keys.init();
values.init();
}
@Override
public void reset() {
super.reset();
keys.reset();
values.reset();
}
@Override
public void unFlatten() {
super.unFlatten();
if (!isRepeating || noNulls || !isNull[0]) {
keys.unFlatten();
values.unFlatten();
}
}
}