Skip to content

Commit 9640566

Browse files
committed
Fix variable-byte encoding of large longs
Previously, the branch encoding longs in 9 bytes was unreachable because the condition `val < (1L << 63)` is always false. Only negative longs should be encoded using 10 bytes.
1 parent 182c6d2 commit 9640566

File tree

2 files changed

+14
-8
lines changed

2 files changed

+14
-8
lines changed

src/main/java/me/lemire/longcompression/LongVariableByte.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public void headlessCompress(long[] in, IntWrapper inpos, int inlength, long[] o
9090
buf.put((byte) extract7bits(5, val));
9191
buf.put((byte) extract7bits(6, val));
9292
buf.put((byte) (extract7bitsmaskless(7, (val)) | (1 << 7)));
93-
} else if (val >= 0 && val < (1L << 63)) {
93+
} else if (val >= 0) {
9494
buf.put((byte) extract7bits(0, val));
9595
buf.put((byte) extract7bits(1, val));
9696
buf.put((byte) extract7bits(2, val));
@@ -175,7 +175,7 @@ public void compress(long[] in, IntWrapper inpos, int inlength, byte[] out,
175175
out[outpostmp++] = (byte) extract7bits(5, val);
176176
out[outpostmp++] = (byte) extract7bits(6, val);
177177
out[outpostmp++] = (byte) (extract7bitsmaskless(7, (val)) | (1 << 7));
178-
} else if (val >= 0 && val < (1L << 63)) {
178+
} else if (val >= 0) {
179179
out[outpostmp++] = (byte) extract7bits(0, val);
180180
out[outpostmp++] = (byte) extract7bits(1, val);
181181
out[outpostmp++] = (byte) extract7bits(2, val);

src/test/java/me/lemire/longcompression/TestLongVariableByte.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,17 @@ public LongCODEC getCodec() {
2424
}
2525

2626
@Test
27-
public void testCodec_intermediateHighPowerOfTwo() {
28-
Assert.assertEquals(1, LongTestUtils.compress((LongCODEC) codec, new long[] { 1L << 42 }).length);
29-
Assert.assertEquals(7, LongTestUtils.compress((ByteLongCODEC) codec, new long[] { 1L << 42 }).length);
30-
Assert.assertEquals(1,
31-
LongTestUtils.compressHeadless((SkippableLongCODEC) codec, new long[] { 1L << 42 }).length);
32-
}
27+
public void testCodec_allBitWidths() {
28+
for (int bitWidth = 0; bitWidth <= 64; bitWidth++) {
29+
long value = bitWidth == 0 ? 0 : 1L << (bitWidth - 1);
30+
31+
int expectedSizeInBytes = Math.max(1, (bitWidth + 6) / 7);
32+
int expectedSizeInLongs = (expectedSizeInBytes > 8) ? 2 : 1;
3333

34+
Assert.assertEquals(expectedSizeInLongs, LongTestUtils.compress((LongCODEC) codec, new long[] { value }).length);
35+
Assert.assertEquals(expectedSizeInBytes, LongTestUtils.compress((ByteLongCODEC) codec, new long[] { value }).length);
36+
Assert.assertEquals(expectedSizeInLongs,
37+
LongTestUtils.compressHeadless((SkippableLongCODEC) codec, new long[] { value }).length);
38+
}
39+
}
3440
}

0 commit comments

Comments
 (0)