Skip to content

Commit 595c265

Browse files
committed
Remove null-suppression in block serialization
1 parent 6f313c9 commit 595c265

File tree

8 files changed

+48
-300
lines changed

8 files changed

+48
-300
lines changed

core/trino-spi/src/main/java/io/trino/spi/block/ArrayBlockEncoding.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static io.trino.spi.block.ArrayBlock.createArrayBlockInternal;
2020
import static io.trino.spi.block.EncoderUtil.decodeNullBits;
2121
import static io.trino.spi.block.EncoderUtil.encodeNullsAsBits;
22+
import static io.trino.spi.block.EncoderUtil.retrieveNullBits;
2223

2324
public class ArrayBlockEncoding
2425
implements BlockEncoding
@@ -67,7 +68,12 @@ public ArrayBlock readBlock(BlockEncodingSerde blockEncodingSerde, SliceInput sl
6768
int positionCount = sliceInput.readInt();
6869
int[] offsets = new int[positionCount + 1];
6970
sliceInput.readInts(offsets);
70-
boolean[] valueIsNull = decodeNullBits(sliceInput, positionCount).orElse(null);
71+
byte[] valueIsNullPacked = retrieveNullBits(sliceInput, positionCount);
72+
if (valueIsNullPacked == null) {
73+
return createArrayBlockInternal(0, positionCount, null, offsets, values);
74+
}
75+
76+
boolean[] valueIsNull = decodeNullBits(valueIsNullPacked, positionCount);
7177
return createArrayBlockInternal(0, positionCount, valueIsNull, offsets, values);
7278
}
7379
}

core/trino-spi/src/main/java/io/trino/spi/block/ByteArrayBlockEncoding.java

Lines changed: 2 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import static io.trino.spi.block.EncoderUtil.decodeNullBits;
2222
import static io.trino.spi.block.EncoderUtil.encodeNullsAsBits;
2323
import static io.trino.spi.block.EncoderUtil.retrieveNullBits;
24-
import static java.lang.System.arraycopy;
2524
import static java.util.Objects.checkFromIndexSize;
2625

2726
public class ByteArrayBlockEncoding
@@ -56,20 +55,7 @@ public void writeBlock(BlockEncodingSerde blockEncodingSerde, SliceOutput sliceO
5655

5756
encodeNullsAsBits(sliceOutput, isNull, rawOffset, positionCount);
5857

59-
if (isNull == null) {
60-
sliceOutput.writeBytes(rawValues, rawOffset, positionCount);
61-
}
62-
else {
63-
byte[] valuesWithoutNull = new byte[positionCount];
64-
int nonNullPositionCount = 0;
65-
for (int i = 0; i < positionCount; i++) {
66-
valuesWithoutNull[nonNullPositionCount] = rawValues[i + rawOffset];
67-
nonNullPositionCount += isNull[i + rawOffset] ? 0 : 1;
68-
}
69-
70-
sliceOutput.writeInt(nonNullPositionCount);
71-
sliceOutput.writeBytes(valuesWithoutNull, 0, nonNullPositionCount);
72-
}
58+
sliceOutput.writeBytes(rawValues, rawOffset, positionCount);
7359
}
7460

7561
@Override
@@ -79,42 +65,13 @@ public ByteArrayBlock readBlock(BlockEncodingSerde blockEncodingSerde, SliceInpu
7965

8066
byte[] valueIsNullPacked = retrieveNullBits(sliceInput, positionCount);
8167
byte[] values = new byte[positionCount];
68+
sliceInput.readBytes(Slices.wrappedBuffer(values));
8269

8370
if (valueIsNullPacked == null) {
84-
sliceInput.readBytes(Slices.wrappedBuffer(values));
8571
return new ByteArrayBlock(0, positionCount, null, values);
8672
}
8773
boolean[] valueIsNull = decodeNullBits(valueIsNullPacked, positionCount);
8874

89-
int nonNullPositionCount = sliceInput.readInt();
90-
sliceInput.readBytes(Slices.wrappedBuffer(values, 0, nonNullPositionCount));
91-
int position = nonNullPositionCount - 1;
92-
93-
// Handle Last (positionCount % 8) values
94-
for (int i = positionCount - 1; i >= (positionCount & ~0b111) && position >= 0; i--) {
95-
values[i] = values[position];
96-
if (!valueIsNull[i]) {
97-
position--;
98-
}
99-
}
100-
101-
// Handle the remaining positions.
102-
for (int i = (positionCount & ~0b111) - 8; i >= 0 && position >= 0; i -= 8) {
103-
byte packed = valueIsNullPacked[i >>> 3];
104-
if (packed == 0) { // Only values
105-
arraycopy(values, position - 7, values, i, 8);
106-
position -= 8;
107-
}
108-
else if (packed != -1) { // At least one non-null
109-
for (int j = i + 7; j >= i && position >= 0; j--) {
110-
values[j] = values[position];
111-
if (!valueIsNull[j]) {
112-
position--;
113-
}
114-
}
115-
}
116-
// Do nothing if there are only nulls
117-
}
11875
return new ByteArrayBlock(0, positionCount, valueIsNull, values);
11976
}
12077
}

