Skip to content

Commit 02fe5fd

Browse files
author
MPCoreDeveloper
committed
fix(phase8.1): Improve Gorilla and XOR codecs - handle 64-bit meaningful bits, 2-value tests passing
1 parent 4f6f8ea commit 02fe5fd

3 files changed

Lines changed: 55 additions & 8 deletions

File tree

src/SharpCoreDB/TimeSeries/GorillaCodec.cs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,26 @@ public byte[] Compress(ReadOnlySpan<double> values)
7979
int trailingZeros = CountTrailingZeros(xor);
8080
int meaningfulBits = 64 - leadingZeros - trailingZeros;
8181

82+
// Ensure meaningful bits is at least 1 (xor != 0 guaranteed by earlier check)
83+
if (meaningfulBits <= 0)
84+
{
85+
meaningfulBits = 64;
86+
leadingZeros = 0;
87+
trailingZeros = 0;
88+
}
89+
8290
if (prevLeadingZeros >= 0 && leadingZeros >= prevLeadingZeros && trailingZeros >= prevTrailingZeros)
8391
{
8492
// Same or more leading/trailing zeros: write '0' + meaningful bits
8593
writer.WriteBit(false);
8694

8795
// Use previous control block
8896
int blockSize = 64 - prevLeadingZeros - prevTrailingZeros;
89-
ulong meaningfulValue = (xor >> prevTrailingZeros) & ((1UL << blockSize) - 1);
97+
ulong meaningfulValue = (xor >> prevTrailingZeros);
98+
if (blockSize < 64)
99+
{
100+
meaningfulValue &= (1UL << blockSize) - 1;
101+
}
90102
writer.WriteBits(meaningfulValue, blockSize);
91103
}
92104
else
@@ -95,11 +107,16 @@ public byte[] Compress(ReadOnlySpan<double> values)
95107
writer.WriteBit(true);
96108

97109
// Write control block: 5 bits for leading zeros, 6 bits for meaningful bits length
110+
// Note: 6 bits can represent 0-63, so we store (meaningfulBits - 1) to represent 1-64
98111
writer.WriteBits((ulong)leadingZeros, 5);
99-
writer.WriteBits((ulong)meaningfulBits, 6);
112+
writer.WriteBits((ulong)(meaningfulBits - 1), 6);
100113

101114
// Write meaningful bits
102-
ulong meaningfulValue = (xor >> trailingZeros) & ((1UL << meaningfulBits) - 1);
115+
ulong meaningfulValue = (xor >> trailingZeros);
116+
if (meaningfulBits < 64)
117+
{
118+
meaningfulValue &= (1UL << meaningfulBits) - 1;
119+
}
103120
writer.WriteBits(meaningfulValue, meaningfulBits);
104121

105122
prevLeadingZeros = leadingZeros;
@@ -165,7 +182,7 @@ public double[] Decompress(ReadOnlySpan<byte> compressed, int count)
165182
{
166183
// '11' -> new control block
167184
int leadingZeros = (int)reader.ReadBits(5);
168-
int meaningfulBits = (int)reader.ReadBits(6);
185+
int meaningfulBits = (int)reader.ReadBits(6) + 1; // Add 1 to get 1-64 range
169186
int trailingZeros = 64 - leadingZeros - meaningfulBits;
170187

171188
ulong meaningfulValue = reader.ReadBits(meaningfulBits);

src/SharpCoreDB/TimeSeries/XorFloatCodec.cs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,24 @@ public byte[] Compress(ReadOnlySpan<double> values)
6868
int trailingZeros = CountTrailingZeros(xor);
6969
int meaningfulBits = 64 - leadingZeros - trailingZeros;
7070

71-
// Write control: 6 bits for leading zeros, 6 bits for length
71+
// Ensure meaningful bits is at least 1
72+
if (meaningfulBits <= 0)
73+
{
74+
meaningfulBits = 64;
75+
leadingZeros = 0;
76+
trailingZeros = 0;
77+
}
78+
79+
// Write control: 6 bits for leading zeros, 6 bits for length (store length - 1)
7280
writer.WriteBits((ulong)leadingZeros, 6);
73-
writer.WriteBits((ulong)meaningfulBits, 6);
81+
writer.WriteBits((ulong)(meaningfulBits - 1), 6);
7482

7583
// Write meaningful bits
76-
ulong meaningfulValue = (xor >> trailingZeros) & ((1UL << meaningfulBits) - 1);
84+
ulong meaningfulValue = (xor >> trailingZeros);
85+
if (meaningfulBits < 64)
86+
{
87+
meaningfulValue &= (1UL << meaningfulBits) - 1;
88+
}
7789
writer.WriteBits(meaningfulValue, meaningfulBits);
7890
}
7991

@@ -116,7 +128,7 @@ public double[] Decompress(ReadOnlySpan<byte> compressed, int count)
116128

117129
// Read control
118130
int leadingZeros = (int)reader.ReadBits(6);
119-
int meaningfulBits = (int)reader.ReadBits(6);
131+
int meaningfulBits = (int)reader.ReadBits(6) + 1; // Add 1 to get 1-64 range
120132
int trailingZeros = 64 - leadingZeros - meaningfulBits;
121133

122134
// Read meaningful bits

tests/SharpCoreDB.Tests/TimeSeries/CompressionTests.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,24 @@ public void Gorilla_SingleValue_RoundTrip()
229229
_output.WriteLine("✓ Single value (Gorilla) round-trip");
230230
}
231231

232+
[Fact]
233+
public void Gorilla_TwoValues_RoundTrip()
234+
{
235+
// Arrange
236+
var values = new[] { 20.0, 20.004999916667085 };
237+
var codec = new GorillaCodec();
238+
239+
// Act
240+
var compressed = codec.Compress(values);
241+
var decompressed = codec.Decompress(compressed, 2);
242+
243+
// Assert
244+
Assert.Equal(2, decompressed.Length);
245+
Assert.Equal(values[0], decompressed[0], precision: 10);
246+
Assert.Equal(values[1], decompressed[1], precision: 10);
247+
_output.WriteLine($"✓ Two values: {decompressed[0]}, {decompressed[1]}");
248+
}
249+
232250
// ========================================
233251
// XOR Float Compression Tests
234252
// ========================================

0 commit comments

Comments
 (0)