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,
36 static inline void _fixup_validation (GtkRBTree *tree,
38 static inline void _fixup_total_count (GtkRBTree *tree,
41 static void _gtk_rbtree_test (const gchar *where,
43 static void _gtk_rbtree_debug_spew (GtkRBTree *tree);
46 static const GtkRBNode nil = {
47 /* .flags = */ GTK_RBNODE_BLACK,
54 _gtk_rbnode_new (GtkRBTree *tree,
57 GtkRBNode *node = g_slice_new (GtkRBNode);
59 node->left = tree->nil;
60 node->right = tree->nil;
61 node->parent = tree->nil;
62 node->flags = GTK_RBNODE_RED;
63 node->total_count = 1;
65 node->children = NULL;
66 node->offset = height;
71 _gtk_rbnode_free (GtkRBNode *node)
74 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
76 node->left = (gpointer) 0xdeadbeef;
77 node->right = (gpointer) 0xdeadbeef;
78 node->parent = (gpointer) 0xdeadbeef;
79 node->total_count = 56789;
85 g_slice_free (GtkRBNode, node);
89 _gtk_rbnode_rotate_left (GtkRBTree *tree,
92 gint node_height, right_height;
93 GtkRBNode *right = node->right;
95 g_return_if_fail (node != tree->nil);
97 node_height = node->offset -
98 (node->left?node->left->offset:0) -
99 (node->right?node->right->offset:0) -
100 (node->children?node->children->root->offset:0);
101 right_height = right->offset -
102 (right->left?right->left->offset:0) -
103 (right->right?right->right->offset:0) -
104 (right->children?right->children->root->offset:0);
105 node->right = right->left;
106 if (right->left != tree->nil)
107 right->left->parent = node;
109 if (right != tree->nil)
110 right->parent = node->parent;
111 if (node->parent != tree->nil)
113 if (node == node->parent->left)
114 node->parent->left = right;
116 node->parent->right = right;
122 if (node != tree->nil)
123 node->parent = right;
125 node->count = 1 + (node->left?node->left->count:0) +
126 (node->right?node->right->count:0);
127 right->count = 1 + (right->left?right->left->count:0) +
128 (right->right?right->right->count:0);
130 node->offset = node_height +
131 (node->left?node->left->offset:0) +
132 (node->right?node->right->offset:0) +
133 (node->children?node->children->root->offset:0);
134 right->offset = right_height +
135 (right->left?right->left->offset:0) +
136 (right->right?right->right->offset:0) +
137 (right->children?right->children->root->offset:0);
139 _fixup_validation (tree, node);
140 _fixup_validation (tree, right);
141 _fixup_total_count (tree, node);
142 _fixup_total_count (tree, right);
146 _gtk_rbnode_rotate_right (GtkRBTree *tree,
149 gint node_height, left_height;
150 GtkRBNode *left = node->left;
152 g_return_if_fail (node != tree->nil);
154 node_height = node->offset -
155 (node->left?node->left->offset:0) -
156 (node->right?node->right->offset:0) -
157 (node->children?node->children->root->offset:0);
158 left_height = left->offset -
159 (left->left?left->left->offset:0) -
160 (left->right?left->right->offset:0) -
161 (left->children?left->children->root->offset:0);
163 node->left = left->right;
164 if (left->right != tree->nil)
165 left->right->parent = node;
167 if (left != tree->nil)
168 left->parent = node->parent;
169 if (node->parent != tree->nil)
171 if (node == node->parent->right)
172 node->parent->right = left;
174 node->parent->left = left;
181 /* link node and left */
183 if (node != tree->nil)
186 node->count = 1 + (node->left?node->left->count:0) +
187 (node->right?node->right->count:0);
188 left->count = 1 + (left->left?left->left->count:0) +
189 (left->right?left->right->count:0);
191 node->offset = node_height +
192 (node->left?node->left->offset:0) +
193 (node->right?node->right->offset:0) +
194 (node->children?node->children->root->offset:0);
195 left->offset = left_height +
196 (left->left?left->left->offset:0) +
197 (left->right?left->right->offset:0) +
198 (left->children?left->children->root->offset:0);
200 _fixup_validation (tree, node);
201 _fixup_validation (tree, left);
202 _fixup_total_count (tree, node);
203 _fixup_total_count (tree, left);
207 _gtk_rbtree_insert_fixup (GtkRBTree *tree,
211 /* check Red-Black properties */
212 while (node != tree->root && GTK_RBNODE_GET_COLOR (node->parent) == GTK_RBNODE_RED)
214 /* we have a violation */
215 if (node->parent == node->parent->parent->left)
217 GtkRBNode *y = node->parent->parent->right;
218 if (GTK_RBNODE_GET_COLOR (y) == GTK_RBNODE_RED)
220 /* uncle is GTK_RBNODE_RED */
221 GTK_RBNODE_SET_COLOR (node->parent, GTK_RBNODE_BLACK);
222 GTK_RBNODE_SET_COLOR (y, GTK_RBNODE_BLACK);
223 GTK_RBNODE_SET_COLOR (node->parent->parent, GTK_RBNODE_RED);
224 node = node->parent->parent;
228 /* uncle is GTK_RBNODE_BLACK */
229 if (node == node->parent->right)
231 /* make node a left child */
233 _gtk_rbnode_rotate_left (tree, node);
236 /* recolor and rotate */
237 GTK_RBNODE_SET_COLOR (node->parent, GTK_RBNODE_BLACK);
238 GTK_RBNODE_SET_COLOR (node->parent->parent, GTK_RBNODE_RED);
239 _gtk_rbnode_rotate_right(tree, node->parent->parent);
244 /* mirror image of above code */
245 GtkRBNode *y = node->parent->parent->left;
246 if (GTK_RBNODE_GET_COLOR (y) == GTK_RBNODE_RED)
248 /* uncle is GTK_RBNODE_RED */
249 GTK_RBNODE_SET_COLOR (node->parent, GTK_RBNODE_BLACK);
250 GTK_RBNODE_SET_COLOR (y, GTK_RBNODE_BLACK);
251 GTK_RBNODE_SET_COLOR (node->parent->parent, GTK_RBNODE_RED);
252 node = node->parent->parent;
256 /* uncle is GTK_RBNODE_BLACK */
257 if (node == node->parent->left)
260 _gtk_rbnode_rotate_right (tree, node);
262 GTK_RBNODE_SET_COLOR (node->parent, GTK_RBNODE_BLACK);
263 GTK_RBNODE_SET_COLOR (node->parent->parent, GTK_RBNODE_RED);
264 _gtk_rbnode_rotate_left (tree, node->parent->parent);
268 GTK_RBNODE_SET_COLOR (tree->root, GTK_RBNODE_BLACK);
272 _gtk_rbtree_remove_node_fixup (GtkRBTree *tree,
276 while (node != tree->root && GTK_RBNODE_GET_COLOR (node) == GTK_RBNODE_BLACK)
278 if (node == parent->left)
280 GtkRBNode *w = parent->right;
281 if (GTK_RBNODE_GET_COLOR (w) == GTK_RBNODE_RED)
283 GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_BLACK);
284 GTK_RBNODE_SET_COLOR (parent, GTK_RBNODE_RED);
285 _gtk_rbnode_rotate_left (tree, parent);
288 if (GTK_RBNODE_GET_COLOR (w->left) == GTK_RBNODE_BLACK && GTK_RBNODE_GET_COLOR (w->right) == GTK_RBNODE_BLACK)
290 GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_RED);
295 if (GTK_RBNODE_GET_COLOR (w->right) == GTK_RBNODE_BLACK)
297 GTK_RBNODE_SET_COLOR (w->left, GTK_RBNODE_BLACK);
298 GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_RED);
299 _gtk_rbnode_rotate_right (tree, w);
302 GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_GET_COLOR (parent));
303 GTK_RBNODE_SET_COLOR (parent, GTK_RBNODE_BLACK);
304 GTK_RBNODE_SET_COLOR (w->right, GTK_RBNODE_BLACK);
305 _gtk_rbnode_rotate_left (tree, parent);
311 GtkRBNode *w = parent->left;
312 if (GTK_RBNODE_GET_COLOR (w) == GTK_RBNODE_RED)
314 GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_BLACK);
315 GTK_RBNODE_SET_COLOR (parent, GTK_RBNODE_RED);
316 _gtk_rbnode_rotate_right (tree, parent);
319 if (GTK_RBNODE_GET_COLOR (w->right) == GTK_RBNODE_BLACK && GTK_RBNODE_GET_COLOR (w->left) == GTK_RBNODE_BLACK)
321 GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_RED);
326 if (GTK_RBNODE_GET_COLOR (w->left) == GTK_RBNODE_BLACK)
328 GTK_RBNODE_SET_COLOR (w->right, GTK_RBNODE_BLACK);
329 GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_RED);
330 _gtk_rbnode_rotate_left (tree, w);
333 GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_GET_COLOR (parent));
334 GTK_RBNODE_SET_COLOR (parent, GTK_RBNODE_BLACK);
335 GTK_RBNODE_SET_COLOR (w->left, GTK_RBNODE_BLACK);
336 _gtk_rbnode_rotate_right (tree, parent);
341 parent = node->parent;
343 GTK_RBNODE_SET_COLOR (node, GTK_RBNODE_BLACK);
347 _gtk_rbtree_new (void)
351 retval = g_new (GtkRBTree, 1);
352 retval->parent_tree = NULL;
353 retval->parent_node = NULL;
355 retval->nil = (GtkRBNode *) &nil;
357 retval->root = retval->nil;
362 _gtk_rbtree_free_helper (GtkRBTree *tree,
367 _gtk_rbtree_free (node->children);
369 _gtk_rbnode_free (node);
373 _gtk_rbtree_free (GtkRBTree *tree)
375 _gtk_rbtree_traverse (tree,
378 _gtk_rbtree_free_helper,
381 if (tree->parent_node &&
382 tree->parent_node->children == tree)
383 tree->parent_node->children = NULL;
388 gtk_rbnode_adjust (GtkRBTree *tree,
391 int total_count_diff,
394 while (tree && node && node != tree->nil)
396 _fixup_validation (tree, node);
397 node->offset += offset_diff;
398 node->count += count_diff;
399 node->total_count += total_count_diff;
402 if (node == tree->nil)
404 node = tree->parent_node;
405 tree = tree->parent_tree;
412 _gtk_rbtree_remove (GtkRBTree *tree)
414 #ifdef G_ENABLE_DEBUG
417 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
418 _gtk_rbtree_test (G_STRLOC, tree);
421 /* ugly hack to make _fixup_validation work in the first iteration of the
423 GTK_RBNODE_UNSET_FLAG (tree->root, GTK_RBNODE_DESCENDANTS_INVALID);
425 gtk_rbnode_adjust (tree->parent_tree,
428 - (int) tree->root->total_count,
429 - tree->root->offset);
431 #ifdef G_ENABLE_DEBUG
432 tmp_tree = tree->parent_tree;
435 _gtk_rbtree_free (tree);
437 #ifdef G_ENABLE_DEBUG
438 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
439 _gtk_rbtree_test (G_STRLOC, tmp_tree);
445 _gtk_rbtree_insert_after (GtkRBTree *tree,
451 gboolean right = TRUE;
453 #ifdef G_ENABLE_DEBUG
454 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
456 g_print ("\n\n_gtk_rbtree_insert_after: %p\n", current);
457 _gtk_rbtree_debug_spew (tree);
458 _gtk_rbtree_test (G_STRLOC, tree);
460 #endif /* G_ENABLE_DEBUG */
462 if (current != NULL && current->right != tree->nil)
464 current = current->right;
465 while (current->left != tree->nil)
466 current = current->left;
470 node = _gtk_rbnode_new (tree, height);
471 node->parent = (current?current:tree->nil);
473 /* insert node in tree */
477 current->right = node;
479 current->left = node;
480 gtk_rbnode_adjust (tree, node->parent,
485 g_assert (tree->root == tree->nil);
487 gtk_rbnode_adjust (tree->parent_tree, tree->parent_node,
492 _gtk_rbtree_node_mark_valid (tree, node);
494 _gtk_rbtree_node_mark_invalid (tree, node);
496 _gtk_rbtree_insert_fixup (tree, node);
498 #ifdef G_ENABLE_DEBUG
499 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
501 g_print ("_gtk_rbtree_insert_after finished...\n");
502 _gtk_rbtree_debug_spew (tree);
504 _gtk_rbtree_test (G_STRLOC, tree);
506 #endif /* G_ENABLE_DEBUG */
512 _gtk_rbtree_insert_before (GtkRBTree *tree,
518 gboolean left = TRUE;
520 #ifdef G_ENABLE_DEBUG
521 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
523 g_print ("\n\n_gtk_rbtree_insert_before: %p\n", current);
524 _gtk_rbtree_debug_spew (tree);
525 _gtk_rbtree_test (G_STRLOC, tree);
527 #endif /* G_ENABLE_DEBUG */
529 if (current != NULL && current->left != tree->nil)
531 current = current->left;
532 while (current->right != tree->nil)
533 current = current->right;
538 node = _gtk_rbnode_new (tree, height);
539 node->parent = (current?current:tree->nil);
541 /* insert node in tree */
545 current->left = node;
547 current->right = node;
548 gtk_rbnode_adjust (tree, node->parent,
553 g_assert (tree->root == tree->nil);
555 gtk_rbnode_adjust (tree->parent_tree, tree->parent_node,
560 _gtk_rbtree_node_mark_valid (tree, node);
562 _gtk_rbtree_node_mark_invalid (tree, node);
564 _gtk_rbtree_insert_fixup (tree, node);
566 #ifdef G_ENABLE_DEBUG
567 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
569 g_print ("_gtk_rbtree_insert_before finished...\n");
570 _gtk_rbtree_debug_spew (tree);
572 _gtk_rbtree_test (G_STRLOC, tree);
574 #endif /* G_ENABLE_DEBUG */
580 _gtk_rbtree_find_count (GtkRBTree *tree,
586 while (node != tree->nil && (node->left->count + 1 != count))
588 if (node->left->count >= count)
592 count -= (node->left->count + 1);
596 if (node == tree->nil)
602 _gtk_rbtree_node_set_height (GtkRBTree *tree,
606 gint diff = height - GTK_RBNODE_GET_HEIGHT (node);
611 gtk_rbnode_adjust (tree, node, 0, 0, diff);
613 #ifdef G_ENABLE_DEBUG
614 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
615 _gtk_rbtree_test (G_STRLOC, tree);
620 _gtk_rbtree_node_mark_invalid (GtkRBTree *tree,
623 if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID))
626 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_INVALID);
629 if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_DESCENDANTS_INVALID))
631 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
633 if (node == tree->nil)
635 node = tree->parent_node;
636 tree = tree->parent_tree;
643 /* Draconian version. */
645 _gtk_rbtree_node_mark_invalid (GtkRBTree *tree,
648 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_INVALID);
651 _fixup_validation (tree, node);
653 if (node == tree->nil)
655 node = tree->parent_node;
656 tree = tree->parent_tree;
664 _gtk_rbtree_node_mark_valid (GtkRBTree *tree,
667 if ((!GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID)) &&
668 (!GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID)))
671 GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_INVALID);
672 GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_COLUMN_INVALID);
676 if ((GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID)) ||
677 (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID)) ||
678 (node->children && GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID)) ||
679 (node->left != tree->nil && GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID)) ||
680 (node->right != tree->nil && GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID)))
683 GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
685 if (node == tree->nil)
687 node = tree->parent_node;
688 tree = tree->parent_tree;
695 /* Draconian version */
697 _gtk_rbtree_node_mark_valid (GtkRBTree *tree,
700 GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_INVALID);
701 GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_COLUMN_INVALID);
705 _fixup_validation (tree, node);
707 if (node == tree->nil)
709 node = tree->parent_node;
710 tree = tree->parent_tree;
716 /* Assume tree is the root node as it doesn't set DESCENDANTS_INVALID above.
719 _gtk_rbtree_column_invalid (GtkRBTree *tree)
726 node = _gtk_rbtree_first (tree);
730 if (! (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID)))
731 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_COLUMN_INVALID);
732 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
735 _gtk_rbtree_column_invalid (node->children);
737 while ((node = _gtk_rbtree_next (tree, node)) != NULL);
741 _gtk_rbtree_mark_invalid (GtkRBTree *tree)
748 node = _gtk_rbtree_first (tree);
752 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_INVALID);
753 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
756 _gtk_rbtree_mark_invalid (node->children);
758 while ((node = _gtk_rbtree_next (tree, node)) != NULL);
762 _gtk_rbtree_set_fixed_height (GtkRBTree *tree,
771 node = _gtk_rbtree_first (tree);
775 if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID))
777 _gtk_rbtree_node_set_height (tree, node, height);
779 _gtk_rbtree_node_mark_valid (tree, node);
783 _gtk_rbtree_set_fixed_height (node->children, height, mark_valid);
785 while ((node = _gtk_rbtree_next (tree, node)) != NULL);
788 typedef struct _GtkRBReorder
799 gtk_rbtree_reorder_sort_func (gconstpointer a,
802 return ((GtkRBReorder *) a)->order - ((GtkRBReorder *) b)->order;
806 gtk_rbtree_reorder_invert_func (gconstpointer a,
809 return ((GtkRBReorder *) a)->invert_order - ((GtkRBReorder *) b)->invert_order;
813 gtk_rbtree_reorder_fixup (GtkRBTree *tree,
816 if (node == tree->nil)
819 node->total_count = 1;
821 if (node->left != tree->nil)
823 gtk_rbtree_reorder_fixup (tree, node->left);
824 node->offset += node->left->offset;
825 node->total_count += node->left->total_count;
827 if (node->right != tree->nil)
829 gtk_rbtree_reorder_fixup (tree, node->right);
830 node->offset += node->right->offset;
831 node->total_count += node->right->total_count;
836 node->offset += node->children->root->offset;
837 node->total_count += node->children->root->total_count;
840 if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID) ||
841 (node->right != tree->nil && GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID)) ||
842 (node->left != tree->nil && GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID)) ||
843 (node->children && GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID)))
844 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
846 GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
849 /* It basically pulls everything out of the tree, rearranges it, and puts it
850 * back together. Our strategy is to keep the old RBTree intact, and just
851 * rearrange the contents. When that is done, we go through and update the
852 * heights. There is probably a more elegant way to write this function. If
853 * anyone wants to spend the time writing it, patches will be accepted.
856 _gtk_rbtree_reorder (GtkRBTree *tree,
860 GtkRBReorder reorder = { NULL };
865 g_return_if_fail (tree != NULL);
866 g_return_if_fail (length > 0);
867 g_return_if_fail (tree->root->count == length);
869 /* Sort the trees values in the new tree. */
870 array = g_array_sized_new (FALSE, FALSE, sizeof (GtkRBReorder), length);
871 for (i = 0; i < length; i++)
873 reorder.order = new_order[i];
874 reorder.invert_order = i;
875 g_array_append_val (array, reorder);
878 g_array_sort(array, gtk_rbtree_reorder_sort_func);
881 node = _gtk_rbtree_first (tree);
883 for (i = 0; i < length; i++)
885 g_assert (node != tree->nil);
886 g_array_index (array, GtkRBReorder, i).children = node->children;
887 g_array_index (array, GtkRBReorder, i).flags = GTK_RBNODE_NON_COLORS & node->flags;
888 g_array_index (array, GtkRBReorder, i).height = GTK_RBNODE_GET_HEIGHT (node);
890 node = _gtk_rbtree_next (tree, node);
893 g_array_sort (array, gtk_rbtree_reorder_invert_func);
896 node = _gtk_rbtree_first (tree);
898 /* Go through the tree and change the values to the new ones. */
899 for (i = 0; i < length; i++)
901 reorder = g_array_index (array, GtkRBReorder, i);
902 node->children = reorder.children;
904 node->children->parent_node = node;
905 node->flags = GTK_RBNODE_GET_COLOR (node) | reorder.flags;
906 /* We temporarily set the height to this. */
907 node->offset = reorder.height;
908 node = _gtk_rbtree_next (tree, node);
910 gtk_rbtree_reorder_fixup (tree, tree->root);
912 g_array_free (array, TRUE);
917 _gtk_rbtree_node_find_offset (GtkRBTree *tree,
924 g_assert (node->left);
926 retval = node->left->offset;
928 while (tree && node && node != tree->nil)
933 /* Add left branch, plus children, iff we came from the right */
934 if (node->right == last)
935 retval += node->offset - node->right->offset;
937 if (node == tree->nil)
939 node = tree->parent_node;
940 tree = tree->parent_tree;
942 /* Add the parent node, plus the left branch. */
944 retval += node->left->offset + GTK_RBNODE_GET_HEIGHT (node);
951 _gtk_rbtree_node_get_index (GtkRBTree *tree,
958 g_assert (node->left);
960 retval = node->left->total_count;
962 while (tree && node && node != tree->nil)
967 /* Add left branch, plus children, iff we came from the right */
968 if (node->right == last)
969 retval += node->total_count - node->right->total_count;
971 if (node == tree->nil)
973 node = tree->parent_node;
974 tree = tree->parent_tree;
976 /* Add the parent node, plus the left branch. */
978 retval += node->left->total_count + 1; /* 1 == GTK_RBNODE_GET_PARITY() */
986 _gtk_rbtree_real_find_offset (GtkRBTree *tree,
988 GtkRBTree **new_tree,
989 GtkRBNode **new_node)
1004 tmp_node = tree->root;
1005 while (tmp_node != tree->nil &&
1006 (tmp_node->left->offset > height ||
1007 (tmp_node->offset - tmp_node->right->offset) < height))
1009 if (tmp_node->left->offset > height)
1010 tmp_node = tmp_node->left;
1013 height -= (tmp_node->offset - tmp_node->right->offset);
1014 tmp_node = tmp_node->right;
1017 if (tmp_node == tree->nil)
1023 if (tmp_node->children)
1025 if ((tmp_node->offset -
1026 tmp_node->right->offset -
1027 tmp_node->children->root->offset) > height)
1030 *new_node = tmp_node;
1031 return (height - tmp_node->left->offset);
1033 return _gtk_rbtree_real_find_offset (tmp_node->children,
1034 height - tmp_node->left->offset -
1036 tmp_node->left->offset -
1037 tmp_node->right->offset -
1038 tmp_node->children->root->offset),
1043 *new_node = tmp_node;
1044 return (height - tmp_node->left->offset);
1048 _gtk_rbtree_find_offset (GtkRBTree *tree,
1050 GtkRBTree **new_tree,
1051 GtkRBNode **new_node)
1056 (height >= tree->root->offset))
1063 return _gtk_rbtree_real_find_offset (tree, height, new_tree, new_node);
1067 _gtk_rbtree_find_index (GtkRBTree *tree,
1069 GtkRBTree **new_tree,
1070 GtkRBNode **new_node)
1072 GtkRBNode *tmp_node;
1076 tmp_node = tree->root;
1077 while (tmp_node != tree->nil)
1079 if (tmp_node->left->total_count > index)
1081 tmp_node = tmp_node->left;
1083 else if (tmp_node->total_count - tmp_node->right->total_count <= index)
1085 index -= tmp_node->total_count - tmp_node->right->total_count;
1086 tmp_node = tmp_node->right;
1090 index -= tmp_node->left->total_count;
1094 if (tmp_node == tree->nil)
1103 g_assert (tmp_node->children);
1105 return _gtk_rbtree_find_index (tmp_node->children,
1112 *new_node = tmp_node;
1117 _gtk_rbtree_remove_node (GtkRBTree *tree,
1122 guint y_total_count;
1124 g_return_if_fail (tree != NULL);
1125 g_return_if_fail (node != NULL);
1128 #ifdef G_ENABLE_DEBUG
1129 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
1131 g_print ("\n\n_gtk_rbtree_remove_node: %p\n", node);
1132 _gtk_rbtree_debug_spew (tree);
1133 _gtk_rbtree_test (G_STRLOC, tree);
1135 #endif /* G_ENABLE_DEBUG */
1137 /* make sure we're deleting a node that's actually in the tree */
1138 for (x = node; x->parent != tree->nil; x = x->parent)
1140 g_return_if_fail (x == tree->root);
1142 #ifdef G_ENABLE_DEBUG
1143 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
1144 _gtk_rbtree_test (G_STRLOC, tree);
1147 if (node->left == tree->nil || node->right == tree->nil)
1155 while (y->left != tree->nil)
1159 y_height = GTK_RBNODE_GET_HEIGHT (y)
1160 + (y->children ? y->children->root->offset : 0);
1161 y_total_count = 1 + (y->children ? y->children->root->total_count : 0);
1163 /* x is y's only child, or nil */
1164 if (y->left != tree->nil)
1169 /* remove y from the parent chain */
1171 x->parent = y->parent;
1172 if (y->parent != tree->nil)
1174 if (y == y->parent->left)
1175 y->parent->left = x;
1177 y->parent->right = x;
1184 /* We need to clean up the validity of the tree.
1186 gtk_rbnode_adjust (tree, y, -1, - y_total_count, - y_height);
1188 if (GTK_RBNODE_GET_COLOR (y) == GTK_RBNODE_BLACK)
1189 _gtk_rbtree_remove_node_fixup (tree, x, y->parent);
1193 gint node_height, node_total_count;
1195 /* We want to see how much we remove from the aggregate values.
1196 * This is all the children we remove plus the node's values.
1198 node_height = GTK_RBNODE_GET_HEIGHT (node)
1199 + (node->children ? node->children->root->offset : 0);
1200 node_total_count = 1
1201 + (node->children ? node->children->root->total_count : 0);
1203 /* Move the node over */
1204 if (GTK_RBNODE_GET_COLOR (node) != GTK_RBNODE_GET_COLOR (y))
1205 y->flags ^= (GTK_RBNODE_BLACK | GTK_RBNODE_RED);
1207 y->left = node->left;
1208 if (y->left != tree->nil)
1209 y->left->parent = y;
1210 y->right = node->right;
1211 if (y->right != tree->nil)
1212 y->right->parent = y;
1213 y->parent = node->parent;
1214 if (y->parent != tree->nil)
1216 if (y->parent->left == node)
1217 y->parent->left = y;
1219 y->parent->right = y;
1225 y->count = node->count;
1226 y->total_count = node->total_count;
1227 y->offset = node->offset;
1229 gtk_rbnode_adjust (tree, y,
1231 y_total_count - node_total_count,
1232 y_height - node_height);
1235 _gtk_rbnode_free (node);
1237 #ifdef G_ENABLE_DEBUG
1238 if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
1240 g_print ("_gtk_rbtree_remove_node finished...\n");
1241 _gtk_rbtree_debug_spew (tree);
1243 _gtk_rbtree_test (G_STRLOC, tree);
1245 #endif /* G_ENABLE_DEBUG */
1249 _gtk_rbtree_first (GtkRBTree *tree)
1255 if (node == tree->nil)
1258 while (node->left != tree->nil)
1265 _gtk_rbtree_next (GtkRBTree *tree,
1268 g_return_val_if_fail (tree != NULL, NULL);
1269 g_return_val_if_fail (node != NULL, NULL);
1271 /* Case 1: the node's below us. */
1272 if (node->right != tree->nil)
1275 while (node->left != tree->nil)
1280 /* Case 2: it's an ancestor */
1281 while (node->parent != tree->nil)
1283 if (node->parent->right == node)
1284 node = node->parent;
1286 return (node->parent);
1289 /* Case 3: There is no next node */
1294 _gtk_rbtree_prev (GtkRBTree *tree,
1297 g_return_val_if_fail (tree != NULL, NULL);
1298 g_return_val_if_fail (node != NULL, NULL);
1300 /* Case 1: the node's below us. */
1301 if (node->left != tree->nil)
1304 while (node->right != tree->nil)
1309 /* Case 2: it's an ancestor */
1310 while (node->parent != tree->nil)
1312 if (node->parent->left == node)
1313 node = node->parent;
1315 return (node->parent);
1318 /* Case 3: There is no next node */
1323 _gtk_rbtree_next_full (GtkRBTree *tree,
1325 GtkRBTree **new_tree,
1326 GtkRBNode **new_node)
1328 g_return_if_fail (tree != NULL);
1329 g_return_if_fail (node != NULL);
1330 g_return_if_fail (new_tree != NULL);
1331 g_return_if_fail (new_node != NULL);
1335 *new_tree = node->children;
1336 *new_node = (*new_tree)->root;
1337 while ((*new_node)->left != (*new_tree)->nil)
1338 *new_node = (*new_node)->left;
1343 *new_node = _gtk_rbtree_next (tree, node);
1345 while ((*new_node == NULL) &&
1346 (*new_tree != NULL))
1348 *new_node = (*new_tree)->parent_node;
1349 *new_tree = (*new_tree)->parent_tree;
1351 *new_node = _gtk_rbtree_next (*new_tree, *new_node);
1356 _gtk_rbtree_prev_full (GtkRBTree *tree,
1358 GtkRBTree **new_tree,
1359 GtkRBNode **new_node)
1361 g_return_if_fail (tree != NULL);
1362 g_return_if_fail (node != NULL);
1363 g_return_if_fail (new_tree != NULL);
1364 g_return_if_fail (new_node != NULL);
1367 *new_node = _gtk_rbtree_prev (tree, node);
1369 if (*new_node == NULL)
1371 *new_node = (*new_tree)->parent_node;
1372 *new_tree = (*new_tree)->parent_tree;
1376 while ((*new_node)->children)
1378 *new_tree = (*new_node)->children;
1379 *new_node = (*new_tree)->root;
1380 while ((*new_node)->right != (*new_tree)->nil)
1381 *new_node = (*new_node)->right;
1387 _gtk_rbtree_get_depth (GtkRBTree *tree)
1389 GtkRBTree *tmp_tree;
1392 tmp_tree = tree->parent_tree;
1396 tmp_tree = tmp_tree->parent_tree;
1403 _gtk_rbtree_traverse_pre_order (GtkRBTree *tree,
1405 GtkRBTreeTraverseFunc func,
1408 if (node == tree->nil)
1411 (* func) (tree, node, data);
1412 _gtk_rbtree_traverse_pre_order (tree, node->left, func, data);
1413 _gtk_rbtree_traverse_pre_order (tree, node->right, func, data);
1417 _gtk_rbtree_traverse_post_order (GtkRBTree *tree,
1419 GtkRBTreeTraverseFunc func,
1422 if (node == tree->nil)
1425 _gtk_rbtree_traverse_post_order (tree, node->left, func, data);
1426 _gtk_rbtree_traverse_post_order (tree, node->right, func, data);
1427 (* func) (tree, node, data);
1431 _gtk_rbtree_traverse (GtkRBTree *tree,
1433 GTraverseType order,
1434 GtkRBTreeTraverseFunc func,
1437 g_return_if_fail (tree != NULL);
1438 g_return_if_fail (node != NULL);
1439 g_return_if_fail (func != NULL);
1440 g_return_if_fail (order <= G_LEVEL_ORDER);
1445 _gtk_rbtree_traverse_pre_order (tree, node, func, data);
1448 _gtk_rbtree_traverse_post_order (tree, node, func, data);
1453 g_warning ("unsupported traversal order.");
1459 void _fixup_validation (GtkRBTree *tree,
1462 if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID) ||
1463 GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID) ||
1464 (node->left != tree->nil && GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID)) ||
1465 (node->right != tree->nil && GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID)) ||
1466 (node->children != NULL && GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID)))
1468 GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
1472 GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
1477 void _fixup_total_count (GtkRBTree *tree,
1480 node->total_count = 1 +
1481 (node->children != NULL ? node->children->root->total_count : 0) +
1482 node->left->total_count + node->right->total_count;
1485 #ifdef G_ENABLE_DEBUG
1487 get_total_count (GtkRBNode *node)
1489 guint child_total = 0;
1491 child_total += (guint) node->left->total_count;
1492 child_total += (guint) node->right->total_count;
1495 child_total += (guint) node->children->root->total_count;
1497 return child_total + 1;
1501 count_total (GtkRBTree *tree,
1506 if (node == tree->nil)
1510 count_total (tree, node->left) +
1511 count_total (tree, node->right) +
1513 (node->children ? count_total (node->children, node->children->root) : 0);
1515 if (res != node->total_count)
1516 g_print ("total count incorrect for node\n");
1518 if (get_total_count (node) != node->total_count)
1519 g_error ("Node has incorrect total count %u, should be %u", node->total_count, get_total_count (node));
1525 _count_nodes (GtkRBTree *tree,
1529 if (node == tree->nil)
1532 g_assert (node->left);
1533 g_assert (node->right);
1535 res = (_count_nodes (tree, node->left) +
1536 _count_nodes (tree, node->right) + 1);
1538 if (res != node->count)
1539 g_print ("Tree failed\n");
1544 _gtk_rbtree_test_height (GtkRBTree *tree,
1547 gint computed_offset = 0;
1549 /* This whole test is sort of a useless truism. */
1551 if (node->left != tree->nil)
1552 computed_offset += node->left->offset;
1554 if (node->right != tree->nil)
1555 computed_offset += node->right->offset;
1557 if (node->children && node->children->root != node->children->nil)
1558 computed_offset += node->children->root->offset;
1560 if (GTK_RBNODE_GET_HEIGHT (node) + computed_offset != node->offset)
1561 g_error ("node has broken offset\n");
1563 if (node->left != tree->nil)
1564 _gtk_rbtree_test_height (tree, node->left);
1566 if (node->right != tree->nil)
1567 _gtk_rbtree_test_height (tree, node->right);
1569 if (node->children && node->children->root != node->children->nil)
1570 _gtk_rbtree_test_height (node->children, node->children->root);
1574 _gtk_rbtree_test_dirty (GtkRBTree *tree,
1576 gint expected_dirtyness)
1579 if (expected_dirtyness)
1581 g_assert (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID) ||
1582 GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID) ||
1583 (node->left != tree->nil && GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID)) ||
1584 (node->right != tree->nil && GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID)) ||
1585 (node->children && GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID)));
1589 g_assert (! GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID) &&
1590 ! GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID));
1591 if (node->left != tree->nil)
1592 g_assert (! GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID));
1593 if (node->right != tree->nil)
1594 g_assert (! GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID));
1595 if (node->children != NULL)
1596 g_assert (! GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID));
1599 if (node->left != tree->nil)
1600 _gtk_rbtree_test_dirty (tree, node->left, GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID));
1601 if (node->right != tree->nil)
1602 _gtk_rbtree_test_dirty (tree, node->right, GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID));
1603 if (node->children != NULL && node->children->root != node->children->nil)
1604 _gtk_rbtree_test_dirty (node->children, node->children->root, GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID));
1607 static void _gtk_rbtree_test_structure (GtkRBTree *tree);
1610 _gtk_rbtree_test_structure_helper (GtkRBTree *tree,
1613 g_assert (node != tree->nil);
1615 g_assert (node->left != NULL);
1616 g_assert (node->right != NULL);
1617 g_assert (node->parent != NULL);
1619 if (node->left != tree->nil)
1621 g_assert (node->left->parent == node);
1622 _gtk_rbtree_test_structure_helper (tree, node->left);
1624 if (node->right != tree->nil)
1626 g_assert (node->right->parent == node);
1627 _gtk_rbtree_test_structure_helper (tree, node->right);
1630 if (node->children != NULL)
1632 g_assert (node->children->parent_tree == tree);
1633 g_assert (node->children->parent_node == node);
1635 _gtk_rbtree_test_structure (node->children);
1639 _gtk_rbtree_test_structure (GtkRBTree *tree)
1641 g_assert (tree->root);
1642 if (tree->root == tree->nil)
1645 g_assert (tree->root->parent == tree->nil);
1646 _gtk_rbtree_test_structure_helper (tree, tree->root);
1650 _gtk_rbtree_test (const gchar *where,
1653 GtkRBTree *tmp_tree;
1658 /* Test the entire tree */
1660 while (tmp_tree->parent_tree)
1661 tmp_tree = tmp_tree->parent_tree;
1663 g_assert (tmp_tree->nil != NULL);
1665 if (tmp_tree->root == tmp_tree->nil)
1668 _gtk_rbtree_test_structure (tmp_tree);
1670 g_assert ((_count_nodes (tmp_tree, tmp_tree->root->left) +
1671 _count_nodes (tmp_tree, tmp_tree->root->right) + 1) == tmp_tree->root->count);
1674 _gtk_rbtree_test_height (tmp_tree, tmp_tree->root);
1675 _gtk_rbtree_test_dirty (tmp_tree, tmp_tree->root, GTK_RBNODE_FLAG_SET (tmp_tree->root, GTK_RBNODE_DESCENDANTS_INVALID));
1676 g_assert (count_total (tmp_tree, tmp_tree->root) == tmp_tree->root->total_count);
1680 _gtk_rbtree_debug_spew_helper (GtkRBTree *tree,
1685 for (i = 0; i < depth; i++)
1688 g_print ("(%p - %s) (Offset %d) (Parity %d) (Validity %d%d%d)\n",
1690 (GTK_RBNODE_GET_COLOR (node) == GTK_RBNODE_BLACK)?"BLACK":" RED ",
1693 (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_DESCENDANTS_INVALID))?1:0,
1694 (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID))?1:0,
1695 (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID))?1:0);
1696 if (node->children != NULL)
1698 g_print ("Looking at child.\n");
1699 _gtk_rbtree_debug_spew (node->children);
1700 g_print ("Done looking at child.\n");
1702 if (node->left != tree->nil)
1704 _gtk_rbtree_debug_spew_helper (tree, node->left, depth+1);
1706 if (node->right != tree->nil)
1708 _gtk_rbtree_debug_spew_helper (tree, node->right, depth+1);
1713 _gtk_rbtree_debug_spew (GtkRBTree *tree)
1715 g_return_if_fail (tree != NULL);
1717 if (tree->root == tree->nil)
1718 g_print ("Empty tree...\n");
1720 _gtk_rbtree_debug_spew_helper (tree, tree->root, 0);
1722 #endif /* G_ENABLE_DEBUG */