Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ public static int readVInt(byte[] arr, int position) {
* @param arr the byte data to read from
* @param position the position in the byte data to read from
* @param length the number of bytes that should be read
* @param output an array where outputs will be placed, which should be at least {@code length} long and zero.
* @param output an array where outputs will be placed, which should be at least {@code length} long.
* @return the number of values written
*/
public static int readVIntsInto(ByteData arr, long position, int length, int[] output) {
Expand All @@ -256,12 +256,24 @@ public static int readVIntsInto(ByteData arr, long position, int length, int[] o
output[i] = b;
}

// Second loop handles multi-byte encoded values using branchless logic
int count = i;
int accumulator = 0;
for(; i < length; i++) {
int b = arr.get(position + i);

output[count] = (output[count] << 7) | (b & 0x7f);
count += (~b >> 7) & 0x1;
// Accumulate the next 7 bits into the value
accumulator = (accumulator << 7) | (b & 0x7f);

// Check if this byte completes a value (continuation bit not set)
int isComplete = (~b >> 7) & 0x1; // 1 if complete, 0 if continuing
output[count] = accumulator; // Write current accumulator (may overwrite same position)
count += isComplete; // Advance output position only when value is complete

// Clear accumulator for next value using sign extension trick:
// - If b has continuation bit (b negative): b >> 7 = 0xFFFFFFFF, keeps accumulator
// - If b completes value (b positive): b >> 7 = 0, clears accumulator
accumulator &= (b >> 7);
}

return count;
Expand All @@ -272,7 +284,7 @@ public static int readVIntsInto(ByteData arr, long position, int length, int[] o
* @param arr the byte data to read from
* @param position the position in the byte data to read from
* @param length the number of bytes that should be read
* @param output an array where outputs will be placed, which should be at least {@code length} long and zero.
* @param output an array where outputs will be placed, which should be at least {@code length} long.
* @return the number of values written
*/
public static int readVIntsInto(ByteData arr, long position, int length, char[] output) {
Expand All @@ -286,11 +298,22 @@ public static int readVIntsInto(ByteData arr, long position, int length, char[]
}

int count = i;
int accumulator = 0;
for(; i < length; i++) {
int b = arr.get(position + i);

output[count] = (char) ((output[count] << 7) | (b & 0x7f));
count += (~b >> 7) & 0x1;
// Accumulate the next 7 bits into the value
accumulator = (accumulator << 7) | (b & 0x7f);

// Check if this byte completes a value (continuation bit not set)
int isComplete = (~b >> 7) & 0x1; // 1 if complete, 0 if continuing
output[count] = (char) accumulator; // Write current accumulator (may overwrite same position)
count += isComplete; // Advance output position only when value is complete

// Clear accumulator for next value using sign extension trick:
// - If b has continuation bit (b negative): b >> 7 = 0xFFFFFFFF, keeps accumulator
// - If b completes value (b positive): b >> 7 = 0, clears accumulator
accumulator &= (b >> 7);
}

return count;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,6 @@ private String readString(ByteData data, long position, int length) {
char[] chararr = HollowObjectTypeReadStateShard.chararr.get();
if (length > chararr.length) {
chararr = new char[length];
} else {
Arrays.fill(chararr, 0, length, '\0');
}

int count = VarInt.readVIntsInto(data, position, length, chararr);
Expand Down