1 /******************************************************************************* 2 3 Based upon Doug Lea's Java collection package 4 5 Copyright: 6 Copyright (c) 2008 Kris Bell. 7 Some parts copyright (c) 2009-2016 dunnhumby Germany GmbH. 8 All rights reserved. 9 10 License: 11 Tango Dual License: 3-Clause BSD License / Academic Free License v3.0. 12 See LICENSE_TANGO.txt for details. 13 14 Version: Apr 2008: Initial release 15 16 Authors: Kris, tsalm 17 18 *******************************************************************************/ 19 20 module ocean.util.container.RedBlack; 21 22 import ocean.transition; 23 24 import ocean.util.container.model.IContainer; 25 26 private 27 { 28 mixin(Typedef!(int, "AttributeDummy")); 29 } 30 31 /******************************************************************************* 32 33 RedBlack implements basic capabilities of Red-Black trees, 34 an efficient kind of balanced binary tree. The particular 35 algorithms used are adaptations of those in Corman, 36 Lieserson, and Rivest's <EM>Introduction to Algorithms</EM>. 37 This class was inspired by (and code cross-checked with) a 38 similar class by Chuck McManis. The implementations of 39 rebalancings during insertion and deletion are 40 a little trickier than those versions since they 41 don't swap Cell contents or use special dummy nilnodes. 42 43 Doug Lea 44 45 *******************************************************************************/ 46 47 struct RedBlack (V, A = AttributeDummy) 48 { 49 import ocean.core.Verify; 50 51 alias RedBlack!(V, A) Type; 52 alias Type *Ref; 53 54 enum : bool {RED = false, BLACK = true} 55 56 /** 57 * Pointer to left child 58 **/ 59 60 package Ref left; 61 62 /** 63 * Pointer to right child 64 **/ 65 66 package Ref right; 67 68 /** 69 * Pointer to parent (null if root) 70 **/ 71 72 package Ref parent; 73 74 package V value; 75 76 static if (!is(typeof(A) == AttributeDummy)) 77 { 78 A attribute; 79 } 80 81 /** 82 * The node color (RED, BLACK) 83 **/ 84 85 package bool color; 86 87 static if (!is(typeof(A) == AttributeDummy)) 88 { 89 final Ref set (V v, A a) 90 { 91 attribute = a; 92 return set (v); 93 } 94 } 95 96 /** 97 * Make a new Cell with given value, null links, and BLACK color. 98 * Normally only called to establish a new root. 99 **/ 100 101 final Ref set (V v) 102 { 103 value = v; 104 left = null; 105 right = null; 106 parent = null; 107 color = BLACK; 108 return (&this); 109 } 110 111 /** 112 * Return a new Ref with same value and color as self, 113 * but with null links. (Since it is never OK to have 114 * multiple identical links in a RB tree.) 115 **/ 116 117 protected Ref dup (scope Ref delegate() alloc) 118 { 119 static if (is(typeof(A) == AttributeDummy)) 120 auto t = alloc().set (value); 121 else 122 auto t = alloc().set (value, attribute); 123 124 t.color = color; 125 return t; 126 } 127 128 129 /** 130 * See_Also: ocean.util.collection.model.View.View.checkImplementation. 131 **/ 132 public void checkImplementation () 133 { 134 135 // It's too hard to check the property that every simple 136 // path from node to leaf has same number of black nodes. 137 // So restrict to the following 138 139 verify(parent is null || 140 (&this) is parent.left || 141 (&this) is parent.right); 142 143 verify(left is null || 144 (&this) is left.parent); 145 146 verify(right is null || 147 (&this) is right.parent); 148 149 verify(color is BLACK || 150 (colorOf(left) is BLACK) && (colorOf(right) is BLACK)); 151 152 if (left !is null) 153 left.checkImplementation(); 154 if (right !is null) 155 right.checkImplementation(); 156 } 157 158 /** 159 * Return the minimum value of the current (sub)tree 160 **/ 161 162 Ref leftmost () 163 { 164 auto p = (&this); 165 for ( ; p.left; p = p.left) {} 166 return p; 167 } 168 169 /** 170 * Return the maximum value of the current (sub)tree 171 **/ 172 Ref rightmost () 173 { 174 auto p = (&this); 175 for ( ; p.right; p = p.right) {} 176 return p; 177 } 178 179 /** 180 * Return the root (parentless node) of the tree 181 **/ 182 Ref root () 183 { 184 auto p = (&this); 185 for ( ; p.parent; p = p.parent) {} 186 return p; 187 } 188 189 /** 190 * Return true if node is a root (i.e., has a null parent) 191 **/ 192 193 bool isRoot () 194 { 195 return parent is null; 196 } 197 198 199 /** 200 * Return the inorder successor, or null if no such 201 **/ 202 203 Ref successor () 204 { 205 if (right) 206 return right.leftmost; 207 208 auto p = parent; 209 auto ch = (&this); 210 while (p && ch is p.right) 211 { 212 ch = p; 213 p = p.parent; 214 } 215 return p; 216 } 217 218 /** 219 * Return the inorder predecessor, or null if no such 220 **/ 221 222 Ref predecessor () 223 { 224 if (left) 225 return left.rightmost; 226 227 auto p = parent; 228 auto ch = (&this); 229 while (p && ch is p.left) 230 { 231 ch = p; 232 p = p.parent; 233 } 234 return p; 235 } 236 237 /** 238 * Return the number of nodes in the subtree 239 **/ 240 int size () 241 { 242 auto c = 1; 243 if (left) 244 c += left.size; 245 if (right) 246 c += right.size; 247 return c; 248 } 249 250 251 /** 252 * Return node of current subtree containing value as value(), 253 * if it exists, else null. 254 * Uses Comparator cmp to find and to check equality. 255 **/ 256 257 Ref find (V value, Compare!(V) cmp) 258 { 259 auto t = (&this); 260 for (;;) 261 { 262 auto diff = cmp (value, t.value); 263 if (diff is 0) 264 return t; 265 else 266 if (diff < 0) 267 t = t.left; 268 else 269 t = t.right; 270 if (t is null) 271 break; 272 } 273 return null; 274 } 275 276 277 /** 278 * Return node of subtree matching "value" 279 * or, if none found, the one just after or before 280 * if it doesn't exist, return null 281 * Uses Comparator cmp to find and to check equality. 282 **/ 283 Ref findFirst (V value, Compare!(V) cmp, bool after = true) 284 { 285 auto t = (&this); 286 auto tLower = (&this); 287 auto tGreater = (&this); 288 289 for (;;) 290 { 291 auto diff = cmp (value, t.value); 292 if (diff is 0) 293 return t; 294 else 295 if (diff < 0) 296 { 297 tGreater = t; 298 t = t.left; 299 } 300 else 301 { 302 tLower = t; 303 t = t.right; 304 } 305 if (t is null) 306 break; 307 } 308 309 if (after) 310 { 311 if (cmp (value, tGreater.value) <= 0) 312 if (cmp (value, tGreater.value) < 0) 313 return tGreater; 314 } 315 else 316 { 317 if (cmp (value, tLower.value) >= 0) 318 if (cmp (value, tLower.value) > 0) 319 return tLower; 320 } 321 322 return null; 323 } 324 325 /** 326 * Return number of nodes of current subtree containing value. 327 * Uses Comparator cmp to find and to check equality. 328 **/ 329 int count (V value, Compare!(V) cmp) 330 { 331 auto c = 0; 332 auto t = (&this); 333 while (t) 334 { 335 int diff = cmp (value, t.value); 336 if (diff is 0) 337 { 338 ++c; 339 if (t.left is null) 340 t = t.right; 341 else 342 if (t.right is null) 343 t = t.left; 344 else 345 { 346 c += t.right.count (value, cmp); 347 t = t.left; 348 } 349 } 350 else 351 if (diff < 0) 352 t = t.left; 353 else 354 t = t.right; 355 } 356 return c; 357 } 358 359 static if (!is(typeof(A) == AttributeDummy)) 360 { 361 Ref findAttribute (A attribute, Compare!(A) cmp) 362 { 363 auto t = (&this); 364 365 while (t) 366 { 367 if (t.attribute == attribute) 368 return t; 369 else 370 if (t.right is null) 371 t = t.left; 372 else 373 if (t.left is null) 374 t = t.right; 375 else 376 { 377 auto p = t.left.findAttribute (attribute, cmp); 378 379 if (p !is null) 380 return p; 381 else 382 t = t.right; 383 } 384 } 385 return null; // not reached 386 } 387 388 int countAttribute (A attrib, Compare!(A) cmp) 389 { 390 int c = 0; 391 auto t = (&this); 392 393 while (t) 394 { 395 if (t.attribute == attribute) 396 ++c; 397 398 if (t.right is null) 399 t = t.left; 400 else 401 if (t.left is null) 402 t = t.right; 403 else 404 { 405 c += t.left.countAttribute (attribute, cmp); 406 t = t.right; 407 } 408 } 409 return c; 410 } 411 412 /** 413 * find and return a cell holding (key, element), or null if no such 414 **/ 415 Ref find (V value, A attribute, Compare!(V) cmp) 416 { 417 auto t = (&this); 418 419 for (;;) 420 { 421 int diff = cmp (value, t.value); 422 if (diff is 0 && t.attribute == attribute) 423 return t; 424 else 425 if (diff <= 0) 426 t = t.left; 427 else 428 t = t.right; 429 430 if (t is null) 431 break; 432 } 433 return null; 434 } 435 436 } 437 438 439 440 /** 441 * Return a new subtree containing each value of current subtree 442 **/ 443 444 Ref copyTree (scope Ref delegate() alloc) 445 { 446 auto t = dup (alloc); 447 448 if (left) 449 { 450 t.left = left.copyTree (alloc); 451 t.left.parent = t; 452 } 453 454 if (right) 455 { 456 t.right = right.copyTree (alloc); 457 t.right.parent = t; 458 } 459 460 return t; 461 } 462 463 464 /** 465 * There's no generic value insertion. Instead find the 466 * place you want to add a node and then invoke insertLeft 467 * or insertRight. 468 * <P> 469 * Insert Cell as the left child of current node, and then 470 * rebalance the tree it is in. 471 * @param Cell the Cell to add 472 * @param root, the root of the current tree 473 * Returns: the new root of the current tree. (Rebalancing 474 * can change the root!) 475 **/ 476 477 478 Ref insertLeft (Ref cell, Ref root) 479 { 480 left = cell; 481 cell.parent = (&this); 482 return cell.fixAfterInsertion (root); 483 } 484 485 /** 486 * Insert Cell as the right child of current node, and then 487 * rebalance the tree it is in. 488 * @param Cell the Cell to add 489 * @param root, the root of the current tree 490 * Returns: the new root of the current tree. (Rebalancing 491 * can change the root!) 492 **/ 493 494 Ref insertRight (Ref cell, Ref root) 495 { 496 right = cell; 497 cell.parent = (&this); 498 return cell.fixAfterInsertion (root); 499 } 500 501 502 /** 503 * Delete the current node, and then rebalance the tree it is in 504 * @param root the root of the current tree 505 * Returns: the new root of the current tree. (Rebalancing 506 * can change the root!) 507 **/ 508 509 510 Ref remove (Ref root) 511 { 512 // handle case where we are only node 513 if (left is null && right is null && parent is null) 514 return null; 515 516 // if strictly internal, swap places with a successor 517 if (left && right) 518 { 519 auto s = successor; 520 521 // To work nicely with arbitrary subclasses of Ref, we don't want to 522 // just copy successor's fields. since we don't know what 523 // they are. Instead we swap positions _in the tree. 524 root = swapPosition ((&this), s, root); 525 } 526 527 // Start fixup at replacement node (normally a child). 528 // But if no children, fake it by using self 529 530 if (left is null && right is null) 531 { 532 if (color is BLACK) 533 root = (&this).fixAfterDeletion (root); 534 535 // Unlink (Couldn't before since fixAfterDeletion needs parent ptr) 536 if (parent) 537 { 538 if ((&this) is parent.left) 539 parent.left = null; 540 else 541 if ((&this) is parent.right) 542 parent.right = null; 543 parent = null; 544 } 545 } 546 else 547 { 548 auto replacement = left; 549 if (replacement is null) 550 replacement = right; 551 552 // link replacement to parent 553 replacement.parent = parent; 554 555 if (parent is null) 556 root = replacement; 557 else 558 if ((&this) is parent.left) 559 parent.left = replacement; 560 else 561 parent.right = replacement; 562 563 left = null; 564 right = null; 565 parent = null; 566 567 // fix replacement 568 if (color is BLACK) 569 root = replacement.fixAfterDeletion (root); 570 } 571 return root; 572 } 573 574 /** 575 * Swap the linkages of two nodes in a tree. 576 * Return new root, in case it changed. 577 **/ 578 579 static Ref swapPosition (Ref x, Ref y, Ref root) 580 { 581 /* Too messy. TODO: find sequence of assigments that are always OK */ 582 583 auto px = x.parent; 584 bool xpl = px !is null && x is px.left; 585 auto lx = x.left; 586 auto rx = x.right; 587 588 auto py = y.parent; 589 bool ypl = py !is null && y is py.left; 590 auto ly = y.left; 591 auto ry = y.right; 592 593 if (x is py) 594 { 595 y.parent = px; 596 if (px !is null) 597 { 598 if (xpl) 599 px.left = y; 600 else 601 px.right = y; 602 } 603 604 x.parent = y; 605 if (ypl) 606 { 607 y.left = x; 608 y.right = rx; 609 if (rx !is null) 610 rx.parent = y; 611 } 612 else 613 { 614 y.right = x; 615 y.left = lx; 616 if (lx !is null) 617 lx.parent = y; 618 } 619 620 x.left = ly; 621 if (ly !is null) 622 ly.parent = x; 623 624 x.right = ry; 625 if (ry !is null) 626 ry.parent = x; 627 } 628 else 629 if (y is px) 630 { 631 x.parent = py; 632 if (py !is null) 633 { 634 if (ypl) 635 py.left = x; 636 else 637 py.right = x; 638 } 639 640 y.parent = x; 641 if (xpl) 642 { 643 x.left = y; 644 x.right = ry; 645 if (ry !is null) 646 ry.parent = x; 647 } 648 else 649 { 650 x.right = y; 651 x.left = ly; 652 if (ly !is null) 653 ly.parent = x; 654 } 655 656 y.left = lx; 657 if (lx !is null) 658 lx.parent = y; 659 660 y.right = rx; 661 if (rx !is null) 662 rx.parent = y; 663 } 664 else 665 { 666 x.parent = py; 667 if (py !is null) 668 { 669 if (ypl) 670 py.left = x; 671 else 672 py.right = x; 673 } 674 675 x.left = ly; 676 if (ly !is null) 677 ly.parent = x; 678 679 x.right = ry; 680 if (ry !is null) 681 ry.parent = x; 682 683 y.parent = px; 684 if (px !is null) 685 { 686 if (xpl) 687 px.left = y; 688 else 689 px.right = y; 690 } 691 692 y.left = lx; 693 if (lx !is null) 694 lx.parent = y; 695 696 y.right = rx; 697 if (rx !is null) 698 rx.parent = y; 699 } 700 701 bool c = x.color; 702 x.color = y.color; 703 y.color = c; 704 705 if (root is x) 706 root = y; 707 else 708 if (root is y) 709 root = x; 710 return root; 711 } 712 713 714 715 /** 716 * Return color of node p, or BLACK if p is null 717 * (In the CLR version, they use 718 * a special dummy `nil' node for such purposes, but that doesn't 719 * work well here, since it could lead to creating one such special 720 * node per real node.) 721 * 722 **/ 723 724 static bool colorOf (Ref p) 725 { 726 return (p is null) ? BLACK : p.color; 727 } 728 729 /** 730 * return parent of node p, or null if p is null 731 **/ 732 static Ref parentOf (Ref p) 733 { 734 return (p is null) ? null : p.parent; 735 } 736 737 /** 738 * Set the color of node p, or do nothing if p is null 739 **/ 740 741 static void setColor (Ref p, bool c) 742 { 743 if (p !is null) 744 p.color = c; 745 } 746 747 /** 748 * return left child of node p, or null if p is null 749 **/ 750 751 static Ref leftOf (Ref p) 752 { 753 return (p is null) ? null : p.left; 754 } 755 756 /** 757 * return right child of node p, or null if p is null 758 **/ 759 760 static Ref rightOf (Ref p) 761 { 762 return (p is null) ? null : p.right; 763 } 764 765 766 /** From CLR **/ 767 package Ref rotateLeft (Ref root) 768 { 769 auto r = right; 770 right = r.left; 771 772 if (r.left) 773 r.left.parent = (&this); 774 775 r.parent = parent; 776 if (parent is null) 777 root = r; 778 else 779 if (parent.left is (&this)) 780 parent.left = r; 781 else 782 parent.right = r; 783 784 r.left = (&this); 785 parent = r; 786 return root; 787 } 788 789 /** From CLR **/ 790 package Ref rotateRight (Ref root) 791 { 792 auto l = left; 793 left = l.right; 794 795 if (l.right !is null) 796 l.right.parent = (&this); 797 798 l.parent = parent; 799 if (parent is null) 800 root = l; 801 else 802 if (parent.right is (&this)) 803 parent.right = l; 804 else 805 parent.left = l; 806 807 l.right = (&this); 808 parent = l; 809 return root; 810 } 811 812 813 /** From CLR **/ 814 package Ref fixAfterInsertion (Ref root) 815 { 816 color = RED; 817 auto x = (&this); 818 819 while (x && x !is root && x.parent.color is RED) 820 { 821 if (parentOf(x) is leftOf(parentOf(parentOf(x)))) 822 { 823 auto y = rightOf(parentOf(parentOf(x))); 824 if (colorOf(y) is RED) 825 { 826 setColor(parentOf(x), BLACK); 827 setColor(y, BLACK); 828 setColor(parentOf(parentOf(x)), RED); 829 x = parentOf(parentOf(x)); 830 } 831 else 832 { 833 if (x is rightOf(parentOf(x))) 834 { 835 x = parentOf(x); 836 root = x.rotateLeft(root); 837 } 838 839 setColor(parentOf(x), BLACK); 840 setColor(parentOf(parentOf(x)), RED); 841 if (parentOf(parentOf(x)) !is null) 842 root = parentOf(parentOf(x)).rotateRight(root); 843 } 844 } 845 else 846 { 847 auto y = leftOf(parentOf(parentOf(x))); 848 if (colorOf(y) is RED) 849 { 850 setColor(parentOf(x), BLACK); 851 setColor(y, BLACK); 852 setColor(parentOf(parentOf(x)), RED); 853 x = parentOf(parentOf(x)); 854 } 855 else 856 { 857 if (x is leftOf(parentOf(x))) 858 { 859 x = parentOf(x); 860 root = x.rotateRight(root); 861 } 862 863 setColor(parentOf(x), BLACK); 864 setColor(parentOf(parentOf(x)), RED); 865 if (parentOf(parentOf(x)) !is null) 866 root = parentOf(parentOf(x)).rotateLeft(root); 867 } 868 } 869 } 870 root.color = BLACK; 871 return root; 872 } 873 874 875 876 /** From CLR **/ 877 package Ref fixAfterDeletion(Ref root) 878 { 879 auto x = (&this); 880 while (x !is root && colorOf(x) is BLACK) 881 { 882 if (x is leftOf(parentOf(x))) 883 { 884 auto sib = rightOf(parentOf(x)); 885 if (colorOf(sib) is RED) 886 { 887 setColor(sib, BLACK); 888 setColor(parentOf(x), RED); 889 root = parentOf(x).rotateLeft(root); 890 sib = rightOf(parentOf(x)); 891 } 892 if (colorOf(leftOf(sib)) is BLACK && colorOf(rightOf(sib)) is BLACK) 893 { 894 setColor(sib, RED); 895 x = parentOf(x); 896 } 897 else 898 { 899 if (colorOf(rightOf(sib)) is BLACK) 900 { 901 setColor(leftOf(sib), BLACK); 902 setColor(sib, RED); 903 root = sib.rotateRight(root); 904 sib = rightOf(parentOf(x)); 905 } 906 907 setColor(sib, colorOf(parentOf(x))); 908 setColor(parentOf(x), BLACK); 909 setColor(rightOf(sib), BLACK); 910 root = parentOf(x).rotateLeft(root); 911 x = root; 912 } 913 } 914 else 915 { 916 auto sib = leftOf(parentOf(x)); 917 if (colorOf(sib) is RED) 918 { 919 setColor(sib, BLACK); 920 setColor(parentOf(x), RED); 921 root = parentOf(x).rotateRight(root); 922 sib = leftOf(parentOf(x)); 923 } 924 925 if (colorOf(rightOf(sib)) is BLACK && colorOf(leftOf(sib)) is BLACK) 926 { 927 setColor(sib, RED); 928 x = parentOf(x); 929 } 930 else 931 { 932 if (colorOf(leftOf(sib)) is BLACK) 933 { 934 setColor(rightOf(sib), BLACK); 935 setColor(sib, RED); 936 root = sib.rotateLeft(root); 937 sib = leftOf(parentOf(x)); 938 } 939 940 setColor(sib, colorOf(parentOf(x))); 941 setColor(parentOf(x), BLACK); 942 setColor(leftOf(sib), BLACK); 943 root = parentOf(x).rotateRight(root); 944 x = root; 945 } 946 } 947 } 948 949 setColor(x, BLACK); 950 return root; 951 } 952 }