@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 getEstimatedDataSizeForStats(int position) { checkReadablePosition(position); if (isNull(position)) { return 0; } int startValueOffset = getOffset(position); int endValueOffset = getOffset(position + 1); Block rawElementBlock = getRawElementBlock(); long size = 0; for (int i = startValueOffset; i < endValueOffset; i++) { size += rawElementBlock.getEstimatedDataSizeForStats(i); } return size; }
@Override public boolean isNull(int position) { checkReadablePosition(position); boolean[] valueIsNull = getValueIsNull(); return valueIsNull == null ? false : valueIsNull[position + getOffsetBase()]; }
int getOffset(int position) { return getOffsets()[position + getOffsetBase()]; }
public <T> T apply(ArrayBlockFunction<T> function, int position) { checkReadablePosition(position); int startValueOffset = getOffset(position); int endValueOffset = getOffset(position + 1); return function.apply(getRawElementBlock(), startValueOffset, endValueOffset - startValueOffset); }
int positions = arrayBlock.getPositionCount(); if (positions == 0) { return bigintArrayData(new PrestoThriftBigintArray(null, null, null)); int[] sizes = null; for (int position = 0; position < positions; position++) { if (arrayBlock.isNull(position)) { if (nulls == null) { nulls = new boolean[positions]; sizes = new int[positions]; sizes[position] = arrayBlock.apply((valuesBlock, startPosition, length) -> length, position); .apply((valuesBlock, startPosition, length) -> PrestoThriftBigint.fromBlock(valuesBlock), 0) .getBigintData(); checkState(values != null, "values must be present");
@Override public Block copyPositions(int[] positions, int offset, int length) { checkArrayRange(positions, offset, length); int[] newOffsets = new int[length + 1]; boolean[] newValueIsNull = new boolean[length]; IntArrayList valuesPositions = new IntArrayList(); int newPosition = 0; for (int i = offset; i < offset + length; ++i) { int position = positions[i]; if (isNull(position)) { newValueIsNull[newPosition] = true; newOffsets[newPosition + 1] = newOffsets[newPosition]; } else { int valuesStartOffset = getOffset(position); int valuesEndOffset = getOffset(position + 1); int valuesLength = valuesEndOffset - valuesStartOffset; newOffsets[newPosition + 1] = newOffsets[newPosition] + valuesLength; for (int elementIndex = valuesStartOffset; elementIndex < valuesEndOffset; elementIndex++) { valuesPositions.add(elementIndex); } } newPosition++; } Block newValues = getRawElementBlock().copyPositions(valuesPositions.elements(), 0, valuesPositions.size()); return createArrayBlockInternal(0, length, newValueIsNull, newOffsets, newValues); }
private void checkReadablePosition(int position) { if (position < 0 || position >= getPositionCount()) { throw new IllegalArgumentException("position is not valid"); } }
@Override public Object getObjectValue(ConnectorSession session, Block block, int position) { if (block.isNull(position)) { return null; } if (block instanceof AbstractArrayBlock) { return ((AbstractArrayBlock) block).apply((valuesBlock, start, length) -> arrayBlockToObjectValues(session, valuesBlock, start, length), position); } else { Block arrayBlock = block.getObject(position, Block.class); return arrayBlockToObjectValues(session, arrayBlock, 0, arrayBlock.getPositionCount()); } }
@Override public BlockBuilder appendStructureInternal(Block block, int position) { if (!(block instanceof AbstractArrayBlock)) { throw new IllegalArgumentException(); } AbstractArrayBlock arrayBlock = (AbstractArrayBlock) block; BlockBuilder entryBuilder = beginBlockEntry(); int startValueOffset = arrayBlock.getOffset(position); int endValueOffset = arrayBlock.getOffset(position + 1); for (int i = startValueOffset; i < endValueOffset; i++) { if (arrayBlock.getRawElementBlock().isNull(i)) { entryBuilder.appendNull(); } else { arrayBlock.getRawElementBlock().writePositionTo(i, entryBuilder); } } closeEntry(); return this; }
@Override public void writePositionTo(int position, BlockBuilder blockBuilder) { checkReadablePosition(position); blockBuilder.appendStructureInternal(this, position); }
@Override public <T> T getObject(int position, Class<T> clazz) { if (clazz != Block.class) { throw new IllegalArgumentException("clazz must be Block.class"); } checkReadablePosition(position); int startValueOffset = getOffset(position); int endValueOffset = getOffset(position + 1); return clazz.cast(getRawElementBlock().getRegion(startValueOffset, endValueOffset - startValueOffset)); }
@Override public Block copyPositions(int[] positions, int offset, int length) { checkArrayRange(positions, offset, length); int[] newOffsets = new int[length + 1]; boolean[] newValueIsNull = new boolean[length]; IntArrayList valuesPositions = new IntArrayList(); int newPosition = 0; for (int i = offset; i < offset + length; ++i) { int position = positions[i]; if (isNull(position)) { newValueIsNull[newPosition] = true; newOffsets[newPosition + 1] = newOffsets[newPosition]; } else { int valuesStartOffset = getOffset(position); int valuesEndOffset = getOffset(position + 1); int valuesLength = valuesEndOffset - valuesStartOffset; newOffsets[newPosition + 1] = newOffsets[newPosition] + valuesLength; for (int elementIndex = valuesStartOffset; elementIndex < valuesEndOffset; elementIndex++) { valuesPositions.add(elementIndex); } } newPosition++; } Block newValues = getRawElementBlock().copyPositions(valuesPositions.elements(), 0, valuesPositions.size()); return createArrayBlockInternal(0, length, newValueIsNull, newOffsets, newValues); }
int getOffset(int position) { return getOffsets()[position + getOffsetBase()]; }
private void checkReadablePosition(int position) { if (position < 0 || position >= getPositionCount()) { throw new IllegalArgumentException("position is not valid"); } }
@Override public Object getObjectValue(ConnectorSession session, Block block, int position) { if (block.isNull(position)) { return null; } if (block instanceof AbstractArrayBlock) { return ((AbstractArrayBlock) block).apply((valuesBlock, start, length) -> arrayBlockToObjectValues(session, valuesBlock, start, length), position); } else { Block arrayBlock = block.getObject(position, Block.class); return arrayBlockToObjectValues(session, arrayBlock, 0, arrayBlock.getPositionCount()); } }
@Override public BlockBuilder appendStructureInternal(Block block, int position) { if (!(block instanceof AbstractArrayBlock)) { throw new IllegalArgumentException(); } AbstractArrayBlock arrayBlock = (AbstractArrayBlock) block; BlockBuilder entryBuilder = beginBlockEntry(); int startValueOffset = arrayBlock.getOffset(position); int endValueOffset = arrayBlock.getOffset(position + 1); for (int i = startValueOffset; i < endValueOffset; i++) { if (arrayBlock.getRawElementBlock().isNull(i)) { entryBuilder.appendNull(); } else { arrayBlock.getRawElementBlock().writePositionTo(i, entryBuilder); } } closeEntry(); return this; }
@Override public void writePositionTo(int position, BlockBuilder blockBuilder) { checkReadablePosition(position); blockBuilder.appendStructureInternal(this, position); }
@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 getSingleValueBlock(int position) { checkReadablePosition(position); int startValueOffset = getOffset(position); int valueLength = getOffset(position + 1) - startValueOffset; Block newValues = getRawElementBlock().copyRegion(startValueOffset, valueLength); return createArrayBlockInternal( 0, 1, new boolean[] {isNull(position)}, new int[] {0, valueLength}, newValues); }