353fef3ff6
License: MIT Signed-off-by: Jakub Sztandera <kubuxu@protonmail.ch>
171 lines
3.8 KiB
Go
171 lines
3.8 KiB
Go
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
|
|
}
|