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