int getOffset(int position) { return getOffsets()[position + getOffsetBase()]; }
@Override public boolean isNull(int position) { checkReadablePosition(position); boolean[] valueIsNull = getValueIsNull(); return valueIsNull == null ? false : valueIsNull[position + getOffsetBase()]; }
@Override public long getRegionSizeInBytes(int position, int length) { int positionCount = getPositionCount(); checkValidRegion(positionCount, position, length); int valueStart = getOffsets()[getOffsetBase() + position]; int valueEnd = getOffsets()[getOffsetBase() + position + length]; return getRawElementBlock().getRegionSizeInBytes(valueStart, valueEnd - valueStart) + ((Integer.BYTES + Byte.BYTES) * (long) length); }
@Override public long getPositionsSizeInBytes(boolean[] positions) { checkValidPositions(positions, getPositionCount()); boolean[] used = new boolean[getRawElementBlock().getPositionCount()]; int usedPositionCount = 0; for (int i = 0; i < positions.length; ++i) { if (positions[i]) { usedPositionCount++; int valueStart = getOffsets()[getOffsetBase() + i]; int valueEnd = getOffsets()[getOffsetBase() + i + 1]; for (int j = valueStart; j < valueEnd; ++j) { used[j] = true; } } } return getRawElementBlock().getPositionsSizeInBytes(used) + ((Integer.BYTES + Byte.BYTES) * (long) usedPositionCount); }
public static ColumnarArray toColumnarArray(Block block) { requireNonNull(block, "block is null"); if (block instanceof DictionaryBlock) { return toColumnarArray((DictionaryBlock) block); } if (block instanceof RunLengthEncodedBlock) { return toColumnarArray((RunLengthEncodedBlock) block); } if (!(block instanceof AbstractArrayBlock)) { throw new IllegalArgumentException("Invalid array block: " + block.getClass().getName()); } AbstractArrayBlock arrayBlock = (AbstractArrayBlock) block; Block elementsBlock = arrayBlock.getRawElementBlock(); // trim elements to just visible region int elementsOffset = 0; int elementsLength = 0; if (arrayBlock.getPositionCount() > 0) { elementsOffset = arrayBlock.getOffset(0); elementsLength = arrayBlock.getOffset(arrayBlock.getPositionCount()) - elementsOffset; } elementsBlock = elementsBlock.getRegion(elementsOffset, elementsLength); return new ColumnarArray(block, arrayBlock.getOffsetBase(), arrayBlock.getOffsets(), elementsBlock); }
@Override public Block getRegion(int position, int length) { int positionCount = getPositionCount(); checkValidRegion(positionCount, position, length); return createArrayBlockInternal( position + getOffsetBase(), length, getValueIsNull(), getOffsets(), getRawElementBlock()); }
@Override public Block copyRegion(int position, int length) { int positionCount = getPositionCount(); checkValidRegion(positionCount, position, length); int startValueOffset = getOffset(position); int endValueOffset = getOffset(position + length); Block newValues = getRawElementBlock().copyRegion(startValueOffset, endValueOffset - startValueOffset); int[] newOffsets = compactOffsets(getOffsets(), position + getOffsetBase(), length); boolean[] valueIsNull = getValueIsNull(); boolean[] newValueIsNull = valueIsNull == null ? null : compactArray(valueIsNull, position + getOffsetBase(), length); if (newValues == getRawElementBlock() && newOffsets == getOffsets() && newValueIsNull == valueIsNull) { return this; } return createArrayBlockInternal(0, length, newValueIsNull, newOffsets, newValues); }
@Override public void writeBlock(BlockEncodingSerde blockEncodingSerde, SliceOutput sliceOutput, Block block) { AbstractArrayBlock arrayBlock = (AbstractArrayBlock) block; int positionCount = arrayBlock.getPositionCount(); int offsetBase = arrayBlock.getOffsetBase(); int[] offsets = arrayBlock.getOffsets(); int valuesStartOffset = offsets[offsetBase]; int valuesEndOffset = offsets[offsetBase + positionCount]; Block values = arrayBlock.getRawElementBlock().getRegion(valuesStartOffset, valuesEndOffset - valuesStartOffset); blockEncodingSerde.writeBlock(sliceOutput, values); sliceOutput.appendInt(positionCount); for (int position = 0; position < positionCount + 1; position++) { sliceOutput.writeInt(offsets[offsetBase + position] - valuesStartOffset); } encodeNullsAsBits(sliceOutput, block); }