in pinot-segment-local/src/main/java/org/apache/pinot/segment/local/io/util/PinotDataBitSetV2.java [122:317]
public void readInt(long startIndex, int length, int[] out) {
long bitOffset = startIndex * _numBitsPerValue;
long byteOffset = bitOffset / Byte.SIZE;
bitOffset = bitOffset & 7;
int packed = 0;
int i = 0;
// unaligned read within a byte
if (bitOffset != 0) {
packed = (int) _dataBuffer.getByte(byteOffset) & 0xff;
if (bitOffset == 1) {
// unpack 7 integers from bits 1-7
out[0] = (packed >>> 6) & 1;
out[1] = (packed >>> 5) & 1;
out[2] = (packed >>> 4) & 1;
out[3] = (packed >>> 3) & 1;
out[4] = (packed >>> 2) & 1;
out[5] = (packed >>> 1) & 1;
out[6] = packed & 1;
i = 7;
length -= 7;
} else if (bitOffset == 2) {
// unpack 6 integers from bits 2 to 7
out[0] = (packed >>> 5) & 1;
out[1] = (packed >>> 4) & 1;
out[2] = (packed >>> 3) & 1;
out[3] = (packed >>> 2) & 1;
out[4] = (packed >>> 1) & 1;
out[5] = packed & 1;
i = 6;
length -= 6;
} else if (bitOffset == 3) {
// unpack 5 integers from bits 3 to 7
out[0] = (packed >>> 4) & 1;
out[1] = (packed >>> 3) & 1;
out[2] = (packed >>> 2) & 1;
out[3] = (packed >>> 1) & 1;
out[4] = packed & 1;
i = 5;
length -= 5;
} else if (bitOffset == 4) {
// unpack 4 integers from bits 4 to 7
out[0] = (packed >>> 3) & 1;
out[1] = (packed >>> 2) & 1;
out[2] = (packed >>> 1) & 1;
out[3] = packed & 1;
i = 4;
length -= 4;
} else if (bitOffset == 5) {
// unpack 3 integers from bits 5 to 7
out[0] = (packed >>> 2) & 1;
out[1] = (packed >>> 1) & 1;
out[2] = packed & 1;
i = 3;
length -= 3;
} else if (bitOffset == 6) {
// unpack 2 integers from bits 6 to 7
out[0] = (packed >>> 1) & 1;
out[1] = packed & 1;
i = 2;
length -= 2;
} else {
// unpack integer from bit 7
out[0] = packed & 1;
i = 1;
length -= 1;
}
byteOffset++;
}
// aligned reads at 4-byte boundary to unpack 32 integers
while (length >= 32) {
packed = _dataBuffer.getInt(byteOffset);
out[i] = packed >>> 31;
out[i + 1] = (packed >>> 30) & 1;
out[i + 2] = (packed >>> 29) & 1;
out[i + 3] = (packed >>> 28) & 1;
out[i + 4] = (packed >>> 27) & 1;
out[i + 5] = (packed >>> 26) & 1;
out[i + 6] = (packed >>> 25) & 1;
out[i + 7] = (packed >>> 24) & 1;
out[i + 8] = (packed >>> 23) & 1;
out[i + 9] = (packed >>> 22) & 1;
out[i + 10] = (packed >>> 21) & 1;
out[i + 11] = (packed >>> 20) & 1;
out[i + 12] = (packed >>> 19) & 1;
out[i + 13] = (packed >>> 18) & 1;
out[i + 14] = (packed >>> 17) & 1;
out[i + 15] = (packed >>> 16) & 1;
out[i + 16] = (packed >>> 15) & 1;
out[i + 17] = (packed >>> 14) & 1;
out[i + 18] = (packed >>> 13) & 1;
out[i + 19] = (packed >>> 12) & 1;
out[i + 20] = (packed >>> 11) & 1;
out[i + 21] = (packed >>> 10) & 1;
out[i + 22] = (packed >>> 9) & 1;
out[i + 23] = (packed >>> 8) & 1;
out[i + 24] = (packed >>> 7) & 1;
out[i + 25] = (packed >>> 6) & 1;
out[i + 26] = (packed >>> 5) & 1;
out[i + 27] = (packed >>> 4) & 1;
out[i + 28] = (packed >>> 3) & 1;
out[i + 29] = (packed >>> 2) & 1;
out[i + 30] = (packed >>> 1) & 1;
out[i + 31] = packed & 1;
length -= 32;
byteOffset += 4;
i += 32;
}
// aligned reads at 2-byte boundary to unpack 16 integers
if (length >= 16) {
packed = (int) _dataBuffer.getShort(byteOffset) & 0xffff;
out[i] = (packed >>> 15) & 1;
out[i + 1] = (packed >>> 14) & 1;
out[i + 2] = (packed >>> 13) & 1;
out[i + 3] = (packed >>> 12) & 1;
out[i + 4] = (packed >>> 11) & 1;
out[i + 5] = (packed >>> 10) & 1;
out[i + 6] = (packed >>> 9) & 1;
out[i + 7] = (packed >>> 8) & 1;
out[i + 8] = (packed >>> 7) & 1;
out[i + 9] = (packed >>> 6) & 1;
out[i + 10] = (packed >>> 5) & 1;
out[i + 11] = (packed >>> 4) & 1;
out[i + 12] = (packed >>> 3) & 1;
out[i + 13] = (packed >>> 2) & 1;
out[i + 14] = (packed >>> 1) & 1;
out[i + 15] = packed & 1;
length -= 16;
byteOffset += 2;
i += 16;
}
// aligned reads at byte boundary to unpack 8 integers
if (length >= 8) {
packed = (int) _dataBuffer.getByte(byteOffset) & 0xff;
out[i] = (packed >>> 7) & 1;
out[i + 1] = (packed >>> 6) & 1;
out[i + 2] = (packed >>> 5) & 1;
out[i + 3] = (packed >>> 4) & 1;
out[i + 4] = (packed >>> 3) & 1;
out[i + 5] = (packed >>> 2) & 1;
out[i + 6] = (packed >>> 1) & 1;
out[i + 7] = packed & 1;
length -= 8;
byteOffset += 1;
i += 8;
}
// handle spill-over
if (length == 7) {
// unpack from bits 0-6
packed = (int) _dataBuffer.getByte(byteOffset) & 0xff;
out[i] = (packed >>> 7) & 1;
out[i + 1] = (packed >>> 6) & 1;
out[i + 2] = (packed >>> 5) & 1;
out[i + 3] = (packed >>> 4) & 1;
out[i + 4] = (packed >>> 3) & 1;
out[i + 5] = (packed >>> 2) & 1;
out[i + 6] = (packed >>> 1) & 1;
} else if (length == 6) {
// unpack from bits 0-5
out[i] = (packed >>> 7) & 1;
out[i + 1] = (packed >>> 6) & 1;
out[i + 2] = (packed >>> 5) & 1;
out[i + 3] = (packed >>> 4) & 1;
out[i + 4] = (packed >>> 3) & 1;
out[i + 5] = (packed >>> 2) & 1;
} else if (length == 5) {
// unpack from bits 0-4
out[i] = (packed >>> 7) & 1;
out[i + 1] = (packed >>> 6) & 1;
out[i + 2] = (packed >>> 5) & 1;
out[i + 3] = (packed >>> 4) & 1;
out[i + 4] = (packed >>> 3) & 1;
} else if (length == 4) {
// unpack from bits 0-3
out[i] = (packed >>> 7) & 1;
out[i + 1] = (packed >>> 6) & 1;
out[i + 2] = (packed >>> 5) & 1;
out[i + 3] = (packed >>> 4) & 1;
} else if (length == 3) {
// unpack from bits 0-2
out[i] = (packed >>> 7) & 1;
out[i + 1] = (packed >>> 6) & 1;
out[i + 2] = (packed >>> 5) & 1;
} else if (length == 2) {
// unpack from bits 0-3
out[i] = (packed >>> 7) & 1;
out[i + 1] = (packed >>> 6) & 1;
} else {
out[i] = (packed >>> 7) & 1;
}
}