mirror of
https://source.quilibrium.com/quilibrium/ceremonyclient.git
synced 2024-12-27 00:55:17 +00:00
118 lines
2.8 KiB
Go
118 lines
2.8 KiB
Go
|
// Copyright 2011 The LevelDB-Go and Pebble Authors. All rights reserved. Use
|
||
|
// of this source code is governed by a BSD-style license that can be found in
|
||
|
// the LICENSE file.
|
||
|
|
||
|
package base
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"slices"
|
||
|
"testing"
|
||
|
"time"
|
||
|
|
||
|
"golang.org/x/exp/rand"
|
||
|
)
|
||
|
|
||
|
func TestDefAppendSeparator(t *testing.T) {
|
||
|
testCases := []struct {
|
||
|
a, b, want string
|
||
|
}{
|
||
|
// Examples from the doc comments.
|
||
|
{"black", "blue", "blb"},
|
||
|
{"green", "", "green"},
|
||
|
// Non-empty b values. The C++ Level-DB code calls these separators.
|
||
|
{"", "2", ""},
|
||
|
{"1", "2", "1"},
|
||
|
{"1", "29", "2"},
|
||
|
{"13", "19", "14"},
|
||
|
{"13", "99", "2"},
|
||
|
{"135", "19", "14"},
|
||
|
{"1357", "19", "14"},
|
||
|
{"1357", "2", "14"},
|
||
|
{"13\xff", "14", "13\xff"},
|
||
|
{"13\xff", "19", "14"},
|
||
|
{"1\xff\xff", "19", "1\xff\xff"},
|
||
|
{"1\xff\xff", "2", "1\xff\xff"},
|
||
|
{"1\xff\xff", "9", "2"},
|
||
|
// Empty b values. The C++ Level-DB code calls these successors.
|
||
|
{"", "", ""},
|
||
|
{"1", "", "1"},
|
||
|
{"11", "", "11"},
|
||
|
{"11\xff", "", "11\xff"},
|
||
|
{"1\xff", "", "1\xff"},
|
||
|
{"1\xff\xff", "", "1\xff\xff"},
|
||
|
{"\xff", "", "\xff"},
|
||
|
{"\xff\xff", "", "\xff\xff"},
|
||
|
{"\xff\xff\xff", "", "\xff\xff\xff"},
|
||
|
}
|
||
|
for _, tc := range testCases {
|
||
|
t.Run("", func(t *testing.T) {
|
||
|
got := string(DefaultComparer.Separator(nil, []byte(tc.a), []byte(tc.b)))
|
||
|
if got != tc.want {
|
||
|
t.Errorf("a, b = %q, %q: got %q, want %q", tc.a, tc.b, got, tc.want)
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestAbbreviatedKey(t *testing.T) {
|
||
|
rng := rand.New(rand.NewSource(uint64(time.Now().UnixNano())))
|
||
|
randBytes := func(size int) []byte {
|
||
|
data := make([]byte, size)
|
||
|
for i := range data {
|
||
|
data[i] = byte(rng.Int() & 0xff)
|
||
|
}
|
||
|
return data
|
||
|
}
|
||
|
|
||
|
keys := make([][]byte, 10000)
|
||
|
for i := range keys {
|
||
|
keys[i] = randBytes(rng.Intn(16))
|
||
|
}
|
||
|
slices.SortFunc(keys, DefaultComparer.Compare)
|
||
|
|
||
|
for i := 1; i < len(keys); i++ {
|
||
|
last := DefaultComparer.AbbreviatedKey(keys[i-1])
|
||
|
cur := DefaultComparer.AbbreviatedKey(keys[i])
|
||
|
cmp := DefaultComparer.Compare(keys[i-1], keys[i])
|
||
|
if cmp == 0 {
|
||
|
if last != cur {
|
||
|
t.Fatalf("expected equal abbreviated keys: %x[%x] != %x[%x]",
|
||
|
last, keys[i-1], cur, keys[i])
|
||
|
}
|
||
|
} else {
|
||
|
if last > cur {
|
||
|
t.Fatalf("unexpected abbreviated key ordering: %x[%x] > %x[%x]",
|
||
|
last, keys[i-1], cur, keys[i])
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func BenchmarkAbbreviatedKey(b *testing.B) {
|
||
|
rng := rand.New(rand.NewSource(1449168817))
|
||
|
randBytes := func(size int) []byte {
|
||
|
data := make([]byte, size)
|
||
|
for i := range data {
|
||
|
data[i] = byte(rng.Int() & 0xff)
|
||
|
}
|
||
|
return data
|
||
|
}
|
||
|
keys := make([][]byte, 10000)
|
||
|
for i := range keys {
|
||
|
keys[i] = randBytes(8)
|
||
|
}
|
||
|
|
||
|
b.ResetTimer()
|
||
|
var sum uint64
|
||
|
for i := 0; i < b.N; i++ {
|
||
|
j := i % len(keys)
|
||
|
sum += DefaultComparer.AbbreviatedKey(keys[j])
|
||
|
}
|
||
|
|
||
|
if testing.Verbose() {
|
||
|
// Ensure the compiler doesn't optimize away our benchmark.
|
||
|
fmt.Println(sum)
|
||
|
}
|
||
|
}
|