2 * Copyright (C) 2000 Red Hat, Inc., Jonathan Blandford <jrb@redhat.com>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 #include "gtkrbtree.h"
24 static GtkRBNode * _gtk_rbnode_new (GtkRBTree *tree,
26 static void _gtk_rbnode_free (GtkRBNode *node);
27 static void _gtk_rbnode_rotate_left (GtkRBTree *tree,
29 static void _gtk_rbnode_rotate_right (GtkRBTree *tree,
31 static void _gtk_rbtree_insert_fixup (GtkRBTree *tree,
33 static void _gtk_rbtree_remove_node_fixup (GtkRBTree *tree,
35 static inline void _fixup_validation (GtkRBTree *tree,
37 static inline void _fixup_total_count (GtkRBTree *tree,
43 _gtk_rbnode_new (GtkRBTree *tree,
46 GtkRBNode *node = g_slice_new (GtkRBNode);
48 node->left = tree->nil;
49 node->right = tree->nil;
50 node->parent = tree->nil;
51 node->flags = GTK_RBNODE_RED;
52 node->total_count = 1;
54 node->children = NULL;
55 node->offset = height;
60 _gtk_rbnode_free (GtkRBNode *node)
62 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
64 node->left = (gpointer) 0xdeadbeef;
65 node->right = (gpointer) 0xdeadbeef;
66 node->parent = (gpointer) 0xdeadbeef;
67 node->total_count = 56789;
72 g_slice_free (GtkRBNode, node);
76 _gtk_rbnode_rotate_left (GtkRBTree *tree,
79 gint node_height, right_height;
80 GtkRBNode *right = node->right;
82 g_return_if_fail (node != tree->nil);
84 node_height = node->offset -
85 (node->left?node->left->offset:0) -
86 (node->right?node->right->offset:0) -
87 (node->children?node->children->root->offset:0);
88 right_height = right->offset -
89 (right->left?right->left->offset:0) -
90 (right->right?right->right->offset:0) -
91 (right->children?right->children->root->offset:0);
92 node->right = right->left;
93 if (right->left != tree->nil)
94 right->left->parent = node;
96 if (right != tree->nil)
97 right->parent = node->parent;
98 if (node->parent != tree->nil)
100 if (node == node->parent->left)
101 node->parent->left = right;
103 node->parent->right = right;
109 if (node != tree->nil)
110 node->parent = right;
112 node->count = 1 + (node->left?node->left->count:0) +
113 (node->right?node->right->count:0);
114 right->count = 1 + (right->left?right->left->count:0) +
115 (right->right?right->right->count:0);
117 node->offset = node_height +
118 (node->left?node->left->offset:0) +
119 (node->right?node->right->offset:0) +
120 (node->children?node->children->root->offset:0);
121 right->offset = right_height +
122 (right->left?right->left->offset:0) +
123 (right->right?right->right->offset:0) +
124 (right->children?right->children->root->offset:0);
126 _fixup_validation (tree, node);
127 _fixup_validation (tree, right);
128 _fixup_total_count (tree, node);
129 _fixup_total_count (tree, right);
133 _gtk_rbnode_rotate_right (GtkRBTree *tree,
136 gint node_height, left_height;
137 GtkRBNode *left = node->left;
139 g_return_if_fail (node != tree->nil);
141 node_height = node->offset -
142 (node->left?node->left->offset:0) -
143 (node->right?node->right->offset:0) -
144 (node->children?node->children->root->offset:0);
145 left_height = left->offset -
146 (left->left?left->left->offset:0) -
147 (left->right?left->right->offset:0) -
148 (left->children?left->children->root->offset:0);
150 node->left = left->right;
151 if (left->right != tree->nil)
152 left->right->parent = node;
154 if (left != tree->nil)
155 left->parent = node->parent;
156 if (node->parent != tree->nil)
158 if (node == node->parent->right)
159 node->parent->right = left;
161 node->parent->left = left;
168 /* link node and left */
170 if (node != tree->nil)
173 node->count = 1 + (node->left?node->left->count:0) +
174 (node->right?node->right->count:0);
175 left->count = 1 + (left->left?left->left->count:0) +
176 (left->right?left->right->count:0);
178 node->offset = node_height +
179 (node->left?node->left->offset:0) +
180 (node->right?node->right->offset:0) +
181 (node->children?node->children->root->offset:0);
182 left->offset = left_height +
183 (left->left?left->left->offset:0) +
184 (left->right?left->right->offset:0) +
185 (left->children?left->children->root->offset:0);
187 _fixup_validation (tree, node);
188 _fixup_validation (tree, left);
189 _fixup_total_count (tree, node);
190 _fixup_total_count (tree, left);
194 _gtk_rbtree_insert_fixup (GtkRBTree *tree,
198 /* check Red-Black properties */
199 while (node != tree->root && GTK_RBNODE_GET_COLOR (node->parent) == GTK_RBNODE_RED)
201 /* we have a violation */
202 if (node->parent == node->parent->parent->left)
204 GtkRBNode *y = node->parent->parent->right;
205 if (GTK_RBNODE_GET_COLOR (y) == GTK_RBNODE_RED)
207 /* uncle is GTK_RBNODE_RED */
208 GTK_RBNODE_SET_COLOR (node->parent, GTK_RBNODE_BLACK);
209 GTK_RBNODE_SET_COLOR (y, GTK_RBNODE_BLACK);
210 GTK_RBNODE_SET_COLOR (node->parent->parent, GTK_RBNODE_RED);
211 node = node->parent->parent;
215 /* uncle is GTK_RBNODE_BLACK */
216 if (node == node->parent->right)
218 /* make node a left child */
220 _gtk_rbnode_rotate_left (tree, node);
223 /* recolor and rotate */
224 GTK_RBNODE_SET_COLOR (node->parent, GTK_RBNODE_BLACK);
225 GTK_RBNODE_SET_COLOR (node->parent->parent, GTK_RBNODE_RED);
226 _gtk_rbnode_rotate_right(tree, node->parent->parent);
231 /* mirror image of above code */
232 GtkRBNode *y = node->parent->parent->left;
233 if (GTK_RBNODE_GET_COLOR (y) == GTK_RBNODE_RED)
235 /* uncle is GTK_RBNODE_RED */
236 GTK_RBNODE_SET_COLOR (node->parent, GTK_RBNODE_BLACK);
237 GTK_RBNODE_SET_COLOR (y, GTK_RBNODE_BLACK);
238 GTK_RBNODE_SET_COLOR (node->parent->parent, GTK_RBNODE_RED);
239 node = node->parent->parent;
243 /* uncle is GTK_RBNODE_BLACK */
244 if (node == node->parent->left)
247 _gtk_rbnode_rotate_right (tree, node);
249 GTK_RBNODE_SET_COLOR (node->parent, GTK_RBNODE_BLACK);
250 GTK_RBNODE_SET_COLOR (node->parent->parent, GTK_RBNODE_RED);
251 _gtk_rbnode_rotate_left (tree, node->parent->parent);
255 GTK_RBNODE_SET_COLOR (tree->root, GTK_RBNODE_BLACK);
259 _gtk_rbtree_remove_node_fixup (GtkRBTree *tree,
262 while (node != tree->root && GTK_RBNODE_GET_COLOR (node) == GTK_RBNODE_BLACK)
264 if (node == node->parent->left)
266 GtkRBNode *w = node->parent->right;
267 if (GTK_RBNODE_GET_COLOR (w) == GTK_RBNODE_RED)
269 GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_BLACK);
270 GTK_RBNODE_SET_COLOR (node->parent, GTK_RBNODE_RED);
271 _gtk_rbnode_rotate_left (tree, node->parent);
272 w = node->parent->right;
274 if (GTK_RBNODE_GET_COLOR (w->left) == GTK_RBNODE_BLACK && GTK_RBNODE_GET_COLOR (w->right) == GTK_RBNODE_BLACK)
276 GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_RED);
281 if (GTK_RBNODE_GET_COLOR (w->right) == GTK_RBNODE_BLACK)
283 GTK_RBNODE_SET_COLOR (w->left, GTK_RBNODE_BLACK);
284 GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_RED);
285 _gtk_rbnode_rotate_right (tree, w);
286 w = node->parent->right;
288 GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_GET_COLOR (node->parent));
289 GTK_RBNODE_SET_COLOR (node->parent, GTK_RBNODE_BLACK);
290 GTK_RBNODE_SET_COLOR (w->right, GTK_RBNODE_BLACK);
291 _gtk_rbnode_rotate_left (tree, node->parent);
297 GtkRBNode *w = node->parent->left;
298 if (GTK_RBNODE_GET_COLOR (w) == GTK_RBNODE_RED)
300 GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_BLACK);
301 GTK_RBNODE_SET_COLOR (node->parent, GTK_RBNODE_RED);
302 _gtk_rbnode_rotate_right (tree, node->parent);
303 w = node->parent->left;
305 if (GTK_RBNODE_GET_COLOR (w->right) == GTK_RBNODE_BLACK && GTK_RBNODE_GET_COLOR (w->left) == GTK_RBNODE_BLACK)
307 GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_RED);
312 if (GTK_RBNODE_GET_COLOR (w->left) == GTK_RBNODE_BLACK)
314 GTK_RBNODE_SET_COLOR (w->right, GTK_RBNODE_BLACK);
315 GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_RED);
316 _gtk_rbnode_rotate_left (tree, w);
317 w = node->parent->left;
319 GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_GET_COLOR (node->parent));
320 GTK_RBNODE_SET_COLOR (node->parent, GTK_RBNODE_BLACK);
321 GTK_RBNODE_SET_COLOR (w->left, GTK_RBNODE_BLACK);
322 _gtk_rbnode_rotate_right (tree, node->parent);
327 GTK_RBNODE_SET_COLOR (node, GTK_RBNODE_BLACK);
331 _gtk_rbtree_new (void)
335 retval = g_new (GtkRBTree, 1);
336 retval->parent_tree = NULL;
337 retval->parent_node = NULL;
339 retval->nil = g_slice_new (GtkRBNode);
340 retval->nil->left = NULL;
341 retval->nil->right = NULL;
342 retval->nil->parent = NULL;
343 retval->nil->flags = GTK_RBNODE_BLACK;
344 retval->nil->count = 0;
345 retval->nil->offset = 0;
346 retval->nil->total_count = 0;
348 retval->root = retval->nil;
353 _gtk_rbtree_free_helper (GtkRBTree *tree,
358 _gtk_rbtree_free (node->children);
360 _gtk_rbnode_free (node);
364 _gtk_rbtree_free (GtkRBTree *tree)
366 _gtk_rbtree_traverse (tree,
369 _gtk_rbtree_free_helper,
372 if (tree->parent_node &&
373 tree->parent_node->children == tree)
374 tree->parent_node->children = NULL;
375 _gtk_rbnode_free (tree->nil);
380 _gtk_rbtree_remove (GtkRBTree *tree)
385 gint height = tree->root->offset;
386 guint total_count = tree->root->total_count;
388 #ifdef G_ENABLE_DEBUG
389 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
390 _gtk_rbtree_test (G_STRLOC, tree);
393 tmp_tree = tree->parent_tree;
394 tmp_node = tree->parent_node;
396 /* ugly hack to make _fixup_validation work in the first iteration of the
398 GTK_RBNODE_UNSET_FLAG (tree->root, GTK_RBNODE_DESCENDANTS_INVALID);
400 while (tmp_tree && tmp_node && tmp_node != tmp_tree->nil)
402 _fixup_validation (tmp_tree, tmp_node);
403 tmp_node->offset -= height;
404 tmp_node->total_count -= total_count;
406 tmp_node = tmp_node->parent;
407 if (tmp_node == tmp_tree->nil)
409 tmp_node = tmp_tree->parent_node;
410 tmp_tree = tmp_tree->parent_tree;
414 tmp_tree = tree->parent_tree;
415 tmp_node = tree->parent_node;
416 _gtk_rbtree_free (tree);
418 #ifdef G_ENABLE_DEBUG
419 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
420 _gtk_rbtree_test (G_STRLOC, tmp_tree);
426 _gtk_rbtree_insert_after (GtkRBTree *tree,
432 gboolean right = TRUE;
436 #ifdef G_ENABLE_DEBUG
437 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
439 g_print ("\n\n_gtk_rbtree_insert_after: %p\n", current);
440 _gtk_rbtree_debug_spew (tree);
441 _gtk_rbtree_test (G_STRLOC, tree);
443 #endif /* G_ENABLE_DEBUG */
445 if (current != NULL && current->right != tree->nil)
447 current = current->right;
448 while (current->left != tree->nil)
449 current = current->left;
453 node = _gtk_rbnode_new (tree, height);
454 node->parent = (current?current:tree->nil);
456 /* insert node in tree */
460 current->right = node;
462 current->left = node;
463 tmp_node = node->parent;
469 tmp_node = tree->parent_node;
470 tmp_tree = tree->parent_tree;
473 while (tmp_tree && tmp_node && tmp_node != tmp_tree->nil)
475 /* We only want to propagate the count if we are in the tree we
477 if (tmp_tree == tree)
480 tmp_node->total_count += 1;
481 tmp_node->offset += height;
482 tmp_node = tmp_node->parent;
483 if (tmp_node == tmp_tree->nil)
485 tmp_node = tmp_tree->parent_node;
486 tmp_tree = tmp_tree->parent_tree;
491 _gtk_rbtree_node_mark_valid (tree, node);
493 _gtk_rbtree_node_mark_invalid (tree, node);
495 _gtk_rbtree_insert_fixup (tree, node);
497 #ifdef G_ENABLE_DEBUG
498 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
500 g_print ("_gtk_rbtree_insert_after finished...\n");
501 _gtk_rbtree_debug_spew (tree);
503 _gtk_rbtree_test (G_STRLOC, tree);
505 #endif /* G_ENABLE_DEBUG */
511 _gtk_rbtree_insert_before (GtkRBTree *tree,
517 gboolean left = TRUE;
521 #ifdef G_ENABLE_DEBUG
522 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
524 g_print ("\n\n_gtk_rbtree_insert_before: %p\n", current);
525 _gtk_rbtree_debug_spew (tree);
526 _gtk_rbtree_test (G_STRLOC, tree);
528 #endif /* G_ENABLE_DEBUG */
530 if (current != NULL && current->left != tree->nil)
532 current = current->left;
533 while (current->right != tree->nil)
534 current = current->right;
539 node = _gtk_rbnode_new (tree, height);
540 node->parent = (current?current:tree->nil);
542 /* insert node in tree */
546 current->left = node;
548 current->right = node;
549 tmp_node = node->parent;
555 tmp_node = tree->parent_node;
556 tmp_tree = tree->parent_tree;
559 while (tmp_tree && tmp_node && tmp_node != tmp_tree->nil)
561 /* We only want to propagate the count if we are in the tree we
563 if (tmp_tree == tree)
566 tmp_node->total_count += 1;
567 tmp_node->offset += height;
568 tmp_node = tmp_node->parent;
569 if (tmp_node == tmp_tree->nil)
571 tmp_node = tmp_tree->parent_node;
572 tmp_tree = tmp_tree->parent_tree;
577 _gtk_rbtree_node_mark_valid (tree, node);
579 _gtk_rbtree_node_mark_invalid (tree, node);
581 _gtk_rbtree_insert_fixup (tree, node);
583 #ifdef G_ENABLE_DEBUG
584 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
586 g_print ("_gtk_rbtree_insert_before finished...\n");
587 _gtk_rbtree_debug_spew (tree);
589 _gtk_rbtree_test (G_STRLOC, tree);
591 #endif /* G_ENABLE_DEBUG */
597 _gtk_rbtree_find_count (GtkRBTree *tree,
603 while (node != tree->nil && (node->left->count + 1 != count))
605 if (node->left->count >= count)
609 count -= (node->left->count + 1);
613 if (node == tree->nil)
619 _gtk_rbtree_node_set_height (GtkRBTree *tree,
623 gint diff = height - GTK_RBNODE_GET_HEIGHT (node);
624 GtkRBNode *tmp_node = node;
625 GtkRBTree *tmp_tree = tree;
630 while (tmp_tree && tmp_node && tmp_node != tmp_tree->nil)
632 tmp_node->offset += diff;
633 tmp_node = tmp_node->parent;
634 if (tmp_node == tmp_tree->nil)
636 tmp_node = tmp_tree->parent_node;
637 tmp_tree = tmp_tree->parent_tree;
640 #ifdef G_ENABLE_DEBUG
641 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
642 _gtk_rbtree_test (G_STRLOC, tree);
647 _gtk_rbtree_node_mark_invalid (GtkRBTree *tree,
650 if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID))
653 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_INVALID);
656 if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_DESCENDANTS_INVALID))
658 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
660 if (node == tree->nil)
662 node = tree->parent_node;
663 tree = tree->parent_tree;
670 /* Draconian version. */
672 _gtk_rbtree_node_mark_invalid (GtkRBTree *tree,
675 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_INVALID);
678 _fixup_validation (tree, node);
680 if (node == tree->nil)
682 node = tree->parent_node;
683 tree = tree->parent_tree;
691 _gtk_rbtree_node_mark_valid (GtkRBTree *tree,
694 if ((!GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID)) &&
695 (!GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID)))
698 GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_INVALID);
699 GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_COLUMN_INVALID);
703 if ((GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID)) ||
704 (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID)) ||
705 (node->children && GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID)) ||
706 (node->left != tree->nil && GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID)) ||
707 (node->right != tree->nil && GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID)))
710 GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
712 if (node == tree->nil)
714 node = tree->parent_node;
715 tree = tree->parent_tree;
722 /* Draconian version */
724 _gtk_rbtree_node_mark_valid (GtkRBTree *tree,
727 GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_INVALID);
728 GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_COLUMN_INVALID);
732 _fixup_validation (tree, node);
734 if (node == tree->nil)
736 node = tree->parent_node;
737 tree = tree->parent_tree;
743 /* Assume tree is the root node as it doesn't set DESCENDANTS_INVALID above.
746 _gtk_rbtree_column_invalid (GtkRBTree *tree)
755 while (node->left != tree->nil)
760 if (! (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID)))
761 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_COLUMN_INVALID);
762 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
765 _gtk_rbtree_column_invalid (node->children);
767 while ((node = _gtk_rbtree_next (tree, node)) != NULL);
771 _gtk_rbtree_mark_invalid (GtkRBTree *tree)
780 while (node->left != tree->nil)
785 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_INVALID);
786 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
789 _gtk_rbtree_mark_invalid (node->children);
791 while ((node = _gtk_rbtree_next (tree, node)) != NULL);
795 _gtk_rbtree_set_fixed_height (GtkRBTree *tree,
807 while (node->left != tree->nil)
812 if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID))
814 _gtk_rbtree_node_set_height (tree, node, height);
816 _gtk_rbtree_node_mark_valid (tree, node);
820 _gtk_rbtree_set_fixed_height (node->children, height, mark_valid);
822 while ((node = _gtk_rbtree_next (tree, node)) != NULL);
825 typedef struct _GtkRBReorder
836 gtk_rbtree_reorder_sort_func (gconstpointer a,
839 return ((GtkRBReorder *) a)->order - ((GtkRBReorder *) b)->order;
843 gtk_rbtree_reorder_invert_func (gconstpointer a,
846 return ((GtkRBReorder *) a)->invert_order - ((GtkRBReorder *) b)->invert_order;
850 gtk_rbtree_reorder_fixup (GtkRBTree *tree,
853 if (node == tree->nil)
856 node->total_count = 1;
858 if (node->left != tree->nil)
860 gtk_rbtree_reorder_fixup (tree, node->left);
861 node->offset += node->left->offset;
862 node->total_count += node->left->total_count;
864 if (node->right != tree->nil)
866 gtk_rbtree_reorder_fixup (tree, node->right);
867 node->offset += node->right->offset;
868 node->total_count += node->right->total_count;
873 node->offset += node->children->root->offset;
874 node->total_count += node->children->root->total_count;
877 if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID) ||
878 (node->right != tree->nil && GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID)) ||
879 (node->left != tree->nil && GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID)) ||
880 (node->children && GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID)))
881 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
883 GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
886 /* It basically pulls everything out of the tree, rearranges it, and puts it
887 * back together. Our strategy is to keep the old RBTree intact, and just
888 * rearrange the contents. When that is done, we go through and update the
889 * heights. There is probably a more elegant way to write this function. If
890 * anyone wants to spend the time writing it, patches will be accepted.
893 _gtk_rbtree_reorder (GtkRBTree *tree,
897 GtkRBReorder reorder = { NULL };
902 g_return_if_fail (tree != NULL);
903 g_return_if_fail (length > 0);
904 g_return_if_fail (tree->root->count == length);
906 /* Sort the trees values in the new tree. */
907 array = g_array_sized_new (FALSE, FALSE, sizeof (GtkRBReorder), length);
908 for (i = 0; i < length; i++)
910 reorder.order = new_order[i];
911 reorder.invert_order = i;
912 g_array_append_val (array, reorder);
915 g_array_sort(array, gtk_rbtree_reorder_sort_func);
919 while (node && node->left != tree->nil)
922 for (i = 0; i < length; i++)
924 g_assert (node != tree->nil);
925 g_array_index (array, GtkRBReorder, i).children = node->children;
926 g_array_index (array, GtkRBReorder, i).flags = GTK_RBNODE_NON_COLORS & node->flags;
927 g_array_index (array, GtkRBReorder, i).height = GTK_RBNODE_GET_HEIGHT (node);
929 node = _gtk_rbtree_next (tree, node);
932 g_array_sort (array, gtk_rbtree_reorder_invert_func);
936 while (node && node->left != tree->nil)
939 /* Go through the tree and change the values to the new ones. */
940 for (i = 0; i < length; i++)
942 reorder = g_array_index (array, GtkRBReorder, i);
943 node->children = reorder.children;
945 node->children->parent_node = node;
946 node->flags = GTK_RBNODE_GET_COLOR (node) | reorder.flags;
947 /* We temporarily set the height to this. */
948 node->offset = reorder.height;
949 node = _gtk_rbtree_next (tree, node);
951 gtk_rbtree_reorder_fixup (tree, tree->root);
953 g_array_free (array, TRUE);
958 _gtk_rbtree_node_find_offset (GtkRBTree *tree,
965 g_assert (node->left);
967 retval = node->left->offset;
969 while (tree && node && node != tree->nil)
974 /* Add left branch, plus children, iff we came from the right */
975 if (node->right == last)
976 retval += node->offset - node->right->offset;
978 if (node == tree->nil)
980 node = tree->parent_node;
981 tree = tree->parent_tree;
983 /* Add the parent node, plus the left branch. */
985 retval += node->left->offset + GTK_RBNODE_GET_HEIGHT (node);
992 _gtk_rbtree_node_get_index (GtkRBTree *tree,
999 g_assert (node->left);
1001 retval = node->left->total_count;
1003 while (tree && node && node != tree->nil)
1006 node = node->parent;
1008 /* Add left branch, plus children, iff we came from the right */
1009 if (node->right == last)
1010 retval += node->total_count - node->right->total_count;
1012 if (node == tree->nil)
1014 node = tree->parent_node;
1015 tree = tree->parent_tree;
1017 /* Add the parent node, plus the left branch. */
1019 retval += node->left->total_count + 1; /* 1 == GTK_RBNODE_GET_PARITY() */
1027 _gtk_rbtree_real_find_offset (GtkRBTree *tree,
1029 GtkRBTree **new_tree,
1030 GtkRBNode **new_node)
1032 GtkRBNode *tmp_node;
1045 tmp_node = tree->root;
1046 while (tmp_node != tree->nil &&
1047 (tmp_node->left->offset > height ||
1048 (tmp_node->offset - tmp_node->right->offset) < height))
1050 if (tmp_node->left->offset > height)
1051 tmp_node = tmp_node->left;
1054 height -= (tmp_node->offset - tmp_node->right->offset);
1055 tmp_node = tmp_node->right;
1058 if (tmp_node == tree->nil)
1064 if (tmp_node->children)
1066 if ((tmp_node->offset -
1067 tmp_node->right->offset -
1068 tmp_node->children->root->offset) > height)
1071 *new_node = tmp_node;
1072 return (height - tmp_node->left->offset);
1074 return _gtk_rbtree_real_find_offset (tmp_node->children,
1075 height - tmp_node->left->offset -
1077 tmp_node->left->offset -
1078 tmp_node->right->offset -
1079 tmp_node->children->root->offset),
1084 *new_node = tmp_node;
1085 return (height - tmp_node->left->offset);
1089 _gtk_rbtree_find_offset (GtkRBTree *tree,
1091 GtkRBTree **new_tree,
1092 GtkRBNode **new_node)
1097 (height >= tree->root->offset))
1104 return _gtk_rbtree_real_find_offset (tree, height, new_tree, new_node);
1108 _gtk_rbtree_find_index (GtkRBTree *tree,
1110 GtkRBTree **new_tree,
1111 GtkRBNode **new_node)
1113 GtkRBNode *tmp_node;
1117 tmp_node = tree->root;
1118 while (tmp_node != tree->nil)
1120 if (tmp_node->left->total_count > index)
1122 tmp_node = tmp_node->left;
1124 else if (tmp_node->total_count - tmp_node->right->total_count <= index)
1126 index -= tmp_node->total_count - tmp_node->right->total_count;
1127 tmp_node = tmp_node->right;
1131 index -= tmp_node->left->total_count;
1135 if (tmp_node == tree->nil)
1144 g_assert (tmp_node->children);
1146 return _gtk_rbtree_find_index (tmp_node->children,
1153 *new_node = tmp_node;
1158 _gtk_rbtree_remove_node (GtkRBTree *tree,
1162 GtkRBTree *tmp_tree;
1163 GtkRBNode *tmp_node;
1166 g_return_if_fail (tree != NULL);
1167 g_return_if_fail (node != NULL);
1170 #ifdef G_ENABLE_DEBUG
1171 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
1173 g_print ("\n\n_gtk_rbtree_remove_node: %p\n", node);
1174 _gtk_rbtree_debug_spew (tree);
1175 _gtk_rbtree_test (G_STRLOC, tree);
1177 #endif /* G_ENABLE_DEBUG */
1179 /* make sure we're deleting a node that's actually in the tree */
1180 for (x = node; x->parent != tree->nil; x = x->parent)
1182 g_return_if_fail (x == tree->root);
1184 #ifdef G_ENABLE_DEBUG
1185 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
1186 _gtk_rbtree_test (G_STRLOC, tree);
1189 if (node->left == tree->nil || node->right == tree->nil)
1197 while (y->left != tree->nil)
1201 /* adjust count only beneath tree */
1202 for (x = y; x != tree->nil; x = x->parent)
1207 /* offsets and total count adjust all the way up through parent trees */
1208 y_height = GTK_RBNODE_GET_HEIGHT (y);
1212 while (tmp_tree && tmp_node && tmp_node != tmp_tree->nil)
1214 tmp_node->offset -= (y_height + (y->children?y->children->root->offset:0));
1215 _fixup_validation (tmp_tree, tmp_node);
1216 _fixup_total_count (tmp_tree, tmp_node);
1217 tmp_node = tmp_node->parent;
1218 if (tmp_node == tmp_tree->nil)
1220 tmp_node = tmp_tree->parent_node;
1221 tmp_tree = tmp_tree->parent_tree;
1225 /* x is y's only child, or nil */
1226 if (y->left != tree->nil)
1231 /* remove y from the parent chain */
1232 x->parent = y->parent;
1233 if (y->parent != tree->nil)
1235 if (y == y->parent->left)
1236 y->parent->left = x;
1238 y->parent->right = x;
1245 /* We need to clean up the validity of the tree.
1252 /* We skip the first time, iff x is nil */
1253 if (tmp_node != tmp_tree->nil)
1255 _fixup_validation (tmp_tree, tmp_node);
1256 _fixup_total_count (tmp_tree, tmp_node);
1258 tmp_node = tmp_node->parent;
1259 if (tmp_node == tmp_tree->nil)
1261 tmp_node = tmp_tree->parent_node;
1262 tmp_tree = tmp_tree->parent_tree;
1265 while (tmp_tree != NULL);
1271 /* Copy the node over */
1272 if (GTK_RBNODE_GET_COLOR (node) == GTK_RBNODE_BLACK)
1273 node->flags = ((y->flags & (GTK_RBNODE_NON_COLORS)) | GTK_RBNODE_BLACK);
1275 node->flags = ((y->flags & (GTK_RBNODE_NON_COLORS)) | GTK_RBNODE_RED);
1276 node->children = y->children;
1279 node->children = y->children;
1280 node->children->parent_node = node;
1284 node->children = NULL;
1286 _fixup_validation (tree, node);
1287 _fixup_total_count (tree, node);
1288 /* We want to see how different our height is from the previous node.
1289 * To do this, we compare our current height with our supposed height.
1291 diff = y_height - GTK_RBNODE_GET_HEIGHT (node);
1295 while (tmp_tree && tmp_node && tmp_node != tmp_tree->nil)
1297 tmp_node->offset += diff;
1298 _fixup_validation (tmp_tree, tmp_node);
1299 _fixup_total_count (tmp_tree, tmp_node);
1300 tmp_node = tmp_node->parent;
1301 if (tmp_node == tmp_tree->nil)
1303 tmp_node = tmp_tree->parent_node;
1304 tmp_tree = tmp_tree->parent_tree;
1309 if (GTK_RBNODE_GET_COLOR (y) == GTK_RBNODE_BLACK)
1310 _gtk_rbtree_remove_node_fixup (tree, x);
1311 _gtk_rbnode_free (y);
1313 #ifdef G_ENABLE_DEBUG
1314 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
1316 g_print ("_gtk_rbtree_remove_node finished...\n");
1317 _gtk_rbtree_debug_spew (tree);
1319 _gtk_rbtree_test (G_STRLOC, tree);
1321 #endif /* G_ENABLE_DEBUG */
1325 _gtk_rbtree_next (GtkRBTree *tree,
1328 g_return_val_if_fail (tree != NULL, NULL);
1329 g_return_val_if_fail (node != NULL, NULL);
1331 /* Case 1: the node's below us. */
1332 if (node->right != tree->nil)
1335 while (node->left != tree->nil)
1340 /* Case 2: it's an ancestor */
1341 while (node->parent != tree->nil)
1343 if (node->parent->right == node)
1344 node = node->parent;
1346 return (node->parent);
1349 /* Case 3: There is no next node */
1354 _gtk_rbtree_prev (GtkRBTree *tree,
1357 g_return_val_if_fail (tree != NULL, NULL);
1358 g_return_val_if_fail (node != NULL, NULL);
1360 /* Case 1: the node's below us. */
1361 if (node->left != tree->nil)
1364 while (node->right != tree->nil)
1369 /* Case 2: it's an ancestor */
1370 while (node->parent != tree->nil)
1372 if (node->parent->left == node)
1373 node = node->parent;
1375 return (node->parent);
1378 /* Case 3: There is no next node */
1383 _gtk_rbtree_next_full (GtkRBTree *tree,
1385 GtkRBTree **new_tree,
1386 GtkRBNode **new_node)
1388 g_return_if_fail (tree != NULL);
1389 g_return_if_fail (node != NULL);
1390 g_return_if_fail (new_tree != NULL);
1391 g_return_if_fail (new_node != NULL);
1395 *new_tree = node->children;
1396 *new_node = (*new_tree)->root;
1397 while ((*new_node)->left != (*new_tree)->nil)
1398 *new_node = (*new_node)->left;
1403 *new_node = _gtk_rbtree_next (tree, node);
1405 while ((*new_node == NULL) &&
1406 (*new_tree != NULL))
1408 *new_node = (*new_tree)->parent_node;
1409 *new_tree = (*new_tree)->parent_tree;
1411 *new_node = _gtk_rbtree_next (*new_tree, *new_node);
1416 _gtk_rbtree_prev_full (GtkRBTree *tree,
1418 GtkRBTree **new_tree,
1419 GtkRBNode **new_node)
1421 g_return_if_fail (tree != NULL);
1422 g_return_if_fail (node != NULL);
1423 g_return_if_fail (new_tree != NULL);
1424 g_return_if_fail (new_node != NULL);
1427 *new_node = _gtk_rbtree_prev (tree, node);
1429 if (*new_node == NULL)
1431 *new_node = (*new_tree)->parent_node;
1432 *new_tree = (*new_tree)->parent_tree;
1436 while ((*new_node)->children)
1438 *new_tree = (*new_node)->children;
1439 *new_node = (*new_tree)->root;
1440 while ((*new_node)->right != (*new_tree)->nil)
1441 *new_node = (*new_node)->right;
1447 _gtk_rbtree_get_depth (GtkRBTree *tree)
1449 GtkRBTree *tmp_tree;
1452 tmp_tree = tree->parent_tree;
1456 tmp_tree = tmp_tree->parent_tree;
1463 _gtk_rbtree_traverse_pre_order (GtkRBTree *tree,
1465 GtkRBTreeTraverseFunc func,
1468 if (node == tree->nil)
1471 (* func) (tree, node, data);
1472 _gtk_rbtree_traverse_pre_order (tree, node->left, func, data);
1473 _gtk_rbtree_traverse_pre_order (tree, node->right, func, data);
1477 _gtk_rbtree_traverse_post_order (GtkRBTree *tree,
1479 GtkRBTreeTraverseFunc func,
1482 if (node == tree->nil)
1485 _gtk_rbtree_traverse_post_order (tree, node->left, func, data);
1486 _gtk_rbtree_traverse_post_order (tree, node->right, func, data);
1487 (* func) (tree, node, data);
1491 _gtk_rbtree_traverse (GtkRBTree *tree,
1493 GTraverseType order,
1494 GtkRBTreeTraverseFunc func,
1497 g_return_if_fail (tree != NULL);
1498 g_return_if_fail (node != NULL);
1499 g_return_if_fail (func != NULL);
1500 g_return_if_fail (order <= G_LEVEL_ORDER);
1505 _gtk_rbtree_traverse_pre_order (tree, node, func, data);
1508 _gtk_rbtree_traverse_post_order (tree, node, func, data);
1513 g_warning ("unsupported traversal order.");
1519 void _fixup_validation (GtkRBTree *tree,
1522 if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID) ||
1523 GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID) ||
1524 (node->left != tree->nil && GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID)) ||
1525 (node->right != tree->nil && GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID)) ||
1526 (node->children != NULL && GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID)))
1528 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
1532 GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
1537 void _fixup_total_count (GtkRBTree *tree,
1540 node->total_count = 1 +
1541 (node->children != NULL ? node->children->root->total_count : 0) +
1542 node->left->total_count + node->right->total_count;
1545 #ifdef G_ENABLE_DEBUG
1547 get_total_count (GtkRBNode *node)
1549 guint child_total = 0;
1551 child_total += (guint) node->left->total_count;
1552 child_total += (guint) node->right->total_count;
1555 child_total += (guint) node->children->root->total_count;
1557 return child_total + 1;
1561 count_total (GtkRBTree *tree,
1566 if (node == tree->nil)
1570 count_total (tree, node->left) +
1571 count_total (tree, node->right) +
1573 (node->children ? count_total (node->children, node->children->root) : 0);
1575 if (res != node->total_count)
1576 g_print ("total count incorrect for node\n");
1578 if (get_total_count (node) != node->total_count)
1579 g_error ("Node has incorrect total count %u, should be %u", node->total_count, get_total_count (node));
1585 _count_nodes (GtkRBTree *tree,
1589 if (node == tree->nil)
1592 g_assert (node->left);
1593 g_assert (node->right);
1595 res = (_count_nodes (tree, node->left) +
1596 _count_nodes (tree, node->right) + 1);
1598 if (res != node->count)
1599 g_print ("Tree failed\n");
1604 _gtk_rbtree_test_height (GtkRBTree *tree,
1607 gint computed_offset = 0;
1609 /* This whole test is sort of a useless truism. */
1611 if (node->left != tree->nil)
1612 computed_offset += node->left->offset;
1614 if (node->right != tree->nil)
1615 computed_offset += node->right->offset;
1617 if (node->children && node->children->root != node->children->nil)
1618 computed_offset += node->children->root->offset;
1620 if (GTK_RBNODE_GET_HEIGHT (node) + computed_offset != node->offset)
1621 g_error ("node has broken offset\n");
1623 if (node->left != tree->nil)
1624 _gtk_rbtree_test_height (tree, node->left);
1626 if (node->right != tree->nil)
1627 _gtk_rbtree_test_height (tree, node->right);
1629 if (node->children && node->children->root != node->children->nil)
1630 _gtk_rbtree_test_height (node->children, node->children->root);
1634 _gtk_rbtree_test_dirty (GtkRBTree *tree,
1636 gint expected_dirtyness)
1639 if (expected_dirtyness)
1641 g_assert (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID) ||
1642 GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID) ||
1643 (node->left != tree->nil && GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID)) ||
1644 (node->right != tree->nil && GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID)) ||
1645 (node->children && GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID)));
1649 g_assert (! GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID) &&
1650 ! GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID));
1651 if (node->left != tree->nil)
1652 g_assert (! GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID));
1653 if (node->right != tree->nil)
1654 g_assert (! GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID));
1655 if (node->children != NULL)
1656 g_assert (! GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID));
1659 if (node->left != tree->nil)
1660 _gtk_rbtree_test_dirty (tree, node->left, GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID));
1661 if (node->right != tree->nil)
1662 _gtk_rbtree_test_dirty (tree, node->right, GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID));
1663 if (node->children != NULL && node->children->root != node->children->nil)
1664 _gtk_rbtree_test_dirty (node->children, node->children->root, GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID));
1667 static void _gtk_rbtree_test_structure (GtkRBTree *tree);
1670 _gtk_rbtree_test_structure_helper (GtkRBTree *tree,
1673 g_assert (node != tree->nil);
1675 g_assert (node->left != NULL);
1676 g_assert (node->right != NULL);
1677 g_assert (node->parent != NULL);
1679 if (node->left != tree->nil)
1681 g_assert (node->left->parent == node);
1682 _gtk_rbtree_test_structure_helper (tree, node->left);
1684 if (node->right != tree->nil)
1686 g_assert (node->right->parent == node);
1687 _gtk_rbtree_test_structure_helper (tree, node->right);
1690 if (node->children != NULL)
1692 g_assert (node->children->parent_tree == tree);
1693 g_assert (node->children->parent_node == node);
1695 _gtk_rbtree_test_structure (node->children);
1699 _gtk_rbtree_test_structure (GtkRBTree *tree)
1701 g_assert (tree->root);
1702 if (tree->root == tree->nil)
1705 g_assert (tree->root->parent == tree->nil);
1706 _gtk_rbtree_test_structure_helper (tree, tree->root);
1710 _gtk_rbtree_test (const gchar *where,
1713 GtkRBTree *tmp_tree;
1718 /* Test the entire tree */
1720 while (tmp_tree->parent_tree)
1721 tmp_tree = tmp_tree->parent_tree;
1723 g_assert (tmp_tree->nil != NULL);
1725 if (tmp_tree->root == tmp_tree->nil)
1728 _gtk_rbtree_test_structure (tmp_tree);
1730 g_assert ((_count_nodes (tmp_tree, tmp_tree->root->left) +
1731 _count_nodes (tmp_tree, tmp_tree->root->right) + 1) == tmp_tree->root->count);
1734 _gtk_rbtree_test_height (tmp_tree, tmp_tree->root);
1735 _gtk_rbtree_test_dirty (tmp_tree, tmp_tree->root, GTK_RBNODE_FLAG_SET (tmp_tree->root, GTK_RBNODE_DESCENDANTS_INVALID));
1736 g_assert (count_total (tmp_tree, tmp_tree->root) == tmp_tree->root->total_count);
1740 _gtk_rbtree_debug_spew_helper (GtkRBTree *tree,
1745 for (i = 0; i < depth; i++)
1748 g_print ("(%p - %s) (Offset %d) (Parity %d) (Validity %d%d%d)\n",
1750 (GTK_RBNODE_GET_COLOR (node) == GTK_RBNODE_BLACK)?"BLACK":" RED ",
1753 (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_DESCENDANTS_INVALID))?1:0,
1754 (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID))?1:0,
1755 (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID))?1:0);
1756 if (node->children != NULL)
1758 g_print ("Looking at child.\n");
1759 _gtk_rbtree_debug_spew (node->children);
1760 g_print ("Done looking at child.\n");
1762 if (node->left != tree->nil)
1764 _gtk_rbtree_debug_spew_helper (tree, node->left, depth+1);
1766 if (node->right != tree->nil)
1768 _gtk_rbtree_debug_spew_helper (tree, node->right, depth+1);
1773 _gtk_rbtree_debug_spew (GtkRBTree *tree)
1775 g_return_if_fail (tree != NULL);
1777 if (tree->root == tree->nil)
1778 g_print ("Empty tree...\n");
1780 _gtk_rbtree_debug_spew_helper (tree, tree->root, 0);
1782 #endif /* G_ENABLE_DEBUG */