core/trino-spi/src/main/java/io/trino/spi/block/Fixed12BlockEncoding.java

Lines changed: 10 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import static io.trino.spi.block.EncoderUtil.decodeNullBits;
2121
import static io.trino.spi.block.EncoderUtil.encodeNullsAsBits;
22+
import static io.trino.spi.block.EncoderUtil.retrieveNullBits;
2223
import static java.util.Objects.checkFromIndexSize;
2324

2425
public class Fixed12BlockEncoding
@@ -53,47 +54,24 @@ public void writeBlock(BlockEncodingSerde blockEncodingSerde, SliceOutput sliceO
5354

5455
encodeNullsAsBits(sliceOutput, isNull, rawArrayOffset, positionCount);
5556

56-
if (isNull == null) {
57-
sliceOutput.writeInts(rawValues, rawArrayOffset * 3, positionCount * 3);
58-
}
59-
else {
60-
int[] valuesWithoutNull = new int[positionCount * 3];
61-
int nonNullPositionCount = 0;
62-
for (int i = 0; i < positionCount; i++) {
63-
int rawIntOffset = (i + rawArrayOffset) * 3;
64-
valuesWithoutNull[nonNullPositionCount] = rawValues[rawIntOffset];
65-
valuesWithoutNull[nonNullPositionCount + 1] = rawValues[rawIntOffset + 1];
66-
valuesWithoutNull[nonNullPositionCount + 2] = rawValues[rawIntOffset + 2];
67-
nonNullPositionCount += isNull[i + rawArrayOffset] ? 0 : 3;
68-
}
69-
70-
sliceOutput.writeInt(nonNullPositionCount / 3);
71-
sliceOutput.writeInts(valuesWithoutNull, 0, nonNullPositionCount);
72-
}
57+
sliceOutput.writeInts(rawValues, rawArrayOffset * 3, positionCount * 3);
7358
}
7459

7560
@Override
7661
public Fixed12Block readBlock(BlockEncodingSerde blockEncodingSerde, SliceInput sliceInput)
7762
{
7863
int positionCount = sliceInput.readInt();
7964

80-
boolean[] valueIsNull = decodeNullBits(sliceInput, positionCount).orElse(null);
81-
65+
byte[] valueIsNullPacked = retrieveNullBits(sliceInput, positionCount);
8266
int[] values = new int[positionCount * 3];
83-
if (valueIsNull == null) {
84-
sliceInput.readInts(values);
85-
}
86-
else {
87-
int nonNullPositionCount = sliceInput.readInt();
88-
sliceInput.readInts(values, 0, nonNullPositionCount * 3);
89-
int position = 3 * (nonNullPositionCount - 1);
90-
for (int i = positionCount - 1; i >= 0 && position >= 0; i--) {
91-
System.arraycopy(values, position, values, 3 * i, 3);
92-
if (!valueIsNull[i]) {
93-
position -= 3;
94-
}
95-
}
67+
sliceInput.readInts(values);
68+
69+
if (valueIsNullPacked == null) {
70+
return new Fixed12Block(0, positionCount, null, values);
9671
}
72+
73+
boolean[] valueIsNull = decodeNullBits(valueIsNullPacked, positionCount);
74+
9775
return new Fixed12Block(0, positionCount, valueIsNull, values);
9876
}
9977
}

core/trino-spi/src/main/java/io/trino/spi/block/Int128ArrayBlockEncoding.java

Lines changed: 9 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import static io.trino.spi.block.EncoderUtil.decodeNullBits;
2121
import static io.trino.spi.block.EncoderUtil.encodeNullsAsBits;
22+
import static io.trino.spi.block.EncoderUtil.retrieveNullBits;
2223
import static java.util.Objects.checkFromIndexSize;
2324

