mirror of
https://github.com/MarginaliaSearch/MarginaliaSearch.git
synced 2025-02-24 21:29:00 +00:00

Fix rare bug where the takeWhileZero method would fail to repopulate the underlying buffer. This caused intermittent de-compression errors if takeWhileZero happened at a 64 bit boundary while the underlying buffer was empty. The change also alters how sequence-lengths are encoded, to more consistently use the getGamma method instead of adding special significance to a zero first byte. Finally, assertions are added checking the invariants of the gamma and delta coding logic as well as UrlIdCodec to earlier detect issues.
139 lines
3.5 KiB
Java
139 lines
3.5 KiB
Java
package nu.marginalia.sequence;
|
|
|
|
import nu.marginalia.sequence.io.BitReader;
|
|
import nu.marginalia.sequence.io.BitWriter;
|
|
import org.junit.jupiter.api.Test;
|
|
|
|
import java.nio.ByteBuffer;
|
|
|
|
import static org.junit.jupiter.api.Assertions.*;
|
|
|
|
class BitReaderTest {
|
|
|
|
@Test
|
|
void getBit() {
|
|
var writer = new BitWriter(ByteBuffer.allocate(1024));
|
|
writer.putBit(true);
|
|
writer.putBit(false);
|
|
writer.putBits(0, 32);
|
|
writer.putBit(true);
|
|
writer.putBit(false);
|
|
var buffer = writer.finish();
|
|
|
|
var reader = new BitReader(buffer);
|
|
assertTrue(reader.getBit());
|
|
assertFalse(reader.getBit());
|
|
for (int i = 0; i < 32; i++) {
|
|
assertFalse(reader.getBit());
|
|
}
|
|
assertTrue(reader.getBit());
|
|
assertFalse(reader.getBit());
|
|
}
|
|
|
|
@Test
|
|
void getInByte() {
|
|
var writer = new BitWriter(ByteBuffer.allocate(1024));
|
|
|
|
writer.putBit(true);
|
|
writer.putBit(false);
|
|
|
|
var buffer = writer.finish();
|
|
|
|
var reader = new BitReader(buffer);
|
|
int val = reader.get(2);
|
|
assertEquals(0b10, val);
|
|
}
|
|
|
|
@Test
|
|
void get() {
|
|
var writer = new BitWriter(ByteBuffer.allocate(1024));
|
|
writer.putBit(true);
|
|
writer.putBit(false);
|
|
writer.putBits(0, 32);
|
|
writer.putBit(true);
|
|
writer.putBit(false);
|
|
var buffer = writer.finish();
|
|
|
|
var reader = new BitReader(buffer);
|
|
int val = reader.get(4);
|
|
assertEquals(0b1000, val);
|
|
|
|
val = reader.get(30);
|
|
assertEquals(0b000, val);
|
|
|
|
val = reader.get(2);
|
|
assertEquals(0b10, val);
|
|
}
|
|
|
|
@Test
|
|
void getSevens() {
|
|
// Fuzz test that probes int32 misalignments
|
|
var writer = new BitWriter(ByteBuffer.allocate(1024));
|
|
|
|
for (int i = 0; i < 729; i++) {
|
|
writer.putBit(true);
|
|
writer.putBit(false);
|
|
writer.putBit(false);
|
|
writer.putBit(true);
|
|
writer.putBit(false);
|
|
writer.putBit(false);
|
|
writer.putBit(true);
|
|
}
|
|
|
|
var buffer = writer.finish();
|
|
|
|
var reader = new BitReader(buffer);
|
|
|
|
for (int i = 0; i < 729; i++) {
|
|
int val = reader.get(7);
|
|
assertEquals(0b1001001, val);
|
|
}
|
|
}
|
|
|
|
@Test
|
|
void getSevens2() {
|
|
// Fuzz test that probes int32 misalignments
|
|
var writer = new BitWriter(ByteBuffer.allocate(1024));
|
|
|
|
for (int i = 0; i < 729; i++) {
|
|
writer.putBits(73, 7);
|
|
}
|
|
|
|
var buffer = writer.finish();
|
|
|
|
var reader = new BitReader(buffer);
|
|
|
|
for (int i = 0; i < 729; i++) {
|
|
int val = reader.get(7);
|
|
assertEquals(0b1001001, val);
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void testTakeWhileZero() {
|
|
var writer = new BitWriter(ByteBuffer.allocate(1024));
|
|
writer.putBits(0, 4);
|
|
writer.putBit(true);
|
|
var buffer = writer.finish();
|
|
|
|
var reader = new BitReader(buffer);
|
|
int val = reader.takeWhileZero();
|
|
assertEquals(4, val);
|
|
assertTrue(reader.getBit());
|
|
}
|
|
|
|
@Test
|
|
public void testTakeWhileZeroOverInt64() {
|
|
var writer = new BitWriter(ByteBuffer.allocate(1024));
|
|
writer.putBits(0, 32);
|
|
writer.putBits(0, 32);
|
|
writer.putBits(0, 2);
|
|
writer.putBit(true);
|
|
var buffer = writer.finish();
|
|
|
|
var reader = new BitReader(buffer);
|
|
int val = reader.takeWhileZero();
|
|
assertEquals(66, val);
|
|
assertTrue(reader.getBit());
|
|
}
|
|
} |