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