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)
67 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
69 node->left = (gpointer) 0xdeadbeef;
70 node->right = (gpointer) 0xdeadbeef;
71 node->parent = (gpointer) 0xdeadbeef;
72 node->total_count = 56789;
77 g_slice_free (GtkRBNode, node);
81 _gtk_rbnode_rotate_left (GtkRBTree *tree,
84 gint node_height, right_height;
85 GtkRBNode *right = node->right;
87 g_return_if_fail (node != tree->nil);
89 node_height = node->offset -
90 (node->left?node->left->offset:0) -
91 (node->right?node->right->offset:0) -
92 (node->children?node->children->root->offset:0);
93 right_height = right->offset -
94 (right->left?right->left->offset:0) -
95 (right->right?right->right->offset:0) -
96 (right->children?right->children->root->offset:0);
97 node->right = right->left;
98 if (right->left != tree->nil)
99 right->left->parent = node;
101 if (right != tree->nil)
102 right->parent = node->parent;
103 if (node->parent != tree->nil)
105 if (node == node->parent->left)
106 node->parent->left = right;
108 node->parent->right = right;
114 if (node != tree->nil)
115 node->parent = right;
117 node->count = 1 + (node->left?node->left->count:0) +
118 (node->right?node->right->count:0);
119 right->count = 1 + (right->left?right->left->count:0) +
120 (right->right?right->right->count:0);
122 node->offset = node_height +
123 (node->left?node->left->offset:0) +
124 (node->right?node->right->offset:0) +
125 (node->children?node->children->root->offset:0);
126 right->offset = right_height +
127 (right->left?right->left->offset:0) +
128 (right->right?right->right->offset:0) +
129 (right->children?right->children->root->offset:0);
131 _fixup_validation (tree, node);
132 _fixup_validation (tree, right);
133 _fixup_total_count (tree, node);
134 _fixup_total_count (tree, right);
138 _gtk_rbnode_rotate_right (GtkRBTree *tree,
141 gint node_height, left_height;
142 GtkRBNode *left = node->left;
144 g_return_if_fail (node != tree->nil);
146 node_height = node->offset -
147 (node->left?node->left->offset:0) -
148 (node->right?node->right->offset:0) -
149 (node->children?node->children->root->offset:0);
150 left_height = left->offset -
151 (left->left?left->left->offset:0) -
152 (left->right?left->right->offset:0) -
153 (left->children?left->children->root->offset:0);
155 node->left = left->right;
156 if (left->right != tree->nil)
157 left->right->parent = node;
159 if (left != tree->nil)
160 left->parent = node->parent;
161 if (node->parent != tree->nil)
163 if (node == node->parent->right)
164 node->parent->right = left;
166 node->parent->left = left;
173 /* link node and left */
175 if (node != tree->nil)
178 node->count = 1 + (node->left?node->left->count:0) +
179 (node->right?node->right->count:0);
180 left->count = 1 + (left->left?left->left->count:0) +
181 (left->right?left->right->count:0);
183 node->offset = node_height +
184 (node->left?node->left->offset:0) +
185 (node->right?node->right->offset:0) +
186 (node->children?node->children->root->offset:0);
187 left->offset = left_height +
188 (left->left?left->left->offset:0) +
189 (left->right?left->right->offset:0) +
190 (left->children?left->children->root->offset:0);
192 _fixup_validation (tree, node);
193 _fixup_validation (tree, left);
194 _fixup_total_count (tree, node);
195 _fixup_total_count (tree, left);
199 _gtk_rbtree_insert_fixup (GtkRBTree *tree,
203 /* check Red-Black properties */
204 while (node != tree->root && GTK_RBNODE_GET_COLOR (node->parent) == GTK_RBNODE_RED)
206 /* we have a violation */
207 if (node->parent == node->parent->parent->left)
209 GtkRBNode *y = node->parent->parent->right;
210 if (GTK_RBNODE_GET_COLOR (y) == GTK_RBNODE_RED)
212 /* uncle is GTK_RBNODE_RED */
213 GTK_RBNODE_SET_COLOR (node->parent, GTK_RBNODE_BLACK);
214 GTK_RBNODE_SET_COLOR (y, GTK_RBNODE_BLACK);
215 GTK_RBNODE_SET_COLOR (node->parent->parent, GTK_RBNODE_RED);
216 node = node->parent->parent;
220 /* uncle is GTK_RBNODE_BLACK */
221 if (node == node->parent->right)
223 /* make node a left child */
225 _gtk_rbnode_rotate_left (tree, node);
228 /* recolor and rotate */
229 GTK_RBNODE_SET_COLOR (node->parent, GTK_RBNODE_BLACK);
230 GTK_RBNODE_SET_COLOR (node->parent->parent, GTK_RBNODE_RED);
231 _gtk_rbnode_rotate_right(tree, node->parent->parent);
236 /* mirror image of above code */
237 GtkRBNode *y = node->parent->parent->left;
238 if (GTK_RBNODE_GET_COLOR (y) == GTK_RBNODE_RED)
240 /* uncle is GTK_RBNODE_RED */
241 GTK_RBNODE_SET_COLOR (node->parent, GTK_RBNODE_BLACK);
242 GTK_RBNODE_SET_COLOR (y, GTK_RBNODE_BLACK);
243 GTK_RBNODE_SET_COLOR (node->parent->parent, GTK_RBNODE_RED);
244 node = node->parent->parent;
248 /* uncle is GTK_RBNODE_BLACK */
249 if (node == node->parent->left)
252 _gtk_rbnode_rotate_right (tree, node);
254 GTK_RBNODE_SET_COLOR (node->parent, GTK_RBNODE_BLACK);
255 GTK_RBNODE_SET_COLOR (node->parent->parent, GTK_RBNODE_RED);
256 _gtk_rbnode_rotate_left (tree, node->parent->parent);
260 GTK_RBNODE_SET_COLOR (tree->root, GTK_RBNODE_BLACK);
264 _gtk_rbtree_remove_node_fixup (GtkRBTree *tree,
267 while (node != tree->root && GTK_RBNODE_GET_COLOR (node) == GTK_RBNODE_BLACK)
269 if (node == node->parent->left)
271 GtkRBNode *w = node->parent->right;
272 if (GTK_RBNODE_GET_COLOR (w) == GTK_RBNODE_RED)
274 GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_BLACK);
275 GTK_RBNODE_SET_COLOR (node->parent, GTK_RBNODE_RED);
276 _gtk_rbnode_rotate_left (tree, node->parent);
277 w = node->parent->right;
279 if (GTK_RBNODE_GET_COLOR (w->left) == GTK_RBNODE_BLACK && GTK_RBNODE_GET_COLOR (w->right) == GTK_RBNODE_BLACK)
281 GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_RED);
286 if (GTK_RBNODE_GET_COLOR (w->right) == GTK_RBNODE_BLACK)
288 GTK_RBNODE_SET_COLOR (w->left, GTK_RBNODE_BLACK);
289 GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_RED);
290 _gtk_rbnode_rotate_right (tree, w);
291 w = node->parent->right;
293 GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_GET_COLOR (node->parent));
294 GTK_RBNODE_SET_COLOR (node->parent, GTK_RBNODE_BLACK);
295 GTK_RBNODE_SET_COLOR (w->right, GTK_RBNODE_BLACK);
296 _gtk_rbnode_rotate_left (tree, node->parent);
302 GtkRBNode *w = node->parent->left;
303 if (GTK_RBNODE_GET_COLOR (w) == GTK_RBNODE_RED)
305 GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_BLACK);
306 GTK_RBNODE_SET_COLOR (node->parent, GTK_RBNODE_RED);
307 _gtk_rbnode_rotate_right (tree, node->parent);
308 w = node->parent->left;
310 if (GTK_RBNODE_GET_COLOR (w->right) == GTK_RBNODE_BLACK && GTK_RBNODE_GET_COLOR (w->left) == GTK_RBNODE_BLACK)
312 GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_RED);
317 if (GTK_RBNODE_GET_COLOR (w->left) == GTK_RBNODE_BLACK)
319 GTK_RBNODE_SET_COLOR (w->right, GTK_RBNODE_BLACK);
320 GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_RED);
321 _gtk_rbnode_rotate_left (tree, w);
322 w = node->parent->left;
324 GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_GET_COLOR (node->parent));
325 GTK_RBNODE_SET_COLOR (node->parent, GTK_RBNODE_BLACK);
326 GTK_RBNODE_SET_COLOR (w->left, GTK_RBNODE_BLACK);
327 _gtk_rbnode_rotate_right (tree, node->parent);
332 GTK_RBNODE_SET_COLOR (node, GTK_RBNODE_BLACK);
336 _gtk_rbtree_new (void)
340 retval = g_new (GtkRBTree, 1);
341 retval->parent_tree = NULL;
342 retval->parent_node = NULL;
344 retval->nil = g_slice_new (GtkRBNode);
345 retval->nil->left = NULL;
346 retval->nil->right = NULL;
347 retval->nil->parent = NULL;
348 retval->nil->flags = GTK_RBNODE_BLACK;
349 retval->nil->count = 0;
350 retval->nil->offset = 0;
351 retval->nil->total_count = 0;
353 retval->root = retval->nil;
358 _gtk_rbtree_free_helper (GtkRBTree *tree,
363 _gtk_rbtree_free (node->children);
365 _gtk_rbnode_free (node);
369 _gtk_rbtree_free (GtkRBTree *tree)
371 _gtk_rbtree_traverse (tree,
374 _gtk_rbtree_free_helper,
377 if (tree->parent_node &&
378 tree->parent_node->children == tree)
379 tree->parent_node->children = NULL;
380 _gtk_rbnode_free (tree->nil);
385 _gtk_rbtree_remove (GtkRBTree *tree)
390 gint height = tree->root->offset;
391 guint total_count = tree->root->total_count;
393 #ifdef G_ENABLE_DEBUG
394 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
395 _gtk_rbtree_test (G_STRLOC, tree);
398 tmp_tree = tree->parent_tree;
399 tmp_node = tree->parent_node;
401 /* ugly hack to make _fixup_validation work in the first iteration of the
403 GTK_RBNODE_UNSET_FLAG (tree->root, GTK_RBNODE_DESCENDANTS_INVALID);
405 while (tmp_tree && tmp_node && tmp_node != tmp_tree->nil)
407 _fixup_validation (tmp_tree, tmp_node);
408 tmp_node->offset -= height;
409 tmp_node->total_count -= total_count;
411 tmp_node = tmp_node->parent;
412 if (tmp_node == tmp_tree->nil)
414 tmp_node = tmp_tree->parent_node;
415 tmp_tree = tmp_tree->parent_tree;
419 tmp_tree = tree->parent_tree;
420 tmp_node = tree->parent_node;
421 _gtk_rbtree_free (tree);
423 #ifdef G_ENABLE_DEBUG
424 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
425 _gtk_rbtree_test (G_STRLOC, tmp_tree);
431 _gtk_rbtree_insert_after (GtkRBTree *tree,
437 gboolean right = TRUE;
441 #ifdef G_ENABLE_DEBUG
442 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
444 g_print ("\n\n_gtk_rbtree_insert_after: %p\n", current);
445 _gtk_rbtree_debug_spew (tree);
446 _gtk_rbtree_test (G_STRLOC, tree);
448 #endif /* G_ENABLE_DEBUG */
450 if (current != NULL && current->right != tree->nil)
452 current = current->right;
453 while (current->left != tree->nil)
454 current = current->left;
458 node = _gtk_rbnode_new (tree, height);
459 node->parent = (current?current:tree->nil);
461 /* insert node in tree */
465 current->right = node;
467 current->left = node;
468 tmp_node = node->parent;
474 tmp_node = tree->parent_node;
475 tmp_tree = tree->parent_tree;
478 while (tmp_tree && tmp_node && tmp_node != tmp_tree->nil)
480 /* We only want to propagate the count if we are in the tree we
482 if (tmp_tree == tree)
485 tmp_node->total_count += 1;
486 tmp_node->offset += height;
487 tmp_node = tmp_node->parent;
488 if (tmp_node == tmp_tree->nil)
490 tmp_node = tmp_tree->parent_node;
491 tmp_tree = tmp_tree->parent_tree;
496 _gtk_rbtree_node_mark_valid (tree, node);
498 _gtk_rbtree_node_mark_invalid (tree, node);
500 _gtk_rbtree_insert_fixup (tree, node);
502 #ifdef G_ENABLE_DEBUG
503 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
505 g_print ("_gtk_rbtree_insert_after finished...\n");
506 _gtk_rbtree_debug_spew (tree);
508 _gtk_rbtree_test (G_STRLOC, tree);
510 #endif /* G_ENABLE_DEBUG */
516 _gtk_rbtree_insert_before (GtkRBTree *tree,
522 gboolean left = TRUE;
526 #ifdef G_ENABLE_DEBUG
527 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
529 g_print ("\n\n_gtk_rbtree_insert_before: %p\n", current);
530 _gtk_rbtree_debug_spew (tree);
531 _gtk_rbtree_test (G_STRLOC, tree);
533 #endif /* G_ENABLE_DEBUG */
535 if (current != NULL && current->left != tree->nil)
537 current = current->left;
538 while (current->right != tree->nil)
539 current = current->right;
544 node = _gtk_rbnode_new (tree, height);
545 node->parent = (current?current:tree->nil);
547 /* insert node in tree */
551 current->left = node;
553 current->right = node;
554 tmp_node = node->parent;
560 tmp_node = tree->parent_node;
561 tmp_tree = tree->parent_tree;
564 while (tmp_tree && tmp_node && tmp_node != tmp_tree->nil)
566 /* We only want to propagate the count if we are in the tree we
568 if (tmp_tree == tree)
571 tmp_node->total_count += 1;
572 tmp_node->offset += height;
573 tmp_node = tmp_node->parent;
574 if (tmp_node == tmp_tree->nil)
576 tmp_node = tmp_tree->parent_node;
577 tmp_tree = tmp_tree->parent_tree;
582 _gtk_rbtree_node_mark_valid (tree, node);
584 _gtk_rbtree_node_mark_invalid (tree, node);
586 _gtk_rbtree_insert_fixup (tree, node);
588 #ifdef G_ENABLE_DEBUG
589 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
591 g_print ("_gtk_rbtree_insert_before finished...\n");
592 _gtk_rbtree_debug_spew (tree);
594 _gtk_rbtree_test (G_STRLOC, tree);
596 #endif /* G_ENABLE_DEBUG */
602 _gtk_rbtree_find_count (GtkRBTree *tree,
608 while (node != tree->nil && (node->left->count + 1 != count))
610 if (node->left->count >= count)
614 count -= (node->left->count + 1);
618 if (node == tree->nil)
624 _gtk_rbtree_node_set_height (GtkRBTree *tree,
628 gint diff = height - GTK_RBNODE_GET_HEIGHT (node);
629 GtkRBNode *tmp_node = node;
630 GtkRBTree *tmp_tree = tree;
635 while (tmp_tree && tmp_node && tmp_node != tmp_tree->nil)
637 tmp_node->offset += diff;
638 tmp_node = tmp_node->parent;
639 if (tmp_node == tmp_tree->nil)
641 tmp_node = tmp_tree->parent_node;
642 tmp_tree = tmp_tree->parent_tree;
645 #ifdef G_ENABLE_DEBUG
646 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
647 _gtk_rbtree_test (G_STRLOC, tree);
652 _gtk_rbtree_node_mark_invalid (GtkRBTree *tree,
655 if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID))
658 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_INVALID);
661 if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_DESCENDANTS_INVALID))
663 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
665 if (node == tree->nil)
667 node = tree->parent_node;
668 tree = tree->parent_tree;
675 /* Draconian version. */
677 _gtk_rbtree_node_mark_invalid (GtkRBTree *tree,
680 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_INVALID);
683 _fixup_validation (tree, node);
685 if (node == tree->nil)
687 node = tree->parent_node;
688 tree = tree->parent_tree;
696 _gtk_rbtree_node_mark_valid (GtkRBTree *tree,
699 if ((!GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID)) &&
700 (!GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID)))
703 GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_INVALID);
704 GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_COLUMN_INVALID);
708 if ((GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID)) ||
709 (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID)) ||
710 (node->children && GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID)) ||
711 (node->left != tree->nil && GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID)) ||
712 (node->right != tree->nil && GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID)))
715 GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
717 if (node == tree->nil)
719 node = tree->parent_node;
720 tree = tree->parent_tree;
727 /* Draconian version */
729 _gtk_rbtree_node_mark_valid (GtkRBTree *tree,
732 GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_INVALID);
733 GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_COLUMN_INVALID);
737 _fixup_validation (tree, node);
739 if (node == tree->nil)
741 node = tree->parent_node;
742 tree = tree->parent_tree;
748 /* Assume tree is the root node as it doesn't set DESCENDANTS_INVALID above.
751 _gtk_rbtree_column_invalid (GtkRBTree *tree)
760 while (node->left != tree->nil)
765 if (! (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID)))
766 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_COLUMN_INVALID);
767 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
770 _gtk_rbtree_column_invalid (node->children);
772 while ((node = _gtk_rbtree_next (tree, node)) != NULL);
776 _gtk_rbtree_mark_invalid (GtkRBTree *tree)
785 while (node->left != tree->nil)
790 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_INVALID);
791 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
794 _gtk_rbtree_mark_invalid (node->children);
796 while ((node = _gtk_rbtree_next (tree, node)) != NULL);
800 _gtk_rbtree_set_fixed_height (GtkRBTree *tree,
812 while (node->left != tree->nil)
817 if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID))
819 _gtk_rbtree_node_set_height (tree, node, height);
821 _gtk_rbtree_node_mark_valid (tree, node);
825 _gtk_rbtree_set_fixed_height (node->children, height, mark_valid);
827 while ((node = _gtk_rbtree_next (tree, node)) != NULL);
830 typedef struct _GtkRBReorder
841 gtk_rbtree_reorder_sort_func (gconstpointer a,
844 return ((GtkRBReorder *) a)->order - ((GtkRBReorder *) b)->order;
848 gtk_rbtree_reorder_invert_func (gconstpointer a,
851 return ((GtkRBReorder *) a)->invert_order - ((GtkRBReorder *) b)->invert_order;
855 gtk_rbtree_reorder_fixup (GtkRBTree *tree,
858 if (node == tree->nil)
861 node->total_count = 1;
863 if (node->left != tree->nil)
865 gtk_rbtree_reorder_fixup (tree, node->left);
866 node->offset += node->left->offset;
867 node->total_count += node->left->total_count;
869 if (node->right != tree->nil)
871 gtk_rbtree_reorder_fixup (tree, node->right);
872 node->offset += node->right->offset;
873 node->total_count += node->right->total_count;
878 node->offset += node->children->root->offset;
879 node->total_count += node->children->root->total_count;
882 if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID) ||
883 (node->right != tree->nil && GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID)) ||
884 (node->left != tree->nil && GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID)) ||
885 (node->children && GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID)))
886 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
888 GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
891 /* It basically pulls everything out of the tree, rearranges it, and puts it
892 * back together. Our strategy is to keep the old RBTree intact, and just
893 * rearrange the contents. When that is done, we go through and update the
894 * heights. There is probably a more elegant way to write this function. If
895 * anyone wants to spend the time writing it, patches will be accepted.
898 _gtk_rbtree_reorder (GtkRBTree *tree,
902 GtkRBReorder reorder = { NULL };
907 g_return_if_fail (tree != NULL);
908 g_return_if_fail (length > 0);
909 g_return_if_fail (tree->root->count == length);
911 /* Sort the trees values in the new tree. */
912 array = g_array_sized_new (FALSE, FALSE, sizeof (GtkRBReorder), length);
913 for (i = 0; i < length; i++)
915 reorder.order = new_order[i];
916 reorder.invert_order = i;
917 g_array_append_val (array, reorder);
920 g_array_sort(array, gtk_rbtree_reorder_sort_func);
924 while (node && node->left != tree->nil)
927 for (i = 0; i < length; i++)
929 g_assert (node != tree->nil);
930 g_array_index (array, GtkRBReorder, i).children = node->children;
931 g_array_index (array, GtkRBReorder, i).flags = GTK_RBNODE_NON_COLORS & node->flags;
932 g_array_index (array, GtkRBReorder, i).height = GTK_RBNODE_GET_HEIGHT (node);
934 node = _gtk_rbtree_next (tree, node);
937 g_array_sort (array, gtk_rbtree_reorder_invert_func);
941 while (node && node->left != tree->nil)
944 /* Go through the tree and change the values to the new ones. */
945 for (i = 0; i < length; i++)
947 reorder = g_array_index (array, GtkRBReorder, i);
948 node->children = reorder.children;
950 node->children->parent_node = node;
951 node->flags = GTK_RBNODE_GET_COLOR (node) | reorder.flags;
952 /* We temporarily set the height to this. */
953 node->offset = reorder.height;
954 node = _gtk_rbtree_next (tree, node);
956 gtk_rbtree_reorder_fixup (tree, tree->root);
958 g_array_free (array, TRUE);
963 _gtk_rbtree_node_find_offset (GtkRBTree *tree,
970 g_assert (node->left);
972 retval = node->left->offset;
974 while (tree && node && node != tree->nil)
979 /* Add left branch, plus children, iff we came from the right */
980 if (node->right == last)
981 retval += node->offset - node->right->offset;
983 if (node == tree->nil)
985 node = tree->parent_node;
986 tree = tree->parent_tree;
988 /* Add the parent node, plus the left branch. */
990 retval += node->left->offset + GTK_RBNODE_GET_HEIGHT (node);
997 _gtk_rbtree_node_get_index (GtkRBTree *tree,
1004 g_assert (node->left);
1006 retval = node->left->total_count;
1008 while (tree && node && node != tree->nil)
1011 node = node->parent;
1013 /* Add left branch, plus children, iff we came from the right */
1014 if (node->right == last)
1015 retval += node->total_count - node->right->total_count;
1017 if (node == tree->nil)
1019 node = tree->parent_node;
1020 tree = tree->parent_tree;
1022 /* Add the parent node, plus the left branch. */
1024 retval += node->left->total_count + 1; /* 1 == GTK_RBNODE_GET_PARITY() */
1032 _gtk_rbtree_real_find_offset (GtkRBTree *tree,
1034 GtkRBTree **new_tree,
1035 GtkRBNode **new_node)
1037 GtkRBNode *tmp_node;
1050 tmp_node = tree->root;
1051 while (tmp_node != tree->nil &&
1052 (tmp_node->left->offset > height ||
1053 (tmp_node->offset - tmp_node->right->offset) < height))
1055 if (tmp_node->left->offset > height)
1056 tmp_node = tmp_node->left;
1059 height -= (tmp_node->offset - tmp_node->right->offset);
1060 tmp_node = tmp_node->right;
1063 if (tmp_node == tree->nil)
1069 if (tmp_node->children)
1071 if ((tmp_node->offset -
1072 tmp_node->right->offset -
1073 tmp_node->children->root->offset) > height)
1076 *new_node = tmp_node;
1077 return (height - tmp_node->left->offset);
1079 return _gtk_rbtree_real_find_offset (tmp_node->children,
1080 height - tmp_node->left->offset -
1082 tmp_node->left->offset -
1083 tmp_node->right->offset -
1084 tmp_node->children->root->offset),
1089 *new_node = tmp_node;
1090 return (height - tmp_node->left->offset);
1094 _gtk_rbtree_find_offset (GtkRBTree *tree,
1096 GtkRBTree **new_tree,
1097 GtkRBNode **new_node)
1102 (height >= tree->root->offset))
1109 return _gtk_rbtree_real_find_offset (tree, height, new_tree, new_node);
1113 _gtk_rbtree_find_index (GtkRBTree *tree,
1115 GtkRBTree **new_tree,
1116 GtkRBNode **new_node)
1118 GtkRBNode *tmp_node;
1122 tmp_node = tree->root;
1123 while (tmp_node != tree->nil)
1125 if (tmp_node->left->total_count > index)
1127 tmp_node = tmp_node->left;
1129 else if (tmp_node->total_count - tmp_node->right->total_count <= index)
1131 index -= tmp_node->total_count - tmp_node->right->total_count;
1132 tmp_node = tmp_node->right;
1136 index -= tmp_node->left->total_count;
1140 if (tmp_node == tree->nil)
1149 g_assert (tmp_node->children);
1151 return _gtk_rbtree_find_index (tmp_node->children,
1158 *new_node = tmp_node;
1163 _gtk_rbtree_remove_node (GtkRBTree *tree,
1167 GtkRBTree *tmp_tree;
1168 GtkRBNode *tmp_node;
1171 g_return_if_fail (tree != NULL);
1172 g_return_if_fail (node != NULL);
1175 #ifdef G_ENABLE_DEBUG
1176 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
1178 g_print ("\n\n_gtk_rbtree_remove_node: %p\n", node);
1179 _gtk_rbtree_debug_spew (tree);
1180 _gtk_rbtree_test (G_STRLOC, tree);
1182 #endif /* G_ENABLE_DEBUG */
1184 /* make sure we're deleting a node that's actually in the tree */
1185 for (x = node; x->parent != tree->nil; x = x->parent)
1187 g_return_if_fail (x == tree->root);
1189 #ifdef G_ENABLE_DEBUG
1190 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
1191 _gtk_rbtree_test (G_STRLOC, tree);
1194 if (node->left == tree->nil || node->right == tree->nil)
1202 while (y->left != tree->nil)
1206 /* adjust count only beneath tree */
1207 for (x = y; x != tree->nil; x = x->parent)
1212 /* offsets and total count adjust all the way up through parent trees */
1213 y_height = GTK_RBNODE_GET_HEIGHT (y);
1217 while (tmp_tree && tmp_node && tmp_node != tmp_tree->nil)
1219 tmp_node->offset -= (y_height + (y->children?y->children->root->offset:0));
1220 _fixup_validation (tmp_tree, tmp_node);
1221 _fixup_total_count (tmp_tree, tmp_node);
1222 tmp_node = tmp_node->parent;
1223 if (tmp_node == tmp_tree->nil)
1225 tmp_node = tmp_tree->parent_node;
1226 tmp_tree = tmp_tree->parent_tree;
1230 /* x is y's only child, or nil */
1231 if (y->left != tree->nil)
1236 /* remove y from the parent chain */
1237 x->parent = y->parent;
1238 if (y->parent != tree->nil)
1240 if (y == y->parent->left)
1241 y->parent->left = x;
1243 y->parent->right = x;
1250 /* We need to clean up the validity of the tree.
1257 /* We skip the first time, iff x is nil */
1258 if (tmp_node != tmp_tree->nil)
1260 _fixup_validation (tmp_tree, tmp_node);
1261 _fixup_total_count (tmp_tree, tmp_node);
1263 tmp_node = tmp_node->parent;
1264 if (tmp_node == tmp_tree->nil)
1266 tmp_node = tmp_tree->parent_node;
1267 tmp_tree = tmp_tree->parent_tree;
1270 while (tmp_tree != NULL);
1276 /* Copy the node over */
1277 if (GTK_RBNODE_GET_COLOR (node) == GTK_RBNODE_BLACK)
1278 node->flags = ((y->flags & (GTK_RBNODE_NON_COLORS)) | GTK_RBNODE_BLACK);
1280 node->flags = ((y->flags & (GTK_RBNODE_NON_COLORS)) | GTK_RBNODE_RED);
1281 node->children = y->children;
1284 node->children = y->children;
1285 node->children->parent_node = node;
1289 node->children = NULL;
1291 _fixup_validation (tree, node);
1292 _fixup_total_count (tree, node);
1293 /* We want to see how different our height is from the previous node.
1294 * To do this, we compare our current height with our supposed height.
1296 diff = y_height - GTK_RBNODE_GET_HEIGHT (node);
1300 while (tmp_tree && tmp_node && tmp_node != tmp_tree->nil)
1302 tmp_node->offset += diff;
1303 _fixup_validation (tmp_tree, tmp_node);
1304 _fixup_total_count (tmp_tree, tmp_node);
1305 tmp_node = tmp_node->parent;
1306 if (tmp_node == tmp_tree->nil)
1308 tmp_node = tmp_tree->parent_node;
1309 tmp_tree = tmp_tree->parent_tree;
1314 if (GTK_RBNODE_GET_COLOR (y) == GTK_RBNODE_BLACK)
1315 _gtk_rbtree_remove_node_fixup (tree, x);
1316 _gtk_rbnode_free (y);
1318 #ifdef G_ENABLE_DEBUG
1319 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
1321 g_print ("_gtk_rbtree_remove_node finished...\n");
1322 _gtk_rbtree_debug_spew (tree);
1324 _gtk_rbtree_test (G_STRLOC, tree);
1326 #endif /* G_ENABLE_DEBUG */
1330 _gtk_rbtree_next (GtkRBTree *tree,
1333 g_return_val_if_fail (tree != NULL, NULL);
1334 g_return_val_if_fail (node != NULL, NULL);
1336 /* Case 1: the node's below us. */
1337 if (node->right != tree->nil)
1340 while (node->left != tree->nil)
1345 /* Case 2: it's an ancestor */
1346 while (node->parent != tree->nil)
1348 if (node->parent->right == node)
1349 node = node->parent;
1351 return (node->parent);
1354 /* Case 3: There is no next node */
1359 _gtk_rbtree_prev (GtkRBTree *tree,
1362 g_return_val_if_fail (tree != NULL, NULL);
1363 g_return_val_if_fail (node != NULL, NULL);
1365 /* Case 1: the node's below us. */
1366 if (node->left != tree->nil)
1369 while (node->right != tree->nil)
1374 /* Case 2: it's an ancestor */
1375 while (node->parent != tree->nil)
1377 if (node->parent->left == node)
1378 node = node->parent;
1380 return (node->parent);
1383 /* Case 3: There is no next node */
1388 _gtk_rbtree_next_full (GtkRBTree *tree,
1390 GtkRBTree **new_tree,
1391 GtkRBNode **new_node)
1393 g_return_if_fail (tree != NULL);
1394 g_return_if_fail (node != NULL);
1395 g_return_if_fail (new_tree != NULL);
1396 g_return_if_fail (new_node != NULL);
1400 *new_tree = node->children;
1401 *new_node = (*new_tree)->root;
1402 while ((*new_node)->left != (*new_tree)->nil)
1403 *new_node = (*new_node)->left;
1408 *new_node = _gtk_rbtree_next (tree, node);
1410 while ((*new_node == NULL) &&
1411 (*new_tree != NULL))
1413 *new_node = (*new_tree)->parent_node;
1414 *new_tree = (*new_tree)->parent_tree;
1416 *new_node = _gtk_rbtree_next (*new_tree, *new_node);
1421 _gtk_rbtree_prev_full (GtkRBTree *tree,
1423 GtkRBTree **new_tree,
1424 GtkRBNode **new_node)
1426 g_return_if_fail (tree != NULL);
1427 g_return_if_fail (node != NULL);
1428 g_return_if_fail (new_tree != NULL);
1429 g_return_if_fail (new_node != NULL);
1432 *new_node = _gtk_rbtree_prev (tree, node);
1434 if (*new_node == NULL)
1436 *new_node = (*new_tree)->parent_node;
1437 *new_tree = (*new_tree)->parent_tree;
1441 while ((*new_node)->children)
1443 *new_tree = (*new_node)->children;
1444 *new_node = (*new_tree)->root;
1445 while ((*new_node)->right != (*new_tree)->nil)
1446 *new_node = (*new_node)->right;
1452 _gtk_rbtree_get_depth (GtkRBTree *tree)
1454 GtkRBTree *tmp_tree;
1457 tmp_tree = tree->parent_tree;
1461 tmp_tree = tmp_tree->parent_tree;
1468 _gtk_rbtree_traverse_pre_order (GtkRBTree *tree,
1470 GtkRBTreeTraverseFunc func,
1473 if (node == tree->nil)
1476 (* func) (tree, node, data);
1477 _gtk_rbtree_traverse_pre_order (tree, node->left, func, data);
1478 _gtk_rbtree_traverse_pre_order (tree, node->right, func, data);
1482 _gtk_rbtree_traverse_post_order (GtkRBTree *tree,
1484 GtkRBTreeTraverseFunc func,
1487 if (node == tree->nil)
1490 _gtk_rbtree_traverse_post_order (tree, node->left, func, data);
1491 _gtk_rbtree_traverse_post_order (tree, node->right, func, data);
1492 (* func) (tree, node, data);
1496 _gtk_rbtree_traverse (GtkRBTree *tree,
1498 GTraverseType order,
1499 GtkRBTreeTraverseFunc func,
1502 g_return_if_fail (tree != NULL);
1503 g_return_if_fail (node != NULL);
1504 g_return_if_fail (func != NULL);
1505 g_return_if_fail (order <= G_LEVEL_ORDER);
1510 _gtk_rbtree_traverse_pre_order (tree, node, func, data);
1513 _gtk_rbtree_traverse_post_order (tree, node, func, data);
1518 g_warning ("unsupported traversal order.");
1524 void _fixup_validation (GtkRBTree *tree,
1527 if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID) ||
1528 GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID) ||
1529 (node->left != tree->nil && GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID)) ||
1530 (node->right != tree->nil && GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID)) ||
1531 (node->children != NULL && GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID)))
1533 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
1537 GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
1542 void _fixup_total_count (GtkRBTree *tree,
1545 node->total_count = 1 +
1546 (node->children != NULL ? node->children->root->total_count : 0) +
1547 node->left->total_count + node->right->total_count;
1550 #ifdef G_ENABLE_DEBUG
1552 get_total_count (GtkRBNode *node)
1554 guint child_total = 0;
1556 child_total += (guint) node->left->total_count;
1557 child_total += (guint) node->right->total_count;
1560 child_total += (guint) node->children->root->total_count;
1562 return child_total + 1;
1566 count_total (GtkRBTree *tree,
1571 if (node == tree->nil)
1575 count_total (tree, node->left) +
1576 count_total (tree, node->right) +
1578 (node->children ? count_total (node->children, node->children->root) : 0);
1580 if (res != node->total_count)
1581 g_print ("total count incorrect for node\n");
1583 if (get_total_count (node) != node->total_count)
1584 g_error ("Node has incorrect total count %u, should be %u", node->total_count, get_total_count (node));
1590 _count_nodes (GtkRBTree *tree,
1594 if (node == tree->nil)
1597 g_assert (node->left);
1598 g_assert (node->right);
1600 res = (_count_nodes (tree, node->left) +
1601 _count_nodes (tree, node->right) + 1);
1603 if (res != node->count)
1604 g_print ("Tree failed\n");
1609 _gtk_rbtree_test_height (GtkRBTree *tree,
1612 gint computed_offset = 0;
1614 /* This whole test is sort of a useless truism. */
1616 if (node->left != tree->nil)
1617 computed_offset += node->left->offset;
1619 if (node->right != tree->nil)
1620 computed_offset += node->right->offset;
1622 if (node->children && node->children->root != node->children->nil)
1623 computed_offset += node->children->root->offset;
1625 if (GTK_RBNODE_GET_HEIGHT (node) + computed_offset != node->offset)
1626 g_error ("node has broken offset\n");
1628 if (node->left != tree->nil)
1629 _gtk_rbtree_test_height (tree, node->left);
1631 if (node->right != tree->nil)
1632 _gtk_rbtree_test_height (tree, node->right);
1634 if (node->children && node->children->root != node->children->nil)
1635 _gtk_rbtree_test_height (node->children, node->children->root);
1639 _gtk_rbtree_test_dirty (GtkRBTree *tree,
1641 gint expected_dirtyness)
1644 if (expected_dirtyness)
1646 g_assert (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID) ||
1647 GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID) ||
1648 (node->left != tree->nil && GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID)) ||
1649 (node->right != tree->nil && GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID)) ||
1650 (node->children && GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID)));
1654 g_assert (! GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID) &&
1655 ! GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID));
1656 if (node->left != tree->nil)
1657 g_assert (! GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID));
1658 if (node->right != tree->nil)
1659 g_assert (! GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID));
1660 if (node->children != NULL)
1661 g_assert (! GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID));
1664 if (node->left != tree->nil)
1665 _gtk_rbtree_test_dirty (tree, node->left, GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID));
1666 if (node->right != tree->nil)
1667 _gtk_rbtree_test_dirty (tree, node->right, GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID));
1668 if (node->children != NULL && node->children->root != node->children->nil)
1669 _gtk_rbtree_test_dirty (node->children, node->children->root, GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID));
1672 static void _gtk_rbtree_test_structure (GtkRBTree *tree);
1675 _gtk_rbtree_test_structure_helper (GtkRBTree *tree,
1678 g_assert (node != tree->nil);
1680 g_assert (node->left != NULL);
1681 g_assert (node->right != NULL);
1682 g_assert (node->parent != NULL);
1684 if (node->left != tree->nil)
1686 g_assert (node->left->parent == node);
1687 _gtk_rbtree_test_structure_helper (tree, node->left);
1689 if (node->right != tree->nil)
1691 g_assert (node->right->parent == node);
1692 _gtk_rbtree_test_structure_helper (tree, node->right);
1695 if (node->children != NULL)
1697 g_assert (node->children->parent_tree == tree);
1698 g_assert (node->children->parent_node == node);
1700 _gtk_rbtree_test_structure (node->children);
1704 _gtk_rbtree_test_structure (GtkRBTree *tree)
1706 g_assert (tree->root);
1707 if (tree->root == tree->nil)
1710 g_assert (tree->root->parent == tree->nil);
1711 _gtk_rbtree_test_structure_helper (tree, tree->root);
1715 _gtk_rbtree_test (const gchar *where,
1718 GtkRBTree *tmp_tree;
1723 /* Test the entire tree */
1725 while (tmp_tree->parent_tree)
1726 tmp_tree = tmp_tree->parent_tree;
1728 g_assert (tmp_tree->nil != NULL);
1730 if (tmp_tree->root == tmp_tree->nil)
1733 _gtk_rbtree_test_structure (tmp_tree);
1735 g_assert ((_count_nodes (tmp_tree, tmp_tree->root->left) +
1736 _count_nodes (tmp_tree, tmp_tree->root->right) + 1) == tmp_tree->root->count);
1739 _gtk_rbtree_test_height (tmp_tree, tmp_tree->root);
1740 _gtk_rbtree_test_dirty (tmp_tree, tmp_tree->root, GTK_RBNODE_FLAG_SET (tmp_tree->root, GTK_RBNODE_DESCENDANTS_INVALID));
1741 g_assert (count_total (tmp_tree, tmp_tree->root) == tmp_tree->root->total_count);
1745 _gtk_rbtree_debug_spew_helper (GtkRBTree *tree,
1750 for (i = 0; i < depth; i++)
1753 g_print ("(%p - %s) (Offset %d) (Parity %d) (Validity %d%d%d)\n",
1755 (GTK_RBNODE_GET_COLOR (node) == GTK_RBNODE_BLACK)?"BLACK":" RED ",
1758 (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_DESCENDANTS_INVALID))?1:0,
1759 (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID))?1:0,
1760 (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID))?1:0);
1761 if (node->children != NULL)
1763 g_print ("Looking at child.\n");
1764 _gtk_rbtree_debug_spew (node->children);
1765 g_print ("Done looking at child.\n");
1767 if (node->left != tree->nil)
1769 _gtk_rbtree_debug_spew_helper (tree, node->left, depth+1);
1771 if (node->right != tree->nil)
1773 _gtk_rbtree_debug_spew_helper (tree, node->right, depth+1);
1778 _gtk_rbtree_debug_spew (GtkRBTree *tree)
1780 g_return_if_fail (tree != NULL);
1782 if (tree->root == tree->nil)
1783 g_print ("Empty tree...\n");
1785 _gtk_rbtree_debug_spew_helper (tree, tree->root, 0);
1787 #endif /* G_ENABLE_DEBUG */