public boolean append(BlockCursor cursor) { // the extra BYTE here is for the null flag int writableBytes = sliceOutput.writableBytes() - SIZE_OF_BYTE; boolean isNull = cursor.isNull(); if (type == Type.FIXED_INT_64) { if (writableBytes < SIZE_OF_LONG) { return false; } positionOffsets.add(sliceOutput.size()); sliceOutput.writeByte(isNull ? 1 : 0); sliceOutput.appendLong(isNull ? 0 : cursor.getLong()); } else if (type == Type.DOUBLE) { if (writableBytes < SIZE_OF_DOUBLE) { return false; } positionOffsets.add(sliceOutput.size()); sliceOutput.writeByte(isNull ? 1 : 0); sliceOutput.appendDouble(isNull ? 0 : cursor.getDouble()); } else if (type == Type.BOOLEAN) { if (writableBytes < SIZE_OF_BYTE) { return false; } positionOffsets.add(sliceOutput.size()); sliceOutput.writeByte(isNull ? 1 : 0); sliceOutput.writeByte(!isNull && cursor.getBoolean() ? 1 : 0); } else if (type == Type.VARIABLE_BINARY) { int sliceLength = isNull ? 0 : getVariableBinaryLength(cursor.getRawSlice(), cursor.getRawOffset()); if (writableBytes < SIZE_OF_INT + sliceLength) { return false; } int startingOffset = sliceOutput.size(); positionOffsets.add(startingOffset); sliceOutput.writeByte(isNull ? 1 : 0); sliceOutput.appendInt(sliceLength + SIZE_OF_BYTE + SIZE_OF_INT); if (!isNull) { sliceOutput.writeBytes( cursor.getRawSlice(), cursor.getRawOffset() + SIZE_OF_BYTE + SIZE_OF_INT, sliceLength); } } else { throw new IllegalArgumentException("Unsupported type " + type); } return true; }
private void recordNewPosition() { if (positions == offsets.length) { offsets = Arrays.copyOf(offsets, offsets.length * 2); } offsets[positions] = sliceOutput.size(); positions++; }
@Override public String toString() { StringBuilder sb = new StringBuilder("VariableWidthBlockBuilder{"); sb.append("positionCount=").append(positions); sb.append(", size=").append(sliceOutput.size()); sb.append('}'); return sb.toString(); }
private void entryAdded(int bytesWritten, boolean isNull) { if (valueIsNull.length <= positions) { growCapacity(); } valueIsNull[positions] = isNull; offsets[positions + 1] = sliceOutput.size(); positions++; blockBuilderStatus.addBytes(SIZE_OF_BYTE + SIZE_OF_INT + bytesWritten); }
@Override public void reset(BlockBuilderStatus blockBuilderStatus) { this.blockBuilderStatus = requireNonNull(blockBuilderStatus, "blockBuilderStatus is null"); int newSize = calculateBlockResetSize(positions); valueIsNull = new boolean[newSize]; offsets = new int[newSize + 1]; sliceOutput = new DynamicSliceOutput(calculateBlockResetSize(sliceOutput.size())); positions = 0; currentEntrySize = 0; updateArraysDataSize(); }
@Override public Block copyPositions(List<Integer> positions) { int finalLength = positions.stream().mapToInt(this::getLength).sum(); SliceOutput newSlice = Slices.allocate(finalLength).getOutput(); int[] newOffsets = new int[positions.size() + 1]; boolean[] newValueIsNull = new boolean[positions.size()]; for (int i = 0; i < positions.size(); i++) { int position = positions.get(i); if (isEntryNull(position)) { newValueIsNull[i] = true; } else { newSlice.appendBytes( sliceOutput .getUnderlyingSlice() .getBytes(getPositionOffset(position), getLength(position))); } newOffsets[i + 1] = newSlice.size(); } return new VariableWidthBlock(positions.size(), newSlice.slice(), newOffsets, newValueIsNull); }
@Override public int getSizeInBytes() { return sliceOutput.size(); }
private void entryAdded(int bytesWritten) { blockBuilderStatus.addBytes(SIZE_OF_BYTE + bytesWritten); if (sliceOutput.size() >= blockBuilderStatus.getMaxBlockSizeInBytes()) { blockBuilderStatus.setFull(); } }
@Override public int getSizeInBytes() { long arraysSizeInBytes = (Integer.BYTES + Byte.BYTES) * (long) positions; return intSaturatedCast(sliceOutput.size() + arraysSizeInBytes); }