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,
40 static void _gtk_rbtree_test (const gchar *where,
42 static void _gtk_rbtree_debug_spew (GtkRBTree *tree);
48 _gtk_rbnode_new (GtkRBTree *tree,
51 GtkRBNode *node = g_slice_new (GtkRBNode);
53 node->left = tree->nil;
54 node->right = tree->nil;
55 node->parent = tree->nil;
56 node->flags = GTK_RBNODE_RED;
57 node->total_count = 1;
59 node->children = NULL;
60 node->offset = height;
65 _gtk_rbnode_free (GtkRBNode *node)
68 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
70 node->left = (gpointer) 0xdeadbeef;
71 node->right = (gpointer) 0xdeadbeef;
72 node->parent = (gpointer) 0xdeadbeef;
73 node->total_count = 56789;
79 g_slice_free (GtkRBNode, node);
83 _gtk_rbnode_rotate_left (GtkRBTree *tree,
86 gint node_height, right_height;
87 GtkRBNode *right = node->right;
89 g_return_if_fail (node != tree->nil);
91 node_height = node->offset -
92 (node->left?node->left->offset:0) -
93 (node->right?node->right->offset:0) -
94 (node->children?node->children->root->offset:0);
95 right_height = right->offset -
96 (right->left?right->left->offset:0) -
97 (right->right?right->right->offset:0) -
98 (right->children?right->children->root->offset:0);
99 node->right = right->left;
100 if (right->left != tree->nil)
101 right->left->parent = node;
103 if (right != tree->nil)
104 right->parent = node->parent;
105 if (node->parent != tree->nil)
107 if (node == node->parent->left)
108 node->parent->left = right;
110 node->parent->right = right;
116 if (node != tree->nil)
117 node->parent = right;
119 node->count = 1 + (node->left?node->left->count:0) +
120 (node->right?node->right->count:0);
121 right->count = 1 + (right->left?right->left->count:0) +
122 (right->right?right->right->count:0);
124 node->offset = node_height +
125 (node->left?node->left->offset:0) +
126 (node->right?node->right->offset:0) +
127 (node->children?node->children->root->offset:0);
128 right->offset = right_height +
129 (right->left?right->left->offset:0) +
130 (right->right?right->right->offset:0) +
131 (right->children?right->children->root->offset:0);
133 _fixup_validation (tree, node);
134 _fixup_validation (tree, right);
135 _fixup_total_count (tree, node);
136 _fixup_total_count (tree, right);
140 _gtk_rbnode_rotate_right (GtkRBTree *tree,
143 gint node_height, left_height;
144 GtkRBNode *left = node->left;
146 g_return_if_fail (node != tree->nil);
148 node_height = node->offset -
149 (node->left?node->left->offset:0) -
150 (node->right?node->right->offset:0) -
151 (node->children?node->children->root->offset:0);
152 left_height = left->offset -
153 (left->left?left->left->offset:0) -
154 (left->right?left->right->offset:0) -
155 (left->children?left->children->root->offset:0);
157 node->left = left->right;
158 if (left->right != tree->nil)
159 left->right->parent = node;
161 if (left != tree->nil)
162 left->parent = node->parent;
163 if (node->parent != tree->nil)
165 if (node == node->parent->right)
166 node->parent->right = left;
168 node->parent->left = left;
175 /* link node and left */
177 if (node != tree->nil)
180 node->count = 1 + (node->left?node->left->count:0) +
181 (node->right?node->right->count:0);
182 left->count = 1 + (left->left?left->left->count:0) +
183 (left->right?left->right->count:0);
185 node->offset = node_height +
186 (node->left?node->left->offset:0) +
187 (node->right?node->right->offset:0) +
188 (node->children?node->children->root->offset:0);
189 left->offset = left_height +
190 (left->left?left->left->offset:0) +
191 (left->right?left->right->offset:0) +
192 (left->children?left->children->root->offset:0);
194 _fixup_validation (tree, node);
195 _fixup_validation (tree, left);
196 _fixup_total_count (tree, node);
197 _fixup_total_count (tree, left);
201 _gtk_rbtree_insert_fixup (GtkRBTree *tree,
205 /* check Red-Black properties */
206 while (node != tree->root && GTK_RBNODE_GET_COLOR (node->parent) == GTK_RBNODE_RED)
208 /* we have a violation */
209 if (node->parent == node->parent->parent->left)
211 GtkRBNode *y = node->parent->parent->right;
212 if (GTK_RBNODE_GET_COLOR (y) == GTK_RBNODE_RED)
214 /* uncle is GTK_RBNODE_RED */
215 GTK_RBNODE_SET_COLOR (node->parent, GTK_RBNODE_BLACK);
216 GTK_RBNODE_SET_COLOR (y, GTK_RBNODE_BLACK);
217 GTK_RBNODE_SET_COLOR (node->parent->parent, GTK_RBNODE_RED);
218 node = node->parent->parent;
222 /* uncle is GTK_RBNODE_BLACK */
223 if (node == node->parent->right)
225 /* make node a left child */
227 _gtk_rbnode_rotate_left (tree, node);
230 /* recolor and rotate */
231 GTK_RBNODE_SET_COLOR (node->parent, GTK_RBNODE_BLACK);
232 GTK_RBNODE_SET_COLOR (node->parent->parent, GTK_RBNODE_RED);
233 _gtk_rbnode_rotate_right(tree, node->parent->parent);
238 /* mirror image of above code */
239 GtkRBNode *y = node->parent->parent->left;
240 if (GTK_RBNODE_GET_COLOR (y) == GTK_RBNODE_RED)
242 /* uncle is GTK_RBNODE_RED */
243 GTK_RBNODE_SET_COLOR (node->parent, GTK_RBNODE_BLACK);
244 GTK_RBNODE_SET_COLOR (y, GTK_RBNODE_BLACK);
245 GTK_RBNODE_SET_COLOR (node->parent->parent, GTK_RBNODE_RED);
246 node = node->parent->parent;
250 /* uncle is GTK_RBNODE_BLACK */
251 if (node == node->parent->left)
254 _gtk_rbnode_rotate_right (tree, node);
256 GTK_RBNODE_SET_COLOR (node->parent, GTK_RBNODE_BLACK);
257 GTK_RBNODE_SET_COLOR (node->parent->parent, GTK_RBNODE_RED);
258 _gtk_rbnode_rotate_left (tree, node->parent->parent);
262 GTK_RBNODE_SET_COLOR (tree->root, GTK_RBNODE_BLACK);
266 _gtk_rbtree_remove_node_fixup (GtkRBTree *tree,
269 while (node != tree->root && GTK_RBNODE_GET_COLOR (node) == GTK_RBNODE_BLACK)
271 if (node == node->parent->left)
273 GtkRBNode *w = node->parent->right;
274 if (GTK_RBNODE_GET_COLOR (w) == GTK_RBNODE_RED)
276 GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_BLACK);
277 GTK_RBNODE_SET_COLOR (node->parent, GTK_RBNODE_RED);
278 _gtk_rbnode_rotate_left (tree, node->parent);
279 w = node->parent->right;
281 if (GTK_RBNODE_GET_COLOR (w->left) == GTK_RBNODE_BLACK && GTK_RBNODE_GET_COLOR (w->right) == GTK_RBNODE_BLACK)
283 GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_RED);
288 if (GTK_RBNODE_GET_COLOR (w->right) == GTK_RBNODE_BLACK)
290 GTK_RBNODE_SET_COLOR (w->left, GTK_RBNODE_BLACK);
291 GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_RED);
292 _gtk_rbnode_rotate_right (tree, w);
293 w = node->parent->right;
295 GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_GET_COLOR (node->parent));
296 GTK_RBNODE_SET_COLOR (node->parent, GTK_RBNODE_BLACK);
297 GTK_RBNODE_SET_COLOR (w->right, GTK_RBNODE_BLACK);
298 _gtk_rbnode_rotate_left (tree, node->parent);
304 GtkRBNode *w = node->parent->left;
305 if (GTK_RBNODE_GET_COLOR (w) == GTK_RBNODE_RED)
307 GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_BLACK);
308 GTK_RBNODE_SET_COLOR (node->parent, GTK_RBNODE_RED);
309 _gtk_rbnode_rotate_right (tree, node->parent);
310 w = node->parent->left;
312 if (GTK_RBNODE_GET_COLOR (w->right) == GTK_RBNODE_BLACK && GTK_RBNODE_GET_COLOR (w->left) == GTK_RBNODE_BLACK)
314 GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_RED);
319 if (GTK_RBNODE_GET_COLOR (w->left) == GTK_RBNODE_BLACK)
321 GTK_RBNODE_SET_COLOR (w->right, GTK_RBNODE_BLACK);
322 GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_RED);
323 _gtk_rbnode_rotate_left (tree, w);
324 w = node->parent->left;
326 GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_GET_COLOR (node->parent));
327 GTK_RBNODE_SET_COLOR (node->parent, GTK_RBNODE_BLACK);
328 GTK_RBNODE_SET_COLOR (w->left, GTK_RBNODE_BLACK);
329 _gtk_rbnode_rotate_right (tree, node->parent);
334 GTK_RBNODE_SET_COLOR (node, GTK_RBNODE_BLACK);
338 _gtk_rbtree_new (void)
342 retval = g_new (GtkRBTree, 1);
343 retval->parent_tree = NULL;
344 retval->parent_node = NULL;
346 retval->nil = g_slice_new (GtkRBNode);
347 retval->nil->left = NULL;
348 retval->nil->right = NULL;
349 retval->nil->parent = NULL;
350 retval->nil->flags = GTK_RBNODE_BLACK;
351 retval->nil->count = 0;
352 retval->nil->offset = 0;
353 retval->nil->total_count = 0;
355 retval->root = retval->nil;
360 _gtk_rbtree_free_helper (GtkRBTree *tree,
365 _gtk_rbtree_free (node->children);
367 _gtk_rbnode_free (node);
371 _gtk_rbtree_free (GtkRBTree *tree)
373 _gtk_rbtree_traverse (tree,
376 _gtk_rbtree_free_helper,
379 if (tree->parent_node &&
380 tree->parent_node->children == tree)
381 tree->parent_node->children = NULL;
382 _gtk_rbnode_free (tree->nil);
387 gtk_rbnode_adjust (GtkRBTree *tree,
390 int total_count_diff,
393 while (tree && node && node != tree->nil)
395 _fixup_validation (tree, node);
396 node->offset += offset_diff;
397 node->count += count_diff;
398 node->total_count += total_count_diff;
401 if (node == tree->nil)
403 node = tree->parent_node;
404 tree = tree->parent_tree;
411 _gtk_rbtree_remove (GtkRBTree *tree)
413 #ifdef G_ENABLE_DEBUG
416 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
417 _gtk_rbtree_test (G_STRLOC, tree);
420 /* ugly hack to make _fixup_validation work in the first iteration of the
422 GTK_RBNODE_UNSET_FLAG (tree->root, GTK_RBNODE_DESCENDANTS_INVALID);
424 gtk_rbnode_adjust (tree->parent_tree,
427 - (int) tree->root->total_count,
428 - tree->root->offset);
430 #ifdef G_ENABLE_DEBUG
431 tmp_tree = tree->parent_tree;
434 _gtk_rbtree_free (tree);
436 #ifdef G_ENABLE_DEBUG
437 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
438 _gtk_rbtree_test (G_STRLOC, tmp_tree);
444 _gtk_rbtree_insert_after (GtkRBTree *tree,
450 gboolean right = TRUE;
454 #ifdef G_ENABLE_DEBUG
455 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
457 g_print ("\n\n_gtk_rbtree_insert_after: %p\n", current);
458 _gtk_rbtree_debug_spew (tree);
459 _gtk_rbtree_test (G_STRLOC, tree);
461 #endif /* G_ENABLE_DEBUG */
463 if (current != NULL && current->right != tree->nil)
465 current = current->right;
466 while (current->left != tree->nil)
467 current = current->left;
471 node = _gtk_rbnode_new (tree, height);
472 node->parent = (current?current:tree->nil);
474 /* insert node in tree */
478 current->right = node;
480 current->left = node;
481 tmp_node = node->parent;
486 g_assert (tree->root == tree->nil);
488 tmp_node = tree->parent_node;
489 tmp_tree = tree->parent_tree;
492 while (tmp_tree && tmp_node && tmp_node != tmp_tree->nil)
494 /* We only want to propagate the count if we are in the tree we
496 if (tmp_tree == tree)
499 tmp_node->total_count += 1;
500 tmp_node->offset += height;
501 tmp_node = tmp_node->parent;
502 if (tmp_node == tmp_tree->nil)
504 tmp_node = tmp_tree->parent_node;
505 tmp_tree = tmp_tree->parent_tree;
510 _gtk_rbtree_node_mark_valid (tree, node);
512 _gtk_rbtree_node_mark_invalid (tree, node);
514 _gtk_rbtree_insert_fixup (tree, node);
516 #ifdef G_ENABLE_DEBUG
517 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
519 g_print ("_gtk_rbtree_insert_after finished...\n");
520 _gtk_rbtree_debug_spew (tree);
522 _gtk_rbtree_test (G_STRLOC, tree);
524 #endif /* G_ENABLE_DEBUG */
530 _gtk_rbtree_insert_before (GtkRBTree *tree,
536 gboolean left = TRUE;
540 #ifdef G_ENABLE_DEBUG
541 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
543 g_print ("\n\n_gtk_rbtree_insert_before: %p\n", current);
544 _gtk_rbtree_debug_spew (tree);
545 _gtk_rbtree_test (G_STRLOC, tree);
547 #endif /* G_ENABLE_DEBUG */
549 if (current != NULL && current->left != tree->nil)
551 current = current->left;
552 while (current->right != tree->nil)
553 current = current->right;
558 node = _gtk_rbnode_new (tree, height);
559 node->parent = (current?current:tree->nil);
561 /* insert node in tree */
565 current->left = node;
567 current->right = node;
568 tmp_node = node->parent;
573 g_assert (tree->root == tree->nil);
575 tmp_node = tree->parent_node;
576 tmp_tree = tree->parent_tree;
579 while (tmp_tree && tmp_node && tmp_node != tmp_tree->nil)
581 /* We only want to propagate the count if we are in the tree we
583 if (tmp_tree == tree)
586 tmp_node->total_count += 1;
587 tmp_node->offset += height;
588 tmp_node = tmp_node->parent;
589 if (tmp_node == tmp_tree->nil)
591 tmp_node = tmp_tree->parent_node;
592 tmp_tree = tmp_tree->parent_tree;
597 _gtk_rbtree_node_mark_valid (tree, node);
599 _gtk_rbtree_node_mark_invalid (tree, node);
601 _gtk_rbtree_insert_fixup (tree, node);
603 #ifdef G_ENABLE_DEBUG
604 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
606 g_print ("_gtk_rbtree_insert_before finished...\n");
607 _gtk_rbtree_debug_spew (tree);
609 _gtk_rbtree_test (G_STRLOC, tree);
611 #endif /* G_ENABLE_DEBUG */
617 _gtk_rbtree_find_count (GtkRBTree *tree,
623 while (node != tree->nil && (node->left->count + 1 != count))
625 if (node->left->count >= count)
629 count -= (node->left->count + 1);
633 if (node == tree->nil)
639 _gtk_rbtree_node_set_height (GtkRBTree *tree,
643 gint diff = height - GTK_RBNODE_GET_HEIGHT (node);
644 GtkRBNode *tmp_node = node;
645 GtkRBTree *tmp_tree = tree;
650 while (tmp_tree && tmp_node && tmp_node != tmp_tree->nil)
652 tmp_node->offset += diff;
653 tmp_node = tmp_node->parent;
654 if (tmp_node == tmp_tree->nil)
656 tmp_node = tmp_tree->parent_node;
657 tmp_tree = tmp_tree->parent_tree;
660 #ifdef G_ENABLE_DEBUG
661 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
662 _gtk_rbtree_test (G_STRLOC, tree);
667 _gtk_rbtree_node_mark_invalid (GtkRBTree *tree,
670 if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID))
673 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_INVALID);
676 if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_DESCENDANTS_INVALID))
678 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
680 if (node == tree->nil)
682 node = tree->parent_node;
683 tree = tree->parent_tree;
690 /* Draconian version. */
692 _gtk_rbtree_node_mark_invalid (GtkRBTree *tree,
695 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_INVALID);
698 _fixup_validation (tree, node);
700 if (node == tree->nil)
702 node = tree->parent_node;
703 tree = tree->parent_tree;
711 _gtk_rbtree_node_mark_valid (GtkRBTree *tree,
714 if ((!GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID)) &&
715 (!GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID)))
718 GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_INVALID);
719 GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_COLUMN_INVALID);
723 if ((GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID)) ||
724 (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID)) ||
725 (node->children && GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID)) ||
726 (node->left != tree->nil && GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID)) ||
727 (node->right != tree->nil && GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID)))
730 GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
732 if (node == tree->nil)
734 node = tree->parent_node;
735 tree = tree->parent_tree;
742 /* Draconian version */
744 _gtk_rbtree_node_mark_valid (GtkRBTree *tree,
747 GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_INVALID);
748 GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_COLUMN_INVALID);
752 _fixup_validation (tree, node);
754 if (node == tree->nil)
756 node = tree->parent_node;
757 tree = tree->parent_tree;
763 /* Assume tree is the root node as it doesn't set DESCENDANTS_INVALID above.
766 _gtk_rbtree_column_invalid (GtkRBTree *tree)
775 while (node->left != tree->nil)
780 if (! (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID)))
781 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_COLUMN_INVALID);
782 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
785 _gtk_rbtree_column_invalid (node->children);
787 while ((node = _gtk_rbtree_next (tree, node)) != NULL);
791 _gtk_rbtree_mark_invalid (GtkRBTree *tree)
800 while (node->left != tree->nil)
805 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_INVALID);
806 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
809 _gtk_rbtree_mark_invalid (node->children);
811 while ((node = _gtk_rbtree_next (tree, node)) != NULL);
815 _gtk_rbtree_set_fixed_height (GtkRBTree *tree,
827 while (node->left != tree->nil)
832 if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID))
834 _gtk_rbtree_node_set_height (tree, node, height);
836 _gtk_rbtree_node_mark_valid (tree, node);
840 _gtk_rbtree_set_fixed_height (node->children, height, mark_valid);
842 while ((node = _gtk_rbtree_next (tree, node)) != NULL);
845 typedef struct _GtkRBReorder
856 gtk_rbtree_reorder_sort_func (gconstpointer a,
859 return ((GtkRBReorder *) a)->order - ((GtkRBReorder *) b)->order;
863 gtk_rbtree_reorder_invert_func (gconstpointer a,
866 return ((GtkRBReorder *) a)->invert_order - ((GtkRBReorder *) b)->invert_order;
870 gtk_rbtree_reorder_fixup (GtkRBTree *tree,
873 if (node == tree->nil)
876 node->total_count = 1;
878 if (node->left != tree->nil)
880 gtk_rbtree_reorder_fixup (tree, node->left);
881 node->offset += node->left->offset;
882 node->total_count += node->left->total_count;
884 if (node->right != tree->nil)
886 gtk_rbtree_reorder_fixup (tree, node->right);
887 node->offset += node->right->offset;
888 node->total_count += node->right->total_count;
893 node->offset += node->children->root->offset;
894 node->total_count += node->children->root->total_count;
897 if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID) ||
898 (node->right != tree->nil && GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID)) ||
899 (node->left != tree->nil && GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID)) ||
900 (node->children && GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID)))
901 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
903 GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
906 /* It basically pulls everything out of the tree, rearranges it, and puts it
907 * back together. Our strategy is to keep the old RBTree intact, and just
908 * rearrange the contents. When that is done, we go through and update the
909 * heights. There is probably a more elegant way to write this function. If
910 * anyone wants to spend the time writing it, patches will be accepted.
913 _gtk_rbtree_reorder (GtkRBTree *tree,
917 GtkRBReorder reorder = { NULL };
922 g_return_if_fail (tree != NULL);
923 g_return_if_fail (length > 0);
924 g_return_if_fail (tree->root->count == length);
926 /* Sort the trees values in the new tree. */
927 array = g_array_sized_new (FALSE, FALSE, sizeof (GtkRBReorder), length);
928 for (i = 0; i < length; i++)
930 reorder.order = new_order[i];
931 reorder.invert_order = i;
932 g_array_append_val (array, reorder);
935 g_array_sort(array, gtk_rbtree_reorder_sort_func);
939 while (node && node->left != tree->nil)
942 for (i = 0; i < length; i++)
944 g_assert (node != tree->nil);
945 g_array_index (array, GtkRBReorder, i).children = node->children;
946 g_array_index (array, GtkRBReorder, i).flags = GTK_RBNODE_NON_COLORS & node->flags;
947 g_array_index (array, GtkRBReorder, i).height = GTK_RBNODE_GET_HEIGHT (node);
949 node = _gtk_rbtree_next (tree, node);
952 g_array_sort (array, gtk_rbtree_reorder_invert_func);
956 while (node && node->left != tree->nil)
959 /* Go through the tree and change the values to the new ones. */
960 for (i = 0; i < length; i++)
962 reorder = g_array_index (array, GtkRBReorder, i);
963 node->children = reorder.children;
965 node->children->parent_node = node;
966 node->flags = GTK_RBNODE_GET_COLOR (node) | reorder.flags;
967 /* We temporarily set the height to this. */
968 node->offset = reorder.height;
969 node = _gtk_rbtree_next (tree, node);
971 gtk_rbtree_reorder_fixup (tree, tree->root);
973 g_array_free (array, TRUE);
978 _gtk_rbtree_node_find_offset (GtkRBTree *tree,
985 g_assert (node->left);
987 retval = node->left->offset;
989 while (tree && node && node != tree->nil)
994 /* Add left branch, plus children, iff we came from the right */
995 if (node->right == last)
996 retval += node->offset - node->right->offset;
998 if (node == tree->nil)
1000 node = tree->parent_node;
1001 tree = tree->parent_tree;
1003 /* Add the parent node, plus the left branch. */
1005 retval += node->left->offset + GTK_RBNODE_GET_HEIGHT (node);
1012 _gtk_rbtree_node_get_index (GtkRBTree *tree,
1019 g_assert (node->left);
1021 retval = node->left->total_count;
1023 while (tree && node && node != tree->nil)
1026 node = node->parent;
1028 /* Add left branch, plus children, iff we came from the right */
1029 if (node->right == last)
1030 retval += node->total_count - node->right->total_count;
1032 if (node == tree->nil)
1034 node = tree->parent_node;
1035 tree = tree->parent_tree;
1037 /* Add the parent node, plus the left branch. */
1039 retval += node->left->total_count + 1; /* 1 == GTK_RBNODE_GET_PARITY() */
1047 _gtk_rbtree_real_find_offset (GtkRBTree *tree,
1049 GtkRBTree **new_tree,
1050 GtkRBNode **new_node)
1052 GtkRBNode *tmp_node;
1065 tmp_node = tree->root;
1066 while (tmp_node != tree->nil &&
1067 (tmp_node->left->offset > height ||
1068 (tmp_node->offset - tmp_node->right->offset) < height))
1070 if (tmp_node->left->offset > height)
1071 tmp_node = tmp_node->left;
1074 height -= (tmp_node->offset - tmp_node->right->offset);
1075 tmp_node = tmp_node->right;
1078 if (tmp_node == tree->nil)
1084 if (tmp_node->children)
1086 if ((tmp_node->offset -
1087 tmp_node->right->offset -
1088 tmp_node->children->root->offset) > height)
1091 *new_node = tmp_node;
1092 return (height - tmp_node->left->offset);
1094 return _gtk_rbtree_real_find_offset (tmp_node->children,
1095 height - tmp_node->left->offset -
1097 tmp_node->left->offset -
1098 tmp_node->right->offset -
1099 tmp_node->children->root->offset),
1104 *new_node = tmp_node;
1105 return (height - tmp_node->left->offset);
1109 _gtk_rbtree_find_offset (GtkRBTree *tree,
1111 GtkRBTree **new_tree,
1112 GtkRBNode **new_node)
1117 (height >= tree->root->offset))
1124 return _gtk_rbtree_real_find_offset (tree, height, new_tree, new_node);
1128 _gtk_rbtree_find_index (GtkRBTree *tree,
1130 GtkRBTree **new_tree,
1131 GtkRBNode **new_node)
1133 GtkRBNode *tmp_node;
1137 tmp_node = tree->root;
1138 while (tmp_node != tree->nil)
1140 if (tmp_node->left->total_count > index)
1142 tmp_node = tmp_node->left;
1144 else if (tmp_node->total_count - tmp_node->right->total_count <= index)
1146 index -= tmp_node->total_count - tmp_node->right->total_count;
1147 tmp_node = tmp_node->right;
1151 index -= tmp_node->left->total_count;
1155 if (tmp_node == tree->nil)
1164 g_assert (tmp_node->children);
1166 return _gtk_rbtree_find_index (tmp_node->children,
1173 *new_node = tmp_node;
1178 _gtk_rbtree_remove_node (GtkRBTree *tree,
1182 GtkRBTree *tmp_tree;
1183 GtkRBNode *tmp_node;
1186 g_return_if_fail (tree != NULL);
1187 g_return_if_fail (node != NULL);
1190 #ifdef G_ENABLE_DEBUG
1191 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
1193 g_print ("\n\n_gtk_rbtree_remove_node: %p\n", node);
1194 _gtk_rbtree_debug_spew (tree);
1195 _gtk_rbtree_test (G_STRLOC, tree);
1197 #endif /* G_ENABLE_DEBUG */
1199 /* make sure we're deleting a node that's actually in the tree */
1200 for (x = node; x->parent != tree->nil; x = x->parent)
1202 g_return_if_fail (x == tree->root);
1204 #ifdef G_ENABLE_DEBUG
1205 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
1206 _gtk_rbtree_test (G_STRLOC, tree);
1209 if (node->left == tree->nil || node->right == tree->nil)
1217 while (y->left != tree->nil)
1221 /* adjust count only beneath tree */
1222 for (x = y; x != tree->nil; x = x->parent)
1227 /* offsets and total count adjust all the way up through parent trees */
1228 y_height = GTK_RBNODE_GET_HEIGHT (y);
1232 while (tmp_tree && tmp_node && tmp_node != tmp_tree->nil)
1234 tmp_node->offset -= (y_height + (y->children?y->children->root->offset:0));
1235 _fixup_validation (tmp_tree, tmp_node);
1236 _fixup_total_count (tmp_tree, tmp_node);
1237 tmp_node = tmp_node->parent;
1238 if (tmp_node == tmp_tree->nil)
1240 tmp_node = tmp_tree->parent_node;
1241 tmp_tree = tmp_tree->parent_tree;
1245 /* x is y's only child, or nil */
1246 if (y->left != tree->nil)
1251 /* remove y from the parent chain */
1252 x->parent = y->parent;
1253 if (y->parent != tree->nil)
1255 if (y == y->parent->left)
1256 y->parent->left = x;
1258 y->parent->right = x;
1265 /* We need to clean up the validity of the tree.
1272 /* We skip the first time, iff x is nil */
1273 if (tmp_node != tmp_tree->nil)
1275 _fixup_validation (tmp_tree, tmp_node);
1276 _fixup_total_count (tmp_tree, tmp_node);
1278 tmp_node = tmp_node->parent;
1279 if (tmp_node == tmp_tree->nil)
1281 tmp_node = tmp_tree->parent_node;
1282 tmp_tree = tmp_tree->parent_tree;
1285 while (tmp_tree != NULL);
1291 /* Copy the node over */
1292 if (GTK_RBNODE_GET_COLOR (node) == GTK_RBNODE_BLACK)
1293 node->flags = ((y->flags & (GTK_RBNODE_NON_COLORS)) | GTK_RBNODE_BLACK);
1295 node->flags = ((y->flags & (GTK_RBNODE_NON_COLORS)) | GTK_RBNODE_RED);
1298 node->children = y->children;
1299 node->children->parent_node = node;
1303 node->children = NULL;
1305 _fixup_validation (tree, node);
1306 _fixup_total_count (tree, node);
1307 /* We want to see how different our height is from the previous node.
1308 * To do this, we compare our current height with our supposed height.
1310 diff = y_height - GTK_RBNODE_GET_HEIGHT (node);
1314 while (tmp_tree && tmp_node && tmp_node != tmp_tree->nil)
1316 tmp_node->offset += diff;
1317 _fixup_validation (tmp_tree, tmp_node);
1318 _fixup_total_count (tmp_tree, tmp_node);
1319 tmp_node = tmp_node->parent;
1320 if (tmp_node == tmp_tree->nil)
1322 tmp_node = tmp_tree->parent_node;
1323 tmp_tree = tmp_tree->parent_tree;
1328 if (GTK_RBNODE_GET_COLOR (y) == GTK_RBNODE_BLACK)
1329 _gtk_rbtree_remove_node_fixup (tree, x);
1330 _gtk_rbnode_free (y);
1332 #ifdef G_ENABLE_DEBUG
1333 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
1335 g_print ("_gtk_rbtree_remove_node finished...\n");
1336 _gtk_rbtree_debug_spew (tree);
1338 _gtk_rbtree_test (G_STRLOC, tree);
1340 #endif /* G_ENABLE_DEBUG */
1344 _gtk_rbtree_next (GtkRBTree *tree,
1347 g_return_val_if_fail (tree != NULL, NULL);
1348 g_return_val_if_fail (node != NULL, NULL);
1350 /* Case 1: the node's below us. */
1351 if (node->right != tree->nil)
1354 while (node->left != tree->nil)
1359 /* Case 2: it's an ancestor */
1360 while (node->parent != tree->nil)
1362 if (node->parent->right == node)
1363 node = node->parent;
1365 return (node->parent);
1368 /* Case 3: There is no next node */
1373 _gtk_rbtree_prev (GtkRBTree *tree,
1376 g_return_val_if_fail (tree != NULL, NULL);
1377 g_return_val_if_fail (node != NULL, NULL);
1379 /* Case 1: the node's below us. */
1380 if (node->left != tree->nil)
1383 while (node->right != tree->nil)
1388 /* Case 2: it's an ancestor */
1389 while (node->parent != tree->nil)
1391 if (node->parent->left == node)
1392 node = node->parent;
1394 return (node->parent);
1397 /* Case 3: There is no next node */
1402 _gtk_rbtree_next_full (GtkRBTree *tree,
1404 GtkRBTree **new_tree,
1405 GtkRBNode **new_node)
1407 g_return_if_fail (tree != NULL);
1408 g_return_if_fail (node != NULL);
1409 g_return_if_fail (new_tree != NULL);
1410 g_return_if_fail (new_node != NULL);
1414 *new_tree = node->children;
1415 *new_node = (*new_tree)->root;
1416 while ((*new_node)->left != (*new_tree)->nil)
1417 *new_node = (*new_node)->left;
1422 *new_node = _gtk_rbtree_next (tree, node);
1424 while ((*new_node == NULL) &&
1425 (*new_tree != NULL))
1427 *new_node = (*new_tree)->parent_node;
1428 *new_tree = (*new_tree)->parent_tree;
1430 *new_node = _gtk_rbtree_next (*new_tree, *new_node);
1435 _gtk_rbtree_prev_full (GtkRBTree *tree,
1437 GtkRBTree **new_tree,
1438 GtkRBNode **new_node)
1440 g_return_if_fail (tree != NULL);
1441 g_return_if_fail (node != NULL);
1442 g_return_if_fail (new_tree != NULL);
1443 g_return_if_fail (new_node != NULL);
1446 *new_node = _gtk_rbtree_prev (tree, node);
1448 if (*new_node == NULL)
1450 *new_node = (*new_tree)->parent_node;
1451 *new_tree = (*new_tree)->parent_tree;
1455 while ((*new_node)->children)
1457 *new_tree = (*new_node)->children;
1458 *new_node = (*new_tree)->root;
1459 while ((*new_node)->right != (*new_tree)->nil)
1460 *new_node = (*new_node)->right;
1466 _gtk_rbtree_get_depth (GtkRBTree *tree)
1468 GtkRBTree *tmp_tree;
1471 tmp_tree = tree->parent_tree;
1475 tmp_tree = tmp_tree->parent_tree;
1482 _gtk_rbtree_traverse_pre_order (GtkRBTree *tree,
1484 GtkRBTreeTraverseFunc func,
1487 if (node == tree->nil)
1490 (* func) (tree, node, data);
1491 _gtk_rbtree_traverse_pre_order (tree, node->left, func, data);
1492 _gtk_rbtree_traverse_pre_order (tree, node->right, func, data);
1496 _gtk_rbtree_traverse_post_order (GtkRBTree *tree,
1498 GtkRBTreeTraverseFunc func,
1501 if (node == tree->nil)
1504 _gtk_rbtree_traverse_post_order (tree, node->left, func, data);
1505 _gtk_rbtree_traverse_post_order (tree, node->right, func, data);
1506 (* func) (tree, node, data);
1510 _gtk_rbtree_traverse (GtkRBTree *tree,
1512 GTraverseType order,
1513 GtkRBTreeTraverseFunc func,
1516 g_return_if_fail (tree != NULL);
1517 g_return_if_fail (node != NULL);
1518 g_return_if_fail (func != NULL);
1519 g_return_if_fail (order <= G_LEVEL_ORDER);
1524 _gtk_rbtree_traverse_pre_order (tree, node, func, data);
1527 _gtk_rbtree_traverse_post_order (tree, node, func, data);
1532 g_warning ("unsupported traversal order.");
1538 void _fixup_validation (GtkRBTree *tree,
1541 if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID) ||
1542 GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID) ||
1543 (node->left != tree->nil && GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID)) ||
1544 (node->right != tree->nil && GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID)) ||
1545 (node->children != NULL && GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID)))
1547 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
1551 GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
1556 void _fixup_total_count (GtkRBTree *tree,
1559 node->total_count = 1 +
1560 (node->children != NULL ? node->children->root->total_count : 0) +
1561 node->left->total_count + node->right->total_count;
1564 #ifdef G_ENABLE_DEBUG
1566 get_total_count (GtkRBNode *node)
1568 guint child_total = 0;
1570 child_total += (guint) node->left->total_count;
1571 child_total += (guint) node->right->total_count;
1574 child_total += (guint) node->children->root->total_count;
1576 return child_total + 1;
1580 count_total (GtkRBTree *tree,
1585 if (node == tree->nil)
1589 count_total (tree, node->left) +
1590 count_total (tree, node->right) +
1592 (node->children ? count_total (node->children, node->children->root) : 0);
1594 if (res != node->total_count)
1595 g_print ("total count incorrect for node\n");
1597 if (get_total_count (node) != node->total_count)
1598 g_error ("Node has incorrect total count %u, should be %u", node->total_count, get_total_count (node));
1604 _count_nodes (GtkRBTree *tree,
1608 if (node == tree->nil)
1611 g_assert (node->left);
1612 g_assert (node->right);
1614 res = (_count_nodes (tree, node->left) +
1615 _count_nodes (tree, node->right) + 1);
1617 if (res != node->count)
1618 g_print ("Tree failed\n");
1623 _gtk_rbtree_test_height (GtkRBTree *tree,
1626 gint computed_offset = 0;
1628 /* This whole test is sort of a useless truism. */
1630 if (node->left != tree->nil)
1631 computed_offset += node->left->offset;
1633 if (node->right != tree->nil)
1634 computed_offset += node->right->offset;
1636 if (node->children && node->children->root != node->children->nil)
1637 computed_offset += node->children->root->offset;
1639 if (GTK_RBNODE_GET_HEIGHT (node) + computed_offset != node->offset)
1640 g_error ("node has broken offset\n");
1642 if (node->left != tree->nil)
1643 _gtk_rbtree_test_height (tree, node->left);
1645 if (node->right != tree->nil)
1646 _gtk_rbtree_test_height (tree, node->right);
1648 if (node->children && node->children->root != node->children->nil)
1649 _gtk_rbtree_test_height (node->children, node->children->root);
1653 _gtk_rbtree_test_dirty (GtkRBTree *tree,
1655 gint expected_dirtyness)
1658 if (expected_dirtyness)
1660 g_assert (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID) ||
1661 GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID) ||
1662 (node->left != tree->nil && GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID)) ||
1663 (node->right != tree->nil && GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID)) ||
1664 (node->children && GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID)));
1668 g_assert (! GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID) &&
1669 ! GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID));
1670 if (node->left != tree->nil)
1671 g_assert (! GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID));
1672 if (node->right != tree->nil)
1673 g_assert (! GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID));
1674 if (node->children != NULL)
1675 g_assert (! GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID));
1678 if (node->left != tree->nil)
1679 _gtk_rbtree_test_dirty (tree, node->left, GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID));
1680 if (node->right != tree->nil)
1681 _gtk_rbtree_test_dirty (tree, node->right, GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID));
1682 if (node->children != NULL && node->children->root != node->children->nil)
1683 _gtk_rbtree_test_dirty (node->children, node->children->root, GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID));
1686 static void _gtk_rbtree_test_structure (GtkRBTree *tree);
1689 _gtk_rbtree_test_structure_helper (GtkRBTree *tree,
1692 g_assert (node != tree->nil);
1694 g_assert (node->left != NULL);
1695 g_assert (node->right != NULL);
1696 g_assert (node->parent != NULL);
1698 if (node->left != tree->nil)
1700 g_assert (node->left->parent == node);
1701 _gtk_rbtree_test_structure_helper (tree, node->left);
1703 if (node->right != tree->nil)
1705 g_assert (node->right->parent == node);
1706 _gtk_rbtree_test_structure_helper (tree, node->right);
1709 if (node->children != NULL)
1711 g_assert (node->children->parent_tree == tree);
1712 g_assert (node->children->parent_node == node);
1714 _gtk_rbtree_test_structure (node->children);
1718 _gtk_rbtree_test_structure (GtkRBTree *tree)
1720 g_assert (tree->root);
1721 if (tree->root == tree->nil)
1724 g_assert (tree->root->parent == tree->nil);
1725 _gtk_rbtree_test_structure_helper (tree, tree->root);
1729 _gtk_rbtree_test (const gchar *where,
1732 GtkRBTree *tmp_tree;
1737 /* Test the entire tree */
1739 while (tmp_tree->parent_tree)
1740 tmp_tree = tmp_tree->parent_tree;
1742 g_assert (tmp_tree->nil != NULL);
1744 if (tmp_tree->root == tmp_tree->nil)
1747 _gtk_rbtree_test_structure (tmp_tree);
1749 g_assert ((_count_nodes (tmp_tree, tmp_tree->root->left) +
1750 _count_nodes (tmp_tree, tmp_tree->root->right) + 1) == tmp_tree->root->count);
1753 _gtk_rbtree_test_height (tmp_tree, tmp_tree->root);
1754 _gtk_rbtree_test_dirty (tmp_tree, tmp_tree->root, GTK_RBNODE_FLAG_SET (tmp_tree->root, GTK_RBNODE_DESCENDANTS_INVALID));
1755 g_assert (count_total (tmp_tree, tmp_tree->root) == tmp_tree->root->total_count);
1759 _gtk_rbtree_debug_spew_helper (GtkRBTree *tree,
1764 for (i = 0; i < depth; i++)
1767 g_print ("(%p - %s) (Offset %d) (Parity %d) (Validity %d%d%d)\n",
1769 (GTK_RBNODE_GET_COLOR (node) == GTK_RBNODE_BLACK)?"BLACK":" RED ",
1772 (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_DESCENDANTS_INVALID))?1:0,
1773 (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID))?1:0,
1774 (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID))?1:0);
1775 if (node->children != NULL)
1777 g_print ("Looking at child.\n");
1778 _gtk_rbtree_debug_spew (node->children);
1779 g_print ("Done looking at child.\n");
1781 if (node->left != tree->nil)
1783 _gtk_rbtree_debug_spew_helper (tree, node->left, depth+1);
1785 if (node->right != tree->nil)
1787 _gtk_rbtree_debug_spew_helper (tree, node->right, depth+1);
1792 _gtk_rbtree_debug_spew (GtkRBTree *tree)
1794 g_return_if_fail (tree != NULL);
1796 if (tree->root == tree->nil)
1797 g_print ("Empty tree...\n");
1799 _gtk_rbtree_debug_spew_helper (tree, tree->root, 0);
1801 #endif /* G_ENABLE_DEBUG */