github.com/scottcagno/storage@v1.8.0/pkg/_junk/_index/rbtree/rbtree.go (about) 1 package rbtree 2 3 import ( 4 "container/list" 5 "encoding/binary" 6 "fmt" 7 "strconv" 8 "strings" 9 ) 10 11 type entry struct { 12 key string 13 value []byte 14 } 15 16 func (e entry) String() string { 17 return fmt.Sprintf("entry.key=%q, entry.value=%q\n", e.key, e.value) 18 } 19 20 var empty = *new(entry) 21 22 func isempty(e entry) bool { 23 return e.key == "" 24 } 25 26 func compare(this, that entry) int { 27 if len(this.key) < len(that.key) { 28 return -1 29 } 30 if len(this.key) > len(that.key) { 31 return +1 32 } 33 if this.key < that.key { 34 return -1 35 } 36 if this.key > that.key { 37 return 1 38 } 39 return 0 40 } 41 42 const ( 43 RED = 0 44 BLACK = 1 45 ) 46 47 type rbNode struct { 48 left *rbNode 49 right *rbNode 50 parent *rbNode 51 color uint 52 entry entry 53 } 54 55 type RBTree = rbTree 56 57 // rbTree is a struct representing a rbTree 58 type rbTree struct { 59 NIL *rbNode 60 root *rbNode 61 count int 62 size int64 63 } 64 65 func NewRBTree() *rbTree { 66 return newRBTree() 67 } 68 69 // NewTree creates and returns a new rbTree 70 func newRBTree() *rbTree { 71 n := &rbNode{ 72 left: nil, 73 right: nil, 74 parent: nil, 75 color: BLACK, 76 entry: empty, 77 } 78 return &rbTree{ 79 NIL: n, 80 root: n, 81 count: 0, 82 } 83 } 84 85 // Has tests and returns a boolean value if the 86 // provided key exists in the tree 87 func (t *rbTree) Has(key string) bool { 88 _, ok := t.get(key) 89 return ok 90 } 91 92 // HasInt tests and returns a boolean value if the 93 // provided key exists in the tree 94 func (t *rbTree) HasInt(key int64) bool { 95 _, ok := t.get(IntToKey(key)) 96 return ok 97 } 98 99 // Add adds the provided key and value only if it does not 100 // already exist in the tree. It returns false if the key and 101 // value was not able to be added, and true if it was added 102 // successfully 103 func (t *rbTree) Add(key string, value []byte) bool { 104 _, ok := t.get(key) 105 if ok { 106 // key already exists, so we are not adding 107 return false 108 } 109 t.put(key, value) 110 return true 111 } 112 113 // AddInt adds the provided key and value only if it does not 114 // already exist in the tree. It returns false if the key and 115 // value was not able to be added, and true if it was added 116 // successfully 117 func (t *rbTree) AddInt(key int64, value int64) bool { 118 _, ok := t.get(IntToKey(key)) 119 if ok { 120 // key already exists, so we are not adding 121 return false 122 } 123 t.put(IntToKey(key), IntToVal(value)) 124 return true 125 } 126 127 func (t *rbTree) Put(key string, value []byte) ([]byte, bool) { 128 return t.put(key, value) 129 } 130 131 func (t *rbTree) PutInt(key int64, value int64) (int64, bool) { 132 val, ok := t.put(IntToKey(key), IntToVal(value)) 133 return ValToInt(val), ok 134 } 135 136 func (t *rbTree) put(key string, value []byte) ([]byte, bool) { 137 e := entry{key: key, value: value} 138 if isempty(e) { 139 return nil, false 140 } 141 // insert returns the node inserted 142 // and if the node returned already 143 // existed and/or was updated 144 ret, ok := t.insert(&rbNode{ 145 left: t.NIL, 146 right: t.NIL, 147 parent: t.NIL, 148 color: RED, 149 entry: e, 150 }) 151 return ret.entry.value, ok 152 } 153 154 func (t *rbTree) Get(key string) ([]byte, bool) { 155 return t.get(key) 156 } 157 158 func (t *rbTree) GetInt(key int64) (int64, bool) { 159 val, ok := t.get(IntToKey(key)) 160 return ValToInt(val), ok 161 } 162 163 func (t *rbTree) get(key string) ([]byte, bool) { 164 e := entry{key: key} 165 if isempty(e) { 166 return nil, false 167 } 168 ret := t.search(&rbNode{ 169 left: t.NIL, 170 right: t.NIL, 171 parent: t.NIL, 172 color: RED, 173 entry: e, 174 }) 175 return ret.entry.value, !isempty(ret.entry) 176 } 177 178 func (t *rbTree) Del(key string) ([]byte, bool) { 179 return t.del(key) 180 } 181 182 func (t *rbTree) DelInt(key int64) (int64, bool) { 183 val, ok := t.del(IntToKey(key)) 184 return ValToInt(val), ok 185 } 186 187 func (t *rbTree) del(key string) ([]byte, bool) { 188 e := entry{key: key} 189 if isempty(e) { 190 return nil, false 191 } 192 cnt := t.count 193 ret := t.delete(&rbNode{ 194 left: t.NIL, 195 right: t.NIL, 196 parent: t.NIL, 197 color: RED, 198 entry: e, 199 }) 200 return ret.entry.value, cnt == t.count+1 201 } 202 203 func (t *rbTree) Len() int { 204 return t.count 205 } 206 207 // Size returns the size in bytes 208 func (t *rbTree) Size() int64 { 209 return t.size 210 } 211 212 func (t *rbTree) Min() (string, []byte, bool) { 213 x := t.min(t.root) 214 if x == t.NIL { 215 return "", nil, false 216 } 217 return x.entry.key, x.entry.value, true 218 } 219 220 func (t *rbTree) Max() (string, []byte, bool) { 221 x := t.max(t.root) 222 if x == t.NIL { 223 return "", nil, false 224 } 225 return x.entry.key, x.entry.value, true 226 } 227 228 type Iterator func(key string, value []byte) bool 229 230 func (t *rbTree) ScanFront(iter Iterator) { 231 t.ascend(t.root, t.min(t.root).entry, iter) 232 } 233 234 func (t *rbTree) ScanBack(iter Iterator) { 235 t.descend(t.root, t.max(t.root).entry, iter) 236 } 237 238 func (t *rbTree) ScanRange(startKey, endKey string, iter Iterator) { 239 t.ascendRange(t.root, startKey, endKey, iter) 240 } 241 242 func (t *rbTree) ToList() (*list.List, error) { 243 if t.count < 1 { 244 return nil, fmt.Errorf("Error: there are not enough entrys in the tree\n") 245 } 246 li := list.New() 247 t.ascend(t.root, t.min(t.root).entry, func(key string, value []byte) bool { 248 li.PushBack(entry{key: key, value: value}) 249 return true 250 }) 251 return li, nil 252 } 253 254 func (t *rbTree) FromList(li *list.List) error { 255 for e := li.Front(); e != nil; e = e.Next() { 256 ent, ok := e.Value.(entry) 257 if !ok { 258 return fmt.Errorf("Error: cannot add to tree, element (%T) "+ 259 "does not implement the entry interface\n", ent.value) 260 } 261 t.put(ent.key, ent.value) 262 } 263 return nil 264 } 265 266 func (t *rbTree) String() string { 267 var sb strings.Builder 268 t.ascend(t.root, t.min(t.root).entry, func(key string, value []byte) bool { 269 sb.WriteString(entry{key: key, value: value}.String()) 270 return true 271 }) 272 return sb.String() 273 } 274 275 func (t *rbTree) Close() { 276 t.NIL = nil 277 t.root = nil 278 t.count = 0 279 return 280 } 281 282 func (t *rbTree) insert(z *rbNode) (*rbNode, bool) { 283 x := t.root 284 y := t.NIL 285 for x != t.NIL { 286 y = x 287 if compare(z.entry, x.entry) == -1 { 288 x = x.left 289 } else if compare(x.entry, z.entry) == -1 { 290 x = x.right 291 } else { 292 t.size -= int64(len(x.entry.key) + len(x.entry.value)) 293 t.size += int64(len(z.entry.key) + len(z.entry.value)) 294 // originally we were just returning x 295 // without updating the entry, but if we 296 // want it to have similar behavior to 297 // a hashmap then we need to update any 298 // entries that already exist in the tree 299 x.entry = z.entry 300 return x, true // true means an existing 301 // value was found and updated. It should 302 // be noted that we don't need to re-balance 303 // the tree because they keys are not changing 304 // and the tree is balance is maintained by 305 // the keys and not their values. 306 } 307 } 308 z.parent = y 309 if y == t.NIL { 310 t.root = z 311 } else if compare(z.entry, y.entry) == -1 { 312 y.left = z 313 } else { 314 y.right = z 315 } 316 t.count++ 317 t.size += int64(len(z.entry.key) + len(z.entry.value)) 318 t.insertFixup(z) 319 return z, false 320 } 321 322 func (t *rbTree) leftRotate(x *rbNode) { 323 if x.right == t.NIL { 324 return 325 } 326 y := x.right 327 x.right = y.left 328 if y.left != t.NIL { 329 y.left.parent = x 330 } 331 y.parent = x.parent 332 if x.parent == t.NIL { 333 t.root = y 334 } else if x == x.parent.left { 335 x.parent.left = y 336 } else { 337 x.parent.right = y 338 } 339 y.left = x 340 x.parent = y 341 } 342 343 func (t *rbTree) rightRotate(x *rbNode) { 344 if x.left == t.NIL { 345 return 346 } 347 y := x.left 348 x.left = y.right 349 if y.right != t.NIL { 350 y.right.parent = x 351 } 352 y.parent = x.parent 353 354 if x.parent == t.NIL { 355 t.root = y 356 } else if x == x.parent.left { 357 x.parent.left = y 358 } else { 359 x.parent.right = y 360 } 361 362 y.right = x 363 x.parent = y 364 } 365 366 func (t *rbTree) insertFixup(z *rbNode) { 367 for z.parent.color == RED { 368 if z.parent == z.parent.parent.left { 369 y := z.parent.parent.right 370 if y.color == RED { 371 z.parent.color = BLACK 372 y.color = BLACK 373 z.parent.parent.color = RED 374 z = z.parent.parent 375 } else { 376 if z == z.parent.right { 377 z = z.parent 378 t.leftRotate(z) 379 } 380 z.parent.color = BLACK 381 z.parent.parent.color = RED 382 t.rightRotate(z.parent.parent) 383 } 384 } else { 385 y := z.parent.parent.left 386 if y.color == RED { 387 z.parent.color = BLACK 388 y.color = BLACK 389 z.parent.parent.color = RED 390 z = z.parent.parent 391 } else { 392 if z == z.parent.left { 393 z = z.parent 394 t.rightRotate(z) 395 } 396 z.parent.color = BLACK 397 z.parent.parent.color = RED 398 t.leftRotate(z.parent.parent) 399 } 400 } 401 } 402 t.root.color = BLACK 403 } 404 405 func (t *rbTree) search(x *rbNode) *rbNode { 406 p := t.root 407 for p != t.NIL { 408 if compare(p.entry, x.entry) == -1 { 409 p = p.right 410 } else if compare(x.entry, p.entry) == -1 { 411 p = p.left 412 } else { 413 break 414 } 415 } 416 return p 417 } 418 419 // min traverses from root to left recursively until left is NIL 420 func (t *rbTree) min(x *rbNode) *rbNode { 421 if x == t.NIL { 422 return t.NIL 423 } 424 for x.left != t.NIL { 425 x = x.left 426 } 427 return x 428 } 429 430 // max traverses from root to right recursively until right is NIL 431 func (t *rbTree) max(x *rbNode) *rbNode { 432 if x == t.NIL { 433 return t.NIL 434 } 435 for x.right != t.NIL { 436 x = x.right 437 } 438 return x 439 } 440 441 func (t *rbTree) successor(x *rbNode) *rbNode { 442 if x == t.NIL { 443 return t.NIL 444 } 445 if x.right != t.NIL { 446 return t.min(x.right) 447 } 448 y := x.parent 449 for y != t.NIL && x == y.right { 450 x = y 451 y = y.parent 452 } 453 return y 454 } 455 456 func (t *rbTree) delete(key *rbNode) *rbNode { 457 z := t.search(key) 458 if z == t.NIL { 459 return t.NIL 460 } 461 ret := &rbNode{t.NIL, t.NIL, t.NIL, z.color, z.entry} 462 var y *rbNode 463 var x *rbNode 464 if z.left == t.NIL || z.right == t.NIL { 465 y = z 466 } else { 467 y = t.successor(z) 468 } 469 if y.left != t.NIL { 470 x = y.left 471 } else { 472 x = y.right 473 } 474 x.parent = y.parent 475 476 if y.parent == t.NIL { 477 t.root = x 478 } else if y == y.parent.left { 479 y.parent.left = x 480 } else { 481 y.parent.right = x 482 } 483 if y != z { 484 z.entry = y.entry 485 } 486 if y.color == BLACK { 487 t.deleteFixup(x) 488 } 489 t.size -= int64(len(ret.entry.key) + len(ret.entry.value)) 490 t.count-- 491 return ret 492 } 493 494 func (t *rbTree) deleteFixup(x *rbNode) { 495 for x != t.root && x.color == BLACK { 496 if x == x.parent.left { 497 w := x.parent.right 498 if w.color == RED { 499 w.color = BLACK 500 x.parent.color = RED 501 t.leftRotate(x.parent) 502 w = x.parent.right 503 } 504 if w.left.color == BLACK && w.right.color == BLACK { 505 w.color = RED 506 x = x.parent 507 } else { 508 if w.right.color == BLACK { 509 w.left.color = BLACK 510 w.color = RED 511 t.rightRotate(w) 512 w = x.parent.right 513 } 514 w.color = x.parent.color 515 x.parent.color = BLACK 516 w.right.color = BLACK 517 t.leftRotate(x.parent) 518 // this is to exit while loop 519 x = t.root 520 } 521 } else { 522 w := x.parent.left 523 if w.color == RED { 524 w.color = BLACK 525 x.parent.color = RED 526 t.rightRotate(x.parent) 527 w = x.parent.left 528 } 529 if w.left.color == BLACK && w.right.color == BLACK { 530 w.color = RED 531 x = x.parent 532 } else { 533 if w.left.color == BLACK { 534 w.right.color = BLACK 535 w.color = RED 536 t.leftRotate(w) 537 w = x.parent.left 538 } 539 w.color = x.parent.color 540 x.parent.color = BLACK 541 w.left.color = BLACK 542 t.rightRotate(x.parent) 543 x = t.root 544 } 545 } 546 } 547 x.color = BLACK 548 } 549 550 func (t *rbTree) ascend(x *rbNode, entry entry, iter Iterator) bool { 551 if x == t.NIL { 552 return true 553 } 554 if !(compare(x.entry, entry) == -1) { 555 if !t.ascend(x.left, entry, iter) { 556 return false 557 } 558 if !iter(x.entry.key, x.entry.value) { 559 return false 560 } 561 } 562 return t.ascend(x.right, entry, iter) 563 } 564 565 func (t *rbTree) Descend(pivot entry, iter Iterator) { 566 t.descend(t.root, pivot, iter) 567 } 568 569 func (t *rbTree) descend(x *rbNode, pivot entry, iter Iterator) bool { 570 if x == t.NIL { 571 return true 572 } 573 if !(compare(pivot, x.entry) == -1) { 574 if !t.descend(x.right, pivot, iter) { 575 return false 576 } 577 if !iter(x.entry.key, x.entry.value) { 578 return false 579 } 580 } 581 return t.descend(x.left, pivot, iter) 582 } 583 584 func (t *rbTree) ascendRange(x *rbNode, inf, sup string, iter Iterator) bool { 585 if x == t.NIL { 586 return true 587 } 588 if !(compare(x.entry, entry{key: sup}) == -1) { 589 return t.ascendRange(x.left, inf, sup, iter) 590 } 591 if compare(x.entry, entry{key: inf}) == -1 { 592 return t.ascendRange(x.right, inf, sup, iter) 593 } 594 if !t.ascendRange(x.left, inf, sup, iter) { 595 return false 596 } 597 if !iter(x.entry.key, x.entry.value) { 598 return false 599 } 600 return t.ascendRange(x.right, inf, sup, iter) 601 } 602 603 func IntToKey(key int64) string { 604 return "i" + strconv.FormatInt(key, 10) 605 } 606 607 func KeyToInt(key string) int64 { 608 if len(key) != 11 || key[0] != 'i' { 609 return -1 610 } 611 ikey, err := strconv.ParseInt(key[1:], 10, 0) 612 if err != nil { 613 return -1 614 } 615 return ikey 616 } 617 618 func IntToVal(val int64) []byte { 619 buf := make([]byte, 1+binary.MaxVarintLen64) 620 buf[0] = 'i' 621 _ = binary.PutVarint(buf[1:], val) 622 return buf 623 } 624 625 func ValToInt(val []byte) int64 { 626 if len(val) != 11 || val[0] != 'i' { 627 return -1 628 } 629 ival, n := binary.Varint(val[1:]) 630 if ival == 0 && n <= 0 { 631 return -1 632 } 633 return ival 634 }