2425
public class Int128ArrayBlockEncoding
@@ -53,46 +54,24 @@ public void writeBlock(BlockEncodingSerde blockEncodingSerde, SliceOutput sliceO
5354

5455
encodeNullsAsBits(sliceOutput, isNull, rawArrayOffset, positionCount);
5556

56-
if (isNull == null) {
57-
sliceOutput.writeLongs(rawValues, rawArrayOffset * 2, positionCount * 2);
58-
}
59-
else {
60-
long[] valuesWithoutNull = new long[positionCount * 2];
61-
int nonNullPositionCount = 0;
62-
for (int i = 0; i < positionCount; i++) {
63-
int rawValuesIndex = (i + rawArrayOffset) * 2;
64-
valuesWithoutNull[nonNullPositionCount] = rawValues[rawValuesIndex];
65-
valuesWithoutNull[nonNullPositionCount + 1] = rawValues[rawValuesIndex + 1];
66-
nonNullPositionCount += isNull[i + rawArrayOffset] ? 0 : 2;
67-
}
68-
69-
sliceOutput.writeInt(nonNullPositionCount / 2);
70-
sliceOutput.writeLongs(valuesWithoutNull, 0, nonNullPositionCount);
71-
}
57+
sliceOutput.writeLongs(rawValues, rawArrayOffset * 2, positionCount * 2);
7258
}
7359

7460
@Override
7561
public Int128ArrayBlock readBlock(BlockEncodingSerde blockEncodingSerde, SliceInput sliceInput)
7662
{
7763
int positionCount = sliceInput.readInt();
7864

79-
boolean[] valueIsNull = decodeNullBits(sliceInput, positionCount).orElse(null);
80-
65+
byte[] valueIsNullPacked = retrieveNullBits(sliceInput, positionCount);
8166
long[] values = new long[positionCount * 2];
82-
if (valueIsNull == null) {
67+
68+
if (valueIsNullPacked == null) {
8369
sliceInput.readLongs(values);
70+
return new Int128ArrayBlock(0, positionCount, null, values);
8471
}
85-
else {
86-
int nonNullPositionCount = sliceInput.readInt();
87-
sliceInput.readLongs(values, 0, nonNullPositionCount * 2);
88-
int position = 2 * (nonNullPositionCount - 1);
89-
for (int i = positionCount - 1; i >= 0 && position >= 0; i--) {
90-
System.arraycopy(values, position, values, 2 * i, 2);
91-
if (!valueIsNull[i]) {
92-
position -= 2;
93-
}
94-
}
95-
}
72+
boolean[] valueIsNull = decodeNullBits(valueIsNullPacked, positionCount);
73+
74+
sliceInput.readLongs(values);
9675

9776
return new Int128ArrayBlock(0, positionCount, valueIsNull, values);
9877
}

core/trino-spi/src/main/java/io/trino/spi/block/IntArrayBlockEncoding.java

Lines changed: 2 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import static io.trino.spi.block.EncoderUtil.decodeNullBits;
2121
import static io.trino.spi.block.EncoderUtil.encodeNullsAsBits;
2222
import static io.trino.spi.block.EncoderUtil.retrieveNullBits;
23-
import static java.lang.System.arraycopy;
2423
import static java.util.Objects.checkFromIndexSize;
2524

2625
public class IntArrayBlockEncoding
@@ -55,20 +54,7 @@ public void writeBlock(BlockEncodingSerde blockEncodingSerde, SliceOutput sliceO
5554

5655
encodeNullsAsBits(sliceOutput, isNull, rawOffset, positionCount);
5756

58-
if (isNull == null) {
59-
sliceOutput.writeInts(rawValues, rawOffset, positionCount);
60-
}
61-
else {
62-
int[] valuesWithoutNull = new int[positionCount];
63-
int nonNullPositionCount = 0;
64-
for (int i = 0; i < positionCount; i++) {
65-
valuesWithoutNull[nonNullPositionCount] = rawValues[i + rawOffset];
66-
nonNullPositionCount += isNull[i + rawOffset] ? 0 : 1;
67-
}
68-
69-
sliceOutput.writeInt(nonNullPositionCount);
70-
sliceOutput.writeInts(valuesWithoutNull, 0, nonNullPositionCount);
71-
}
57+
sliceOutput.writeInts(rawValues, rawOffset, positionCount);
7258
}
7359

7460
@Override
@@ -78,42 +64,13 @@ public IntArrayBlock readBlock(BlockEncodingSerde blockEncodingSerde, SliceInput
7864

7965
byte[] valueIsNullPacked = retrieveNullBits(sliceInput, positionCount);
8066
int[] values = new int[positionCount];
67+
sliceInput.readInts(values);
8168

8269
if (valueIsNullPacked == null) {
83-
sliceInput.readInts(values);
8470
return new IntArrayBlock(0, positionCount, null, values);
8571
}
8672
boolean[] valueIsNull = decodeNullBits(valueIsNullPacked, positionCount);
8773

88-
int nonNullPositionCount = sliceInput.readInt();
89-
sliceInput.readInts(values, 0, nonNullPositionCount);
90-
int position = nonNullPositionCount - 1;
91-
92-
// Handle Last (positionCount % 8) values
93-
for (int i = positionCount - 1; i >= (positionCount & ~0b111) && position >= 0; i--) {
94-
values[i] = values[position];
95-
if (!valueIsNull[i]) {
96-
position--;
97-
}
98-
}
99-
100-
// Handle the remaining positions.
101-
for (int i = (positionCount & ~0b111) - 8; i >= 0 && position >= 0; i -= 8) {
102-
byte packed = valueIsNullPacked[i >>> 3];
103-
if (packed == 0) { // Only values
104-
arraycopy(values, position - 7, values, i, 8);
105-
position -= 8;
106-
}
107-
else if (packed != -1) { // At least one non-null
108-
for (int j = i + 7; j >= i && position >= 0; j--) {
109-
values[j] = values[position];
110-
if (!valueIsNull[j]) {
111-
position--;
112-
}
113-
}
114-
}
115-
// Do nothing if there are only nulls
116-
}
11774
return new IntArrayBlock(0, positionCount, valueIsNull, values);
11875
}
11976
}

