github.com/scottcagno/storage@v1.8.0/pkg/lsmt/mtbl/rbtree_test.go (about) 1 package mtbl 2 3 import ( 4 "bytes" 5 "fmt" 6 "github.com/scottcagno/storage/pkg/lsmt/binary" 7 "github.com/scottcagno/storage/pkg/util" 8 "log" 9 "strconv" 10 "testing" 11 ) 12 13 const ( 14 thousand = 1000 15 n = 1 16 ) 17 18 func NewEntry(k, v string) *binary.Entry { 19 if v == "" { 20 return &binary.Entry{ 21 Key: []byte(k), 22 } 23 } 24 return &binary.Entry{ 25 Key: []byte(k), 26 Value: []byte(v), 27 } 28 } 29 30 func TestFindNearest(t *testing.T) { 31 tree := NewRBTree() 32 // insert A, E, J, O, T, Z 33 34 tree.Put(NewEntry("e", "e")) 35 tree.Put(NewEntry("a", "a")) 36 tree.Put(NewEntry("t", "t")) 37 tree.Put(NewEntry("z", "z")) 38 tree.Put(NewEntry("j", "j")) 39 tree.Put(NewEntry("o", "o")) 40 41 // print tree 42 tree.Scan(func(e *binary.Entry) bool { 43 fmt.Printf("%s\n", e) 44 return true 45 }) 46 47 // find O 48 key := NewEntry("o", "") 49 a, b, c, d := tree.GetApproxPrevNext(key) 50 fmt.Printf("find-%s: a=%s, b=%s, c=%s, d=%v\n", key, a, b, c, d) 51 52 // find K 53 key = NewEntry("k", "") 54 a, b, c, d = tree.GetApproxPrevNext(key) 55 fmt.Printf("find-%s: a=%q, b=%q, c=%q, d=%v\n", key, a, b, c, d) 56 57 // find F 58 key = NewEntry("f", "") 59 a, b, c, d = tree.GetApproxPrevNext(key) 60 fmt.Printf("find-%s: a=%q, b=%q, c=%q, d=%v\n", key, a, b, c, d) 61 62 tree.Close() 63 } 64 65 func TestNewRBTree(t *testing.T) { 66 var tree *RBTree 67 tree = NewRBTree() 68 util.AssertNotNil(t, tree) 69 tree.Close() 70 } 71 72 func makeKey(i int) *binary.Entry { 73 return &binary.Entry{ 74 Key: []byte(strconv.Itoa(i)), 75 Value: []byte(strconv.Itoa(i)), 76 } 77 } 78 79 // signature: Has(key string) (bool, int64) 80 func TestRbTree_Has(t *testing.T) { 81 tree := NewRBTree() 82 util.AssertLen(t, 0, tree.Len()) 83 for i := 0; i < n*thousand; i++ { 84 tree.Put(makeKey(i)) 85 } 86 for i := 0; i < n*thousand; i++ { 87 ok := tree.Has(makeKey(i)) 88 if !ok { // existing=updated 89 t.Errorf("has: %v", ok) 90 } 91 } 92 util.AssertLen(t, n*thousand, tree.Len()) 93 tree.Close() 94 } 95 96 // signature: Put(key string, val []byte) ([]byte, bool) 97 func TestRbTree_Put(t *testing.T) { 98 tree := NewRBTree() 99 util.AssertLen(t, 0, tree.Len()) 100 for i := 0; i < n*thousand; i++ { 101 _, existing := tree.Put(makeKey(i)) 102 if existing { // existing=updated 103 t.Errorf("putting: %v", existing) 104 } 105 } 106 util.AssertLen(t, n*thousand, tree.Len()) 107 tree.Close() 108 } 109 110 // signature: Get(key string) ([]byte, bool) 111 func TestRbTree_Get(t *testing.T) { 112 tree := NewRBTree() 113 for i := 0; i < n*thousand; i++ { 114 tree.Put(makeKey(i)) 115 } 116 util.AssertLen(t, n*thousand, tree.Len()) 117 for i := 0; i < n*thousand; i++ { 118 val, ok := tree.Get(makeKey(i)) 119 if !ok { 120 t.Errorf("getting: %v", ok) 121 } 122 util.AssertEqual(t, makeKey(i), val) 123 } 124 tree.Close() 125 } 126 127 // signature: Del(key string) ([]byte, bool) 128 func TestRbTree_Del(t *testing.T) { 129 tree := NewRBTree() 130 for i := 0; i < n*thousand; i++ { 131 tree.Put(makeKey(i)) 132 } 133 util.AssertLen(t, n*thousand, tree.Len()) 134 for i := 0; i < n*thousand; i++ { 135 _, ok := tree.Del(makeKey(i)) 136 if !ok { 137 t.Errorf("delete: %v", ok) 138 } 139 } 140 util.AssertLen(t, 0, tree.Len()) 141 tree.Close() 142 } 143 144 // signature: Len() int 145 func TestRbTree_Len(t *testing.T) { 146 tree := NewRBTree() 147 for i := 0; i < n*thousand; i++ { 148 tree.Put(makeKey(i)) 149 } 150 util.AssertLen(t, n*thousand, tree.Len()) 151 tree.Close() 152 } 153 154 // signature: Size() int64 155 func TestRbTree_Size(t *testing.T) { 156 tree := NewRBTree() 157 var numBytes int64 158 for i := 0; i < n*thousand; i++ { 159 key := makeKey(i) 160 numBytes += int64(key.Size()) 161 tree.Put(key) 162 } 163 util.AssertLen(t, numBytes, tree.Size()) 164 log.Printf("size=%d\n", numBytes) 165 tree.Close() 166 } 167 168 // signature: Min() (string, []byte, bool) 169 func TestRbTree_Min(t *testing.T) { 170 tree := NewRBTree() 171 for i := 0; i < n*thousand; i++ { 172 tree.Put(makeKey(i)) 173 } 174 util.AssertLen(t, n*thousand, tree.Len()) 175 k, ok := tree.Min() 176 if !ok { 177 t.Errorf("min: %v", tree) 178 } 179 util.AssertEqual(t, makeKey(0), k) 180 tree.Close() 181 } 182 183 // signature: Max() (string, []byte, bool) 184 func TestRbTree_Max(t *testing.T) { 185 tree := NewRBTree() 186 for i := 0; i < n*thousand; i++ { 187 tree.Put(makeKey(i)) 188 } 189 util.AssertLen(t, n*thousand, tree.Len()) 190 k, ok := tree.Max() 191 if !ok { 192 t.Errorf("min: %v", tree) 193 } 194 util.AssertEqual(t, makeKey(n*thousand-1), k) 195 tree.Close() 196 } 197 198 // signature: ScanFront(iter Iterator) 199 func TestRbTree_ScanFront(t *testing.T) { 200 tree := NewRBTree() 201 for i := 0; i < n*thousand; i++ { 202 tree.Put(makeKey(i)) 203 } 204 util.AssertLen(t, n*thousand, tree.Len()) 205 206 printInfo := true 207 208 // do scan front 209 tree.Scan(func(e *binary.Entry) bool { 210 if e.Key == nil { 211 t.Errorf("scan front, issue with key: %s", e) 212 return false 213 } 214 if printInfo { 215 log.Printf("entry: %s\n", e) 216 } 217 return true 218 }) 219 220 tree.Close() 221 } 222 223 // signature: ScanRange(start Entry, end Entry, iter Iterator) 224 func TestRbTree_ScanRange(t *testing.T) { 225 tree := NewRBTree() 226 for i := 0; i < n*thousand; i++ { 227 tree.Put(makeKey(i)) 228 } 229 util.AssertLen(t, n*thousand, tree.Len()) 230 231 printInfo := true 232 233 start, stop := makeKey(300), makeKey(700) 234 tree.ScanRange(start, stop, func(e *binary.Entry) bool { 235 if e.Key == nil && bytes.Compare(e.Key, start.Key) == -1 && bytes.Compare(e.Key, stop.Key) == 1 { 236 t.Errorf("scan range, issue with key: %s", e) 237 return false 238 } 239 if printInfo { 240 log.Printf("entry: %s\n", e) 241 } 242 return true 243 }) 244 245 tree.Close() 246 } 247 248 // signature: Close() 249 func TestRbTree_Close(t *testing.T) { 250 var tree *RBTree 251 tree = NewRBTree() 252 tree.Close() 253 }