Fix decoding RLE integer blocks with negative deltas
Integer blocks that were run length encoded could produce the wrong value when read back out because the deltas were not zig zag decoded before scaling the final value. If the deltas were negative, as would be seen in a counter that decrements by a constant value, the results would be random with som negative and positive values. Fixes #7391pull/7399/head
parent
601d440670
commit
2898f3dacf
|
@ -6,6 +6,12 @@
|
||||||
- [#5878](https://github.com/influxdata/influxdb/issues/5878): Ensure correct shard groups created when retention policy has been altered.
|
- [#5878](https://github.com/influxdata/influxdb/issues/5878): Ensure correct shard groups created when retention policy has been altered.
|
||||||
|
|
||||||
|
|
||||||
|
## v1.0.2 [unreleased]
|
||||||
|
|
||||||
|
### Bugfixes
|
||||||
|
|
||||||
|
- [#7391](https://github.com/influxdata/influxdb/issues/7391): Fix RLE integer decoding producing negative numbers
|
||||||
|
|
||||||
## v1.0.1 [2016-09-26]
|
## v1.0.1 [2016-09-26]
|
||||||
|
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
|
|
@ -203,7 +203,7 @@ func (d *IntegerDecoder) Error() error {
|
||||||
func (d *IntegerDecoder) Read() int64 {
|
func (d *IntegerDecoder) Read() int64 {
|
||||||
switch d.encoding {
|
switch d.encoding {
|
||||||
case intCompressedRLE:
|
case intCompressedRLE:
|
||||||
return ZigZagDecode(d.rleFirst + uint64(d.i)*d.rleDelta)
|
return ZigZagDecode(d.rleFirst) + int64(d.i)*ZigZagDecode(d.rleDelta)
|
||||||
default:
|
default:
|
||||||
v := ZigZagDecode(d.values[d.i])
|
v := ZigZagDecode(d.values[d.i])
|
||||||
// v is the delta encoded value, we need to add the prior value to get the original
|
// v is the delta encoded value, we need to add the prior value to get the original
|
||||||
|
|
|
@ -354,6 +354,94 @@ func Test_IntegerEncoder_CounterRLE(t *testing.T) {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if b[0]>>4 != intCompressedRLE {
|
||||||
|
t.Fatalf("unexpected encoding format: expected RLE, got %v", b[0]>>4)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should use 1 header byte, 8 byte first value, 1 var-byte for delta and 1 var-byte for
|
||||||
|
// count of deltas in this particular RLE.
|
||||||
|
if exp := 11; len(b) != exp {
|
||||||
|
t.Fatalf("encoded length mismatch: got %v, exp %v", len(b), exp)
|
||||||
|
}
|
||||||
|
|
||||||
|
var dec IntegerDecoder
|
||||||
|
dec.SetBytes(b)
|
||||||
|
i := 0
|
||||||
|
for dec.Next() {
|
||||||
|
if i > len(values) {
|
||||||
|
t.Fatalf("read too many values: got %v, exp %v", i, len(values))
|
||||||
|
}
|
||||||
|
|
||||||
|
if values[i] != dec.Read() {
|
||||||
|
t.Fatalf("read value %d mismatch: got %v, exp %v", i, dec.Read(), values[i])
|
||||||
|
}
|
||||||
|
i += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if i != len(values) {
|
||||||
|
t.Fatalf("failed to read enough values: got %v, exp %v", i, len(values))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_IntegerEncoder_Descending(t *testing.T) {
|
||||||
|
enc := NewIntegerEncoder(16)
|
||||||
|
values := []int64{
|
||||||
|
7094, 4472, 1850,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range values {
|
||||||
|
enc.Write(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := enc.Bytes()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if b[0]>>4 != intCompressedRLE {
|
||||||
|
t.Fatalf("unexpected encoding format: expected simple, got %v", b[0]>>4)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should use 1 header byte, 8 byte first value, 1 var-byte for delta and 1 var-byte for
|
||||||
|
// count of deltas in this particular RLE.
|
||||||
|
if exp := 12; len(b) != exp {
|
||||||
|
t.Fatalf("encoded length mismatch: got %v, exp %v", len(b), exp)
|
||||||
|
}
|
||||||
|
|
||||||
|
var dec IntegerDecoder
|
||||||
|
dec.SetBytes(b)
|
||||||
|
i := 0
|
||||||
|
for dec.Next() {
|
||||||
|
if i > len(values) {
|
||||||
|
t.Fatalf("read too many values: got %v, exp %v", i, len(values))
|
||||||
|
}
|
||||||
|
|
||||||
|
if values[i] != dec.Read() {
|
||||||
|
t.Fatalf("read value %d mismatch: got %v, exp %v", i, dec.Read(), values[i])
|
||||||
|
}
|
||||||
|
i += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if i != len(values) {
|
||||||
|
t.Fatalf("failed to read enough values: got %v, exp %v", i, len(values))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_IntegerEncoder_Flat(t *testing.T) {
|
||||||
|
enc := NewIntegerEncoder(16)
|
||||||
|
values := []int64{
|
||||||
|
1, 1, 1, 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range values {
|
||||||
|
enc.Write(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := enc.Bytes()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
if b[0]>>4 != intCompressedRLE {
|
if b[0]>>4 != intCompressedRLE {
|
||||||
t.Fatalf("unexpected encoding format: expected simple, got %v", b[0]>>4)
|
t.Fatalf("unexpected encoding format: expected simple, got %v", b[0]>>4)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue