github.com/benz9527/xboot@v0.0.0-20240504061247-c23f15593274/lib/tree/rbtree.go (about) 1 package tree 2 3 import ( 4 "cmp" 5 "sync/atomic" 6 7 "github.com/benz9527/xboot/lib/infra" 8 ) 9 10 type rbNode[K infra.OrderedKey, V any] struct { 11 parent *rbNode[K, V] 12 left *rbNode[K, V] 13 right *rbNode[K, V] 14 key K 15 val V 16 color RBColor 17 hasKV bool 18 } 19 20 func (node *rbNode[K, V]) Color() RBColor { 21 return node.color 22 } 23 24 func (node *rbNode[K, V]) Key() K { 25 return node.key 26 } 27 28 func (node *rbNode[K, V]) Val() V { 29 return node.val 30 } 31 32 func (node *rbNode[K, V]) HasKeyVal() bool { 33 if node == nil { 34 return false 35 } 36 return node.hasKV 37 } 38 39 func (node *rbNode[K, V]) Left() RBNode[K, V] { 40 if node == nil || node.left == nil { 41 return nil 42 } 43 return node.left 44 } 45 46 func (node *rbNode[K, V]) Parent() RBNode[K, V] { 47 if node == nil || node.parent == nil { 48 return nil 49 } 50 return node.parent 51 } 52 53 func (node *rbNode[K, V]) Right() RBNode[K, V] { 54 if node == nil || node.right == nil { 55 return nil 56 } 57 return node.right 58 } 59 60 func (node *rbNode[K, V]) isNilLeaf() bool { 61 return isNilLeaf[K, V](node) 62 } 63 64 func (node *rbNode[K, V]) isRed() bool { 65 return isRed[K, V](node) 66 } 67 68 func (node *rbNode[K, V]) isBlack() bool { 69 return isBlack[K, V](node) 70 } 71 72 func (node *rbNode[K, V]) isRoot() bool { 73 return isRoot[K, V](node) 74 } 75 76 func (node *rbNode[K, V]) isLeaf() bool { 77 return node != nil && node.parent != nil && node.left.isNilLeaf() && node.right.isNilLeaf() 78 } 79 80 func (node *rbNode[K, V]) Direction() RBDirection { 81 if node.isNilLeaf() { 82 // impossible run to here 83 panic( /* debug assertion */ "[rbtree] nil leaf node without direction") 84 } 85 86 if node.isRoot() { 87 return Root 88 } 89 if node == node.parent.left { 90 return Left 91 } 92 return Right 93 } 94 95 func (node *rbNode[K, V]) sibling() *rbNode[K, V] { 96 dir := node.Direction() 97 switch dir { 98 case Left: 99 return node.parent.right 100 case Right: 101 return node.parent.left 102 default: 103 104 } 105 return nil 106 } 107 108 func (node *rbNode[K, V]) hasSibling() bool { 109 return !node.isRoot() && node.sibling() != nil 110 } 111 112 func (node *rbNode[K, V]) uncle() *rbNode[K, V] { 113 return node.parent.sibling() 114 } 115 116 func (node *rbNode[K, V]) hasUncle() bool { 117 return !node.isRoot() && node.parent.hasSibling() 118 } 119 120 func (node *rbNode[K, V]) grandpa() *rbNode[K, V] { 121 return node.parent.parent 122 } 123 124 func (node *rbNode[K, V]) hasGrandpa() bool { 125 return !node.isRoot() && node.parent.parent != nil 126 } 127 128 func (node *rbNode[K, V]) fixLink() { 129 if node.left != nil { 130 node.left.parent = node 131 } 132 if node.right != nil { 133 node.right.parent = node 134 } 135 } 136 137 func (node *rbNode[K, V]) minimum() *rbNode[K, V] { 138 aux := node 139 for ; aux != nil && aux.left != nil; aux = aux.left { 140 } 141 return aux 142 } 143 144 func (node *rbNode[K, V]) maximum() *rbNode[K, V] { 145 aux := node 146 for ; aux != nil && aux.right != nil; aux = aux.right { 147 } 148 return aux 149 } 150 151 // The pred node of the current node is its previous node in sorted order 152 func (node *rbNode[K, V]) pred() *rbNode[K, V] { 153 x := node 154 if x == nil { 155 return nil 156 } 157 aux := x 158 if aux.left != nil { 159 return aux.left.maximum() 160 } 161 162 aux = x.parent 163 // Backtrack to father node that is the x's pred. 164 for aux != nil && x == aux.left { 165 x = aux 166 aux = aux.parent 167 } 168 return aux 169 } 170 171 // The succ node of the current node is its next node in sorted order. 172 func (node *rbNode[K, V]) succ() *rbNode[K, V] { 173 x := node 174 if x == nil { 175 return nil 176 } 177 178 aux := x 179 if aux.right != nil { 180 return aux.right.minimum() 181 } 182 183 aux = x.parent 184 // Backtrack to father node that is the x's succ. 185 for aux != nil && x == aux.right { 186 x = aux 187 aux = aux.parent 188 } 189 return aux 190 } 191 192 type rbTree[K infra.OrderedKey, V any] struct { 193 root *rbNode[K, V] 194 count int64 195 isDesc bool 196 isRmBorrowSucc bool 197 } 198 199 func (tree *rbTree[K, V]) keyCompare(k1, k2 K) int64 { 200 if res := cmp.Compare[K](k1, k2); res < 0 { 201 if !tree.isDesc { 202 return -1 203 } 204 return +1 205 } else if res > 0 { 206 if !tree.isDesc { 207 return +1 208 } 209 return -1 210 } 211 return 0 212 } 213 214 func (tree *rbTree[K, V]) Len() int64 { 215 return atomic.LoadInt64(&tree.count) 216 } 217 218 func (tree *rbTree[K, V]) Root() RBNode[K, V] { 219 return tree.root 220 } 221 222 // References: 223 // https://elixir.bootlin.com/linux/latest/source/lib/rbtree.c 224 // rbtree properties: 225 // https://en.wikipedia.org/wiki/Red%E2%80%93black_tree#Properties 226 // p1. Every node is either red or black. 227 // p2. All NIL nodes are considered black. 228 // p3. A red node does not have a red child. (red-violation) 229 // p4. Every path from a given node to any of its descendant 230 // NIL nodes goes through the same number of black nodes. (black-violation) 231 // p5. (Optional) The root is black. 232 // (Conclusion) If a node X has exactly one child, it must be a red child, 233 // because if it were black, its NIL descendants would sit at a different 234 // black depth than X's NIL child, violating p4. 235 // So the shortest path nodes are black nodes. Otherwise, 236 // the path must contain red node. 237 // The longest path nodes' number is 2 * shortest path nodes' number. 238 239 /* 240 | | 241 X S 242 / \ leftRotate(X) / \ 243 L S ============> X Sd 244 / \ / \ 245 Sc Sd L Sc 246 */ 247 func (tree *rbTree[K, V]) leftRotate(x *rbNode[K, V]) { 248 if x == nil || x.right.isNilLeaf() { 249 // impossible run to here 250 panic( /* debug assertion */ "[rbtree] left rotate node x is nil or x.right is nil") 251 } 252 253 p, y := x.parent, x.right 254 dir := x.Direction() 255 x.right, y.left = y.left, x 256 257 x.fixLink() 258 y.fixLink() 259 260 switch dir { 261 case Root: 262 tree.root = y 263 case Left: 264 p.left = y 265 case Right: 266 p.right = y 267 default: 268 // impossible run to here 269 panic( /* debug assertion */ "[rbtree] unknown node direction to left-rotate") 270 } 271 y.parent = p 272 } 273 274 /* 275 | | 276 X S 277 / \ rightRotate(S) / \ 278 L S <============ X R 279 / \ / \ 280 Sc Sd Sc Sd 281 */ 282 func (tree *rbTree[K, V]) rightRotate(x *rbNode[K, V]) { 283 if x == nil || x.left.isNilLeaf() { 284 // impossible run to here 285 panic( /* debug assertion */ "[rbtree] right rotate node x is nil or x.right is nil") 286 } 287 288 p, y := x.parent, x.left 289 dir := x.Direction() 290 x.left, y.right = y.right, x 291 292 x.fixLink() 293 y.fixLink() 294 295 switch dir { 296 case Root: 297 tree.root = y 298 case Left: 299 p.left = y 300 case Right: 301 p.right = y 302 default: 303 // impossible run to here 304 panic( /* debug assertion */ "[rbtree] unknown node direction to right-rotate") 305 } 306 y.parent = p 307 } 308 309 // i1: Empty rbtree, insert directly, but root node is painted to black. 310 func (tree *rbTree[K, V]) Insert(key K, val V, ifNotPresent ...bool) (err error) { 311 if /* i1 */ tree.root.isNilLeaf() { 312 tree.root = &rbNode[K, V]{ 313 key: key, 314 val: val, 315 hasKV: true, 316 } 317 atomic.AddInt64(&tree.count, 1) 318 return nil 319 } 320 321 var x, y *rbNode[K, V] = tree.root, nil 322 for !x.isNilLeaf() { 323 y = x 324 res := tree.keyCompare(key, x.key) 325 if /* equal */ res == 0 { 326 break 327 } else /* less */ if res < 0 { 328 x = x.left 329 } else /* greater */ { 330 x = x.right 331 } 332 } 333 334 if y.isNilLeaf() { 335 // impossible run to here 336 panic( /* debug assertion */ "[rbtree] insert a new value into nil node") 337 } 338 339 var z *rbNode[K, V] 340 res := tree.keyCompare(key, y.key) 341 if /* equal */ res == 0 { 342 if /* disabled */ ifNotPresent[0] { 343 return infra.NewErrorStack("[rbtree] replace disabled") 344 } 345 y.val = val 346 return nil 347 } else /* less */ if res < 0 { 348 z = &rbNode[K, V]{ 349 key: key, 350 val: val, 351 color: Red, 352 parent: y, 353 hasKV: true, 354 } 355 y.left = z 356 } else /* greater */ { 357 z = &rbNode[K, V]{ 358 key: key, 359 val: val, 360 color: Red, 361 parent: y, 362 hasKV: true, 363 } 364 y.right = z 365 } 366 367 atomic.AddInt64(&tree.count, 1) 368 tree.insertRebalance(z) 369 return nil 370 } 371 372 /* 373 New node X is red by default. 374 375 <X> is a RED node. 376 [X] is a BLACK node (or NIL). 377 {X} is either a RED node or a BLACK node. 378 379 im1: Current node X's parent P is black and P is root, so hold r3 and r4. 380 381 im2: Current node X's parent P is red and P is root, repaint P into black. 382 383 im3: If both the parent P and the uncle U are red, grandpa G is black. 384 (red-violation) 385 After repainted G into red may be still red-violation. 386 Recursive to fix grandpa. 387 388 [G] <G> 389 / \ / \ 390 <P> <U> ====> [P] [U] 391 / / 392 <X> <X> 393 394 im4: The parent P is red but the uncle U is black. (red-violation) 395 X is opposite direction to P. Rotate P to opposite direction. 396 After rotation may be still red-violation. Here must enter im5 to fix. 397 398 [G] [G] 399 / \ rotate(P) / \ 400 <P> [U] ========> <X> [U] 401 \ / 402 <X> <P> 403 404 im5: Handle im4 scenario, current node is the same direction as parent. 405 406 [G] <P> [P] 407 / \ rotate(G) / \ repaint / \ 408 <P> [U] ========> <X> [G] ======> <X> <G> 409 / \ \ 410 <X> [U] [U] 411 */ 412 func (tree *rbTree[K, V]) insertRebalance(x *rbNode[K, V]) { 413 for !x.isNilLeaf() { 414 if x.isRoot() { 415 if x.isRed() { 416 x.color = Black 417 } 418 return 419 } 420 421 if x.parent.isBlack() { 422 return 423 } 424 425 if x.parent.isRoot() { 426 if /* im1 */ x.parent.isBlack() { 427 return 428 } else /* im2 */ { 429 x.parent.color = Black 430 } 431 } 432 433 if /* im3 */ x.hasUncle() && x.uncle().isRed() { 434 x.parent.color = Black 435 x.uncle().color = Black 436 gp := x.grandpa() 437 gp.color = Red 438 x = gp 439 continue 440 } else { 441 if !x.hasUncle() || x.uncle().isBlack() { 442 dir := x.Direction() 443 if /* im4 */ dir != x.parent.Direction() { 444 p := x.parent 445 switch dir { 446 case Left: 447 tree.rightRotate(p) 448 case Right: 449 tree.leftRotate(p) 450 default: 451 // impossible run to here 452 panic( /* debug assertion */ "[x-conc-skl] rbtree insert violate (im4)") 453 } 454 x = p // enter im5 to fix 455 } 456 457 switch /* im5 */ dir = x.parent.Direction(); dir { 458 case Left: 459 tree.rightRotate(x.grandpa()) 460 case Right: 461 tree.leftRotate(x.grandpa()) 462 default: 463 // impossible run to here 464 panic( /* debug assertion */ "[x-conc-skl] rbtree insert violate (im5)") 465 } 466 467 x.parent.color = Black 468 x.sibling().color = Red 469 return 470 } 471 } 472 } 473 } 474 475 /* 476 r1: Only a root node, remove directly. 477 478 r2: Current node X has left and right node. 479 Find node X's pred or succ to replace it to be removed. 480 Swap the value only. 481 Both of pred and succ are nil left and right node. 482 483 Find pred: 484 485 | | 486 X L 487 / \ / \ 488 L .. swap(X, L) X .. 489 | =========> | 490 P P 491 / \ / \ 492 S .. S .. 493 494 Find succ: 495 496 | | 497 X S 498 / \ / \ 499 L .. swap(X, S) L .. 500 | =========> | 501 P P 502 / \ / \ 503 S .. X .. 504 505 r3: (1) Current node X is a red leaf node, remove directly. 506 507 r3: (2) Current node X is a black leaf node, we have to rebalance after remove. 508 (black-violation) 509 510 r4: Current node X is not a leaf node but contains a not nil child node. 511 The child node must be a red node. (See conclusion. Otherwise, black-violation) 512 */ 513 func (tree *rbTree[K, V]) removeNode(z *rbNode[K, V]) (res *rbNode[K, V], err error) { 514 if /* r1 */ atomic.LoadInt64(&tree.count) == 1 && z.isRoot() { 515 tree.root = nil 516 z.left = nil 517 z.right = nil 518 return z, nil 519 } 520 521 res = &rbNode[K, V]{ 522 val: z.val, 523 key: z.key, 524 } 525 526 y := z 527 if /* r2 */ !y.left.isNilLeaf() && !y.right.isNilLeaf() { 528 if tree.isRmBorrowSucc { 529 y = z.succ() // enter r3-r4 530 } else { 531 y = z.pred() // enter r3-r4 532 } 533 // Swap key & value. 534 z.key, z.val = y.key, y.val 535 z.hasKV = true 536 } 537 538 if /* r3 */ y.isLeaf() { 539 if /* r3 (1) */ y.isRed() { 540 switch dir := y.Direction(); dir { 541 case Left: 542 y.parent.left = nil 543 case Right: 544 y.parent.right = nil 545 default: 546 // impossible run to here 547 panic( /* debug assertion */ "[rbtree] y should be a leaf node, violate (r3-1)") 548 } 549 return res, nil 550 } else /* r3 (2) */ { 551 tree.removeRebalance(y) 552 } 553 } else /* r4 */ { 554 var replace *rbNode[K, V] 555 if !y.right.isNilLeaf() { 556 replace = y.right 557 } else if !y.left.isNilLeaf() { 558 replace = y.left 559 } 560 561 if replace == nil { 562 // impossible run to here 563 panic( /* debug assertion */ "[rbtree] remove a leaf node without child, violate (r4)") 564 } 565 566 switch dir := y.Direction(); dir { 567 case Root: 568 tree.root = replace 569 tree.root.parent = nil 570 case Left: 571 y.parent.left = replace 572 replace.parent = y.parent 573 case Right: 574 y.parent.right = replace 575 replace.parent = y.parent 576 default: 577 // impossible run to here 578 panic( /* debug assertion */ "[x-conc-skl] rbtree impossible run to here") 579 } 580 581 if y.isBlack() { 582 if replace.isRed() { 583 replace.color = Black 584 } else { 585 tree.removeRebalance(replace) 586 } 587 } 588 } 589 590 // Unlink node 591 if !y.isRoot() && y == y.parent.left { 592 y.parent.left = nil 593 } else if !y.isRoot() && y == y.parent.right { 594 y.parent.right = nil 595 } 596 y.parent = nil 597 y.left = nil 598 y.right = nil 599 y.hasKV = false 600 601 return res, nil 602 } 603 604 func (tree *rbTree[K, V]) Remove(key K) (RBNode[K, V], error) { 605 if atomic.LoadInt64(&tree.count) <= 0 { 606 return nil, infra.NewErrorStack("[rbtree] empty element to remove") 607 } 608 z := tree.Search(tree.root, func(node RBNode[K, V]) int64 { 609 return tree.keyCompare(key, node.Key()) 610 }) 611 if z == nil { 612 return nil, infra.NewErrorStack("[rbtree] key not found") 613 } 614 defer func() { 615 atomic.AddInt64(&tree.count, -1) 616 }() 617 618 return tree.removeNode(z.(*rbNode[K, V])) 619 } 620 621 func (tree *rbTree[K, V]) RemoveMin() (RBNode[K, V], error) { 622 if atomic.LoadInt64(&tree.count) <= 0 { 623 return nil, infra.NewErrorStack("[rbtree] key not found") 624 } 625 _min := tree.root.minimum() 626 if _min.isNilLeaf() { 627 return nil, infra.NewErrorStack("[rbtree] key not found") 628 } 629 defer func() { 630 atomic.AddInt64(&tree.count, -1) 631 }() 632 return tree.removeNode(_min) 633 } 634 635 /* 636 <X> is a RED node. 637 [X] is a BLACK node (or NIL). 638 {X} is either a RED node or a BLACK node. 639 640 Sc is the same direction to X and it X's sibling's child node. 641 Sd is the opposite direction to X and it X's sibling's child node. 642 643 rm1: Current node X's sibling S is red, so the parent P, nephew node Sc and Sd 644 must be black. (Otherwise, red-violation) 645 (1) X is left node of P, left rotate P 646 (2) X is right node of P, right rotate P. 647 (3) repaint S into black, P into red. 648 649 [P] <S> [S] 650 / \ l-rotate(P) / \ repaint / \ 651 [X] <S> ==========> [P] [D] ======> <P> [Sd] 652 / \ / \ / \ 653 [Sc] [Sd] [X] [Sc] [X] [Sc] 654 655 rm2: Current node X's parent P is red, the sibling S, nephew node Sc and Sd 656 is black. 657 Repaint S into red and P into black. 658 659 <P> [P] 660 / \ / \ 661 [X] [S] ====> [X] <S> 662 / \ / \ 663 [Sc] [Sd] [Sc] [Sd] 664 665 rm3: All of current node X's parent P, the sibling S, nephew node Sc and Sd 666 are black. 667 Unable to satisfy p3 and p4. We have to paint the S into red to satisfy 668 p4 locally. Then recursive to handle P. 669 670 [P] [P] 671 / \ / \ 672 [X] [S] ====> [X] <S> 673 / \ / \ 674 [Sc] [Sd] [Sc] [Sd] 675 676 rm4: Current node X's sibling S is black, nephew node Sc is red and Sd 677 is black. Ignore X's parent P's color (red or black is okay) 678 Unable to satisfy p3 and p4. 679 (1) If X is left node of P, right rotate P. 680 (2) If X is right node of P, left rotate P. 681 (3) Repaint S into red, Sc into black 682 Enter into rm5 to fix. 683 684 {P} {P} 685 {P} / \ / \ 686 / \ r-rotate(S) [X] <Sc> repaint [X] [Sc] 687 [X] [S] ==========> \ ======> \ 688 / \ [S] <S> 689 <Sc> [Sd] \ \ 690 [Sd] [Sd] 691 692 rm5: Current node X's sibling S is black, nephew node Sc is black and Sd 693 is red. Ignore X's parent P's color (red or black is okay) 694 Unable to satisfy p4 (black-violation) 695 (1) If X is left node of P, left rotate P. 696 (2) If X is right node of P, right rotate P. 697 (3) Swap P and S's color (red-violation) 698 (4) Repaint Sd into black. 699 700 {P} [S] {S} 701 / \ l-rotate(P) / \ repaint / \ 702 [X] [S] ==========> {P} <Sd> ======> [P] [Sd] 703 / \ / \ / \ 704 [Sc] <Sd> [X] [Sc] [X] [Sc] 705 */ 706 func (tree *rbTree[K, V]) removeRebalance(x *rbNode[K, V]) { 707 for { 708 if x.isRoot() { 709 return 710 } 711 712 sibling := x.sibling() 713 dir := x.Direction() 714 if /* rm1 */ sibling.isRed() { 715 switch dir { 716 case Left: 717 tree.leftRotate(x.parent) 718 case Right: 719 tree.rightRotate(x.parent) 720 default: 721 // impossible run to here 722 panic( /* debug assertion */ "[rbtree] remove violate (rm1)") 723 } 724 sibling.color = Black 725 x.parent.color = Red // ready to enter rm2 726 sibling = x.sibling() 727 } 728 729 var sc, sd *rbNode[K, V] 730 switch /* rm2 */ dir { 731 case Left: 732 sc, sd = sibling.left, sibling.right 733 case Right: 734 sc, sd = sibling.right, sibling.left 735 default: 736 // impossible run to here 737 panic( /* debug assertion */ "[x-conc-skl] rbtree remove violate (rm2)") 738 } 739 740 if sc.isBlack() && sd.isBlack() { 741 if /* rm2 */ x.parent.isRed() { 742 sibling.color = Red 743 x.parent.color = Black 744 break 745 } else /* rm3 */ { 746 sibling.color = Red 747 x = x.parent 748 continue 749 } 750 } else { 751 if /* rm 4 */ !sc.isNilLeaf() && sc.isRed() { 752 switch dir { 753 case Left: 754 tree.rightRotate(sibling) 755 case Right: 756 tree.leftRotate(sibling) 757 default: 758 // impossible run to here 759 panic( /* debug assertion */ "[x-conc-skl] rbtree remove violate (rm4)") 760 } 761 sc.color = Black 762 sibling.color = Red 763 sibling = x.sibling() 764 switch dir { 765 case Left: 766 sd = sibling.right 767 case Right: 768 sd = sibling.left 769 default: 770 // impossible run to here 771 panic( /* debug assertion */ "[x-conc-skl] rbtree remove violate (rm4)") 772 } 773 } 774 775 switch /* rm5 */ dir { 776 case Left: 777 tree.leftRotate(x.parent) 778 case Right: 779 tree.rightRotate(x.parent) 780 default: 781 // impossible run to here 782 panic( /* debug assertion */ "[x-conc-skl] rbtree remove violate (rm5)") 783 } 784 sibling.color = x.parent.color 785 x.parent.color = Black 786 if !sd.isNilLeaf() { 787 sd.color = Black 788 } 789 break 790 } 791 } 792 } 793 794 func (tree *rbTree[K, V]) Search(x RBNode[K, V], fn func(RBNode[K, V]) int64) RBNode[K, V] { 795 if x == nil { 796 return nil 797 } 798 799 for aux := x; aux != nil; { 800 res := fn(aux) 801 if res == 0 { 802 return aux 803 } else if res > 0 { 804 aux = aux.Right() 805 } else { 806 aux = aux.Left() 807 } 808 } 809 return nil 810 } 811 812 // Inorder traversal to implement the DFS. 813 func (tree *rbTree[K, V]) Foreach(action func(idx int64, color RBColor, key K, val V) bool) { 814 size := atomic.LoadInt64(&tree.count) 815 aux := tree.root 816 if size < 0 || aux == nil { 817 return 818 } 819 820 stack := make([]*rbNode[K, V], 0, size>>1) 821 defer func() { 822 clear(stack) 823 }() 824 825 for ; !aux.isNilLeaf(); aux = aux.left { 826 stack = append(stack, aux) 827 } 828 829 idx := int64(0) 830 for size = int64(len(stack)); size > 0; size = int64(len(stack)) { 831 if aux = stack[size-1]; !action(idx, aux.color, aux.key, aux.val) { 832 return 833 } 834 idx++ 835 stack = stack[:size-1] 836 if aux.right != nil { 837 for aux = aux.right; aux != nil; aux = aux.left { 838 stack = append(stack, aux) 839 } 840 } 841 } 842 } 843 844 func (tree *rbTree[K, V]) Release() { 845 size := atomic.LoadInt64(&tree.count) 846 aux := tree.root 847 tree.root = nil 848 if size < 0 || aux == nil { 849 return 850 } 851 852 stack := make([]*rbNode[K, V], 0, size>>1) 853 defer func() { 854 clear(stack) 855 }() 856 857 for ; !aux.isNilLeaf(); aux = aux.left { 858 stack = append(stack, aux) 859 } 860 861 for size = int64(len(stack)); size > 0; size = int64(len(stack)) { 862 aux = stack[size-1] 863 r := aux.right 864 aux.right, aux.parent = nil, nil 865 atomic.AddInt64(&tree.count, -1) 866 stack = stack[:size-1] 867 if r != nil { 868 for aux = r; aux != nil; aux = aux.left { 869 stack = append(stack, aux) 870 } 871 } 872 } 873 } 874 875 type RBTreeOpt[K infra.OrderedKey, V any] func(*rbTree[K, V]) 876 877 func WithRBTreeDesc[K infra.OrderedKey, V any]() RBTreeOpt[K, V] { 878 return func(tree *rbTree[K, V]) { 879 tree.isDesc = true 880 } 881 } 882 883 func WithRBTreeRemoveBorrowSucc[K infra.OrderedKey, V any]() RBTreeOpt[K, V] { 884 return func(tree *rbTree[K, V]) { 885 tree.isRmBorrowSucc = true 886 } 887 } 888 889 func NewRBTree[K infra.OrderedKey, V any](opts ...RBTreeOpt[K, V]) RBTree[K, V] { 890 tree := &rbTree[K, V]{ 891 count: 0, 892 isDesc: false, 893 isRmBorrowSucc: false, 894 } 895 896 for _, o := range opts { 897 o(tree) 898 } 899 return tree 900 }