lotus/lib/rlepluslazy/rleplus_test.go

171 lines
3.8 KiB
Go
Raw Normal View History

package rlepluslazy
import (
"math/rand"
"testing"
"github.com/filecoin-project/lotus/extern/rleplus"
"github.com/stretchr/testify/assert"
)
func TestDecode(t *testing.T) {
// Encoding bitvec![LittleEndian; 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
// in the Rust reference implementation gives an encoding of [223, 145, 136, 0] (without version field)
// The bit vector is equivalent to the integer set { 0, 2, 4, 5, 6, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 }
// This is the above reference output with a version header "00" manually added
referenceEncoding := []byte{124, 71, 34, 2}
expectedNumbers := []uint64{0, 2, 4, 5, 6, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27}
runs, err := RunsFromBits(BitsFromSlice(expectedNumbers))
assert.NoError(t, err)
encoded, err := EncodeRuns(runs, []byte{})
assert.NoError(t, err)
// Our encoded bytes are the same as the ref bytes
assert.Equal(t, len(referenceEncoding), len(encoded))
assert.Equal(t, referenceEncoding, encoded)
rle, err := FromBuf(encoded)
assert.NoError(t, err)
decoded := make([]uint64, 0, len(expectedNumbers))
rit, err := rle.RunIterator()
assert.NoError(t, err)
it, err := BitsFromRuns(rit)
assert.NoError(t, err)
for it.HasNext() {
bit, err := it.Next()
assert.NoError(t, err)
decoded = append(decoded, bit)
}
// Our decoded integers are the same as expected
assert.Equal(t, expectedNumbers, decoded)
}
func TestGoldenGen(t *testing.T) {
t.SkipNow()
N := 10000
mod := uint32(1) << 20
runExProp := float32(0.93)
bits := make([]uint64, N)
for i := 0; i < N; i++ {
x := rand.Uint32() % mod
bits[i] = uint64(x)
for rand.Float32() < runExProp && i+1 < N {
i++
x = (x + 1) % mod
bits[i] = uint64(x)
}
}
out, _, err := rleplus.Encode(bits)
assert.NoError(t, err)
t.Logf("%#v", out)
_, runs := rleplus.RunLengths(bits)
t.Logf("runs: %v", runs)
t.Logf("len: %d", len(out))
}
func TestGolden(t *testing.T) {
expected, _ := rleplus.Decode(goldenRLE)
res := make([]uint64, 0, len(expected))
rle, err := FromBuf(goldenRLE)
assert.NoError(t, err)
rit, err := rle.RunIterator()
assert.NoError(t, err)
it, err := BitsFromRuns(rit)
assert.NoError(t, err)
for it.HasNext() {
bit, err := it.Next()
assert.NoError(t, err)
res = append(res, bit)
}
assert.Equal(t, expected, res)
}
func TestGoldenLoop(t *testing.T) {
rle, err := FromBuf(goldenRLE)
assert.NoError(t, err)
rit, err := rle.RunIterator()
assert.NoError(t, err)
buf, err := EncodeRuns(rit, nil)
assert.NoError(t, err)
assert.Equal(t, goldenRLE, buf)
}
var Res uint64 = 0
func BenchmarkRunIterator(b *testing.B) {
b.ReportAllocs()
var r uint64
for i := 0; i < b.N; i++ {
rle, _ := FromBuf(goldenRLE)
rit, _ := rle.RunIterator()
for rit.HasNext() {
run, _ := rit.NextRun()
if run.Val {
r = r + run.Len
}
}
}
Res = Res + r
}
func BenchmarkRunsToBits(b *testing.B) {
b.ReportAllocs()
var r uint64
for i := 0; i < b.N; i++ {
rle, _ := FromBuf(goldenRLE)
rit, _ := rle.RunIterator()
it, _ := BitsFromRuns(rit)
for it.HasNext() {
bit, _ := it.Next()
if bit < 1<<63 {
r++
}
}
}
Res = Res + r
}
func BenchmarkOldRLE(b *testing.B) {
b.ReportAllocs()
var r uint64
for i := 0; i < b.N; i++ {
rle, _ := rleplus.Decode(goldenRLE)
r = r + uint64(len(rle))
}
Res = Res + r
}
func BenchmarkDecodeEncode(b *testing.B) {
b.ReportAllocs()
var r uint64
out := make([]byte, 0, len(goldenRLE))
for i := 0; i < b.N; i++ {
rle, _ := FromBuf(goldenRLE)
rit, _ := rle.RunIterator()
out, _ = EncodeRuns(rit, out)
r = r + uint64(len(out))
}
/*
for i := 0; i < b.N; i++ {
rle, _ := rleplus.Decode(goldenRLE)
out, _, _ := rleplus.Encode(rle)
r = r + uint64(len(out))
}
*/
Res = Res + r
}