github.com/cockroachdb/pebble@v1.1.2/internal/base/comparer_test.go (about) 1 // Copyright 2011 The LevelDB-Go and Pebble Authors. All rights reserved. Use 2 // of this source code is governed by a BSD-style license that can be found in 3 // the LICENSE file. 4 5 package base 6 7 import ( 8 "fmt" 9 "sort" 10 "testing" 11 "time" 12 13 "golang.org/x/exp/rand" 14 ) 15 16 func TestDefAppendSeparator(t *testing.T) { 17 testCases := []struct { 18 a, b, want string 19 }{ 20 // Examples from the doc comments. 21 {"black", "blue", "blb"}, 22 {"green", "", "green"}, 23 // Non-empty b values. The C++ Level-DB code calls these separators. 24 {"", "2", ""}, 25 {"1", "2", "1"}, 26 {"1", "29", "2"}, 27 {"13", "19", "14"}, 28 {"13", "99", "2"}, 29 {"135", "19", "14"}, 30 {"1357", "19", "14"}, 31 {"1357", "2", "14"}, 32 {"13\xff", "14", "13\xff"}, 33 {"13\xff", "19", "14"}, 34 {"1\xff\xff", "19", "1\xff\xff"}, 35 {"1\xff\xff", "2", "1\xff\xff"}, 36 {"1\xff\xff", "9", "2"}, 37 // Empty b values. The C++ Level-DB code calls these successors. 38 {"", "", ""}, 39 {"1", "", "1"}, 40 {"11", "", "11"}, 41 {"11\xff", "", "11\xff"}, 42 {"1\xff", "", "1\xff"}, 43 {"1\xff\xff", "", "1\xff\xff"}, 44 {"\xff", "", "\xff"}, 45 {"\xff\xff", "", "\xff\xff"}, 46 {"\xff\xff\xff", "", "\xff\xff\xff"}, 47 } 48 for _, tc := range testCases { 49 t.Run("", func(t *testing.T) { 50 got := string(DefaultComparer.Separator(nil, []byte(tc.a), []byte(tc.b))) 51 if got != tc.want { 52 t.Errorf("a, b = %q, %q: got %q, want %q", tc.a, tc.b, got, tc.want) 53 } 54 }) 55 } 56 } 57 58 func TestAbbreviatedKey(t *testing.T) { 59 rng := rand.New(rand.NewSource(uint64(time.Now().UnixNano()))) 60 randBytes := func(size int) []byte { 61 data := make([]byte, size) 62 for i := range data { 63 data[i] = byte(rng.Int() & 0xff) 64 } 65 return data 66 } 67 68 keys := make([][]byte, 10000) 69 for i := range keys { 70 keys[i] = randBytes(rng.Intn(16)) 71 } 72 sort.Slice(keys, func(i, j int) bool { 73 return DefaultComparer.Compare(keys[i], keys[j]) < 0 74 }) 75 76 for i := 1; i < len(keys); i++ { 77 last := DefaultComparer.AbbreviatedKey(keys[i-1]) 78 cur := DefaultComparer.AbbreviatedKey(keys[i]) 79 cmp := DefaultComparer.Compare(keys[i-1], keys[i]) 80 if cmp == 0 { 81 if last != cur { 82 t.Fatalf("expected equal abbreviated keys: %x[%x] != %x[%x]", 83 last, keys[i-1], cur, keys[i]) 84 } 85 } else { 86 if last > cur { 87 t.Fatalf("unexpected abbreviated key ordering: %x[%x] > %x[%x]", 88 last, keys[i-1], cur, keys[i]) 89 } 90 } 91 } 92 } 93 94 func BenchmarkAbbreviatedKey(b *testing.B) { 95 rng := rand.New(rand.NewSource(1449168817)) 96 randBytes := func(size int) []byte { 97 data := make([]byte, size) 98 for i := range data { 99 data[i] = byte(rng.Int() & 0xff) 100 } 101 return data 102 } 103 keys := make([][]byte, 10000) 104 for i := range keys { 105 keys[i] = randBytes(8) 106 } 107 108 b.ResetTimer() 109 var sum uint64 110 for i := 0; i < b.N; i++ { 111 j := i % len(keys) 112 sum += DefaultComparer.AbbreviatedKey(keys[j]) 113 } 114 115 if testing.Verbose() { 116 // Ensure the compiler doesn't optimize away our benchmark. 117 fmt.Println(sum) 118 } 119 }