core/trino-spi/src/main/java/io/trino/spi/block/LongArrayBlockEncoding.java

Lines changed: 2 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import static io.trino.spi.block.EncoderUtil.decodeNullBits;
2121
import static io.trino.spi.block.EncoderUtil.encodeNullsAsBits;
2222
import static io.trino.spi.block.EncoderUtil.retrieveNullBits;
23-
import static java.lang.System.arraycopy;
2423
import static java.util.Objects.checkFromIndexSize;
2524

2625
public class LongArrayBlockEncoding
@@ -55,20 +54,7 @@ public void writeBlock(BlockEncodingSerde blockEncodingSerde, SliceOutput sliceO
5554

5655
encodeNullsAsBits(sliceOutput, isNull, rawOffset, positionCount);
5756

58-
if (isNull == null) {
59-
sliceOutput.writeLongs(rawValues, rawOffset, positionCount);
60-
}
61-
else {
62-
long[] valuesWithoutNull = new long[positionCount];
63-
int nonNullPositionCount = 0;
64-
for (int i = 0; i < positionCount; i++) {
65-
valuesWithoutNull[nonNullPositionCount] = rawValues[i + rawOffset];
66-
nonNullPositionCount += isNull[i + rawOffset] ? 0 : 1;
67-
}
68-
69-
sliceOutput.writeInt(nonNullPositionCount);
70-
sliceOutput.writeLongs(valuesWithoutNull, 0, nonNullPositionCount);
71-
}
57+
sliceOutput.writeLongs(rawValues, rawOffset, positionCount);
7258
}
7359

7460
@Override
@@ -85,35 +71,8 @@ public LongArrayBlock readBlock(BlockEncodingSerde blockEncodingSerde, SliceInpu
8571
}
8672
boolean[] valueIsNull = decodeNullBits(valueIsNullPacked, positionCount);
8773

88-
int nonNullPositionCount = sliceInput.readInt();
89-
sliceInput.readLongs(values, 0, nonNullPositionCount);
90-
int position = nonNullPositionCount - 1;
74+
sliceInput.readLongs(values);
9175

92-
// Handle Last (positionCount % 8) values
93-
for (int i = positionCount - 1; i >= (positionCount & ~0b111) && position >= 0; i--) {
94-
values[i] = values[position];
95-
if (!valueIsNull[i]) {
96-
position--;
97-
}
98-
}
99-
100-
// Handle the remaining positions.
101-
for (int i = (positionCount & ~0b111) - 8; i >= 0 && position >= 0; i -= 8) {
102-
byte packed = valueIsNullPacked[i >>> 3];
103-
if (packed == 0) { // Only values
104-
arraycopy(values, position - 7, values, i, 8);
105-
position -= 8;
106-
}
107-
else if (packed != -1) { // At least one non-null
108-
for (int j = i + 7; j >= i && position >= 0; j--) {
109-
values[j] = values[position];
110-
if (!valueIsNull[j]) {
111-
position--;
112-
}
113-
}
114-
}
115-
// Do nothing if there are only nulls
116-
}
11776
return new LongArrayBlock(0, positionCount, valueIsNull, values);
11877
}
11978
}

0 commit comments

Comments
 (0)