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