X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkrbtree.c;h=d3e1fef7a61b37624aac786e780daa1db567e56d;hb=HEAD;hp=fdd45ad81223e95d04b9a199205bda1cebb2baed;hpb=0a07e9733bb259598a09515a3e4cdbcda5feef57;p=~andy%2Fgtk diff --git a/gtk/gtkrbtree.c b/gtk/gtkrbtree.c index fdd45ad81..d3e1fef7a 100644 --- a/gtk/gtkrbtree.c +++ b/gtk/gtkrbtree.c @@ -12,9 +12,7 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library. If not, see . */ #include "config.h" @@ -31,13 +29,29 @@ static void _gtk_rbnode_rotate_right (GtkRBTree *tree, static void _gtk_rbtree_insert_fixup (GtkRBTree *tree, GtkRBNode *node); static void _gtk_rbtree_remove_node_fixup (GtkRBTree *tree, - GtkRBNode *node); + GtkRBNode *node, + GtkRBNode *parent); static inline void _fixup_validation (GtkRBTree *tree, GtkRBNode *node); -static inline void _fixup_parity (GtkRBTree *tree, +static inline void _fixup_total_count (GtkRBTree *tree, GtkRBNode *node); +#ifdef G_ENABLE_DEBUG +static void _gtk_rbtree_test (const gchar *where, + GtkRBTree *tree); +static void _gtk_rbtree_debug_spew (GtkRBTree *tree); +#endif +static const GtkRBNode nil = { + /* .flags = */ GTK_RBNODE_BLACK, + /* rest is NULL */ +}; + +gboolean +_gtk_rbtree_is_nil (GtkRBNode *node) +{ + return node == &nil; +} static GtkRBNode * _gtk_rbnode_new (GtkRBTree *tree, @@ -45,11 +59,11 @@ _gtk_rbnode_new (GtkRBTree *tree, { GtkRBNode *node = g_slice_new (GtkRBNode); - node->left = tree->nil; - node->right = tree->nil; - node->parent = tree->nil; + node->left = (GtkRBNode *) &nil; + node->right = (GtkRBNode *) &nil; + node->parent = (GtkRBNode *) &nil; node->flags = GTK_RBNODE_RED; - node->parity = 1; + node->total_count = 1; node->count = 1; node->children = NULL; node->offset = height; @@ -59,15 +73,18 @@ _gtk_rbnode_new (GtkRBTree *tree, static void _gtk_rbnode_free (GtkRBNode *node) { - if (gtk_debug_flags & GTK_DEBUG_TREE) +#ifdef G_ENABLE_DEBUG + if (gtk_get_debug_flags () & GTK_DEBUG_TREE) { node->left = (gpointer) 0xdeadbeef; node->right = (gpointer) 0xdeadbeef; node->parent = (gpointer) 0xdeadbeef; + node->total_count = 56789; node->offset = 56789; node->count = 56789; node->flags = 0; } +#endif g_slice_free (GtkRBNode, node); } @@ -76,25 +93,21 @@ _gtk_rbnode_rotate_left (GtkRBTree *tree, GtkRBNode *node) { gint node_height, right_height; - GtkRBNode *right = node->right; - - g_return_if_fail (node != tree->nil); - - node_height = node->offset - - (node->left?node->left->offset:0) - - (node->right?node->right->offset:0) - - (node->children?node->children->root->offset:0); - right_height = right->offset - - (right->left?right->left->offset:0) - - (right->right?right->right->offset:0) - - (right->children?right->children->root->offset:0); + GtkRBNode *right; + + g_return_if_fail (!_gtk_rbtree_is_nil (node)); + g_return_if_fail (!_gtk_rbtree_is_nil (node->right)); + + right = node->right; + + node_height = GTK_RBNODE_GET_HEIGHT (node); + right_height = GTK_RBNODE_GET_HEIGHT (right); node->right = right->left; - if (right->left != tree->nil) + if (!_gtk_rbtree_is_nil (right->left)) right->left->parent = node; - if (right != tree->nil) - right->parent = node->parent; - if (node->parent != tree->nil) + right->parent = node->parent; + if (!_gtk_rbtree_is_nil (node->parent)) { if (node == node->parent->left) node->parent->left = right; @@ -105,27 +118,20 @@ _gtk_rbnode_rotate_left (GtkRBTree *tree, } right->left = node; - if (node != tree->nil) - node->parent = right; - - node->count = 1 + (node->left?node->left->count:0) + - (node->right?node->right->count:0); - right->count = 1 + (right->left?right->left->count:0) + - (right->right?right->right->count:0); - - node->offset = node_height + - (node->left?node->left->offset:0) + - (node->right?node->right->offset:0) + - (node->children?node->children->root->offset:0); - right->offset = right_height + - (right->left?right->left->offset:0) + - (right->right?right->right->offset:0) + - (right->children?right->children->root->offset:0); + node->parent = right; + + node->count = 1 + node->left->count + node->right->count; + right->count = 1 + right->left->count + right->right->count; + + node->offset = node_height + node->left->offset + node->right->offset + + (node->children ? node->children->root->offset : 0); + right->offset = right_height + right->left->offset + right->right->offset + + (right->children ? right->children->root->offset : 0); _fixup_validation (tree, node); _fixup_validation (tree, right); - _fixup_parity (tree, node); - _fixup_parity (tree, right); + _fixup_total_count (tree, node); + _fixup_total_count (tree, right); } static void @@ -133,26 +139,22 @@ _gtk_rbnode_rotate_right (GtkRBTree *tree, GtkRBNode *node) { gint node_height, left_height; - GtkRBNode *left = node->left; - - g_return_if_fail (node != tree->nil); - - node_height = node->offset - - (node->left?node->left->offset:0) - - (node->right?node->right->offset:0) - - (node->children?node->children->root->offset:0); - left_height = left->offset - - (left->left?left->left->offset:0) - - (left->right?left->right->offset:0) - - (left->children?left->children->root->offset:0); + GtkRBNode *left; + + g_return_if_fail (!_gtk_rbtree_is_nil (node)); + g_return_if_fail (!_gtk_rbtree_is_nil (node->left)); + + left = node->left; + + node_height = GTK_RBNODE_GET_HEIGHT (node); + left_height = GTK_RBNODE_GET_HEIGHT (left); node->left = left->right; - if (left->right != tree->nil) + if (!_gtk_rbtree_is_nil (left->right)) left->right->parent = node; - if (left != tree->nil) - left->parent = node->parent; - if (node->parent != tree->nil) + left->parent = node->parent; + if (!_gtk_rbtree_is_nil (node->parent)) { if (node == node->parent->right) node->parent->right = left; @@ -166,27 +168,20 @@ _gtk_rbnode_rotate_right (GtkRBTree *tree, /* link node and left */ left->right = node; - if (node != tree->nil) - node->parent = left; - - node->count = 1 + (node->left?node->left->count:0) + - (node->right?node->right->count:0); - left->count = 1 + (left->left?left->left->count:0) + - (left->right?left->right->count:0); - - node->offset = node_height + - (node->left?node->left->offset:0) + - (node->right?node->right->offset:0) + - (node->children?node->children->root->offset:0); - left->offset = left_height + - (left->left?left->left->offset:0) + - (left->right?left->right->offset:0) + - (left->children?left->children->root->offset:0); + node->parent = left; + + node->count = 1 + node->left->count + node->right->count; + left->count = 1 + left->left->count + left->right->count; + + node->offset = node_height + node->left->offset + node->right->offset + + (node->children ? node->children->root->offset : 0); + left->offset = left_height + left->left->offset + left->right->offset + + (left->children?left->children->root->offset:0); _fixup_validation (tree, node); _fixup_validation (tree, left); - _fixup_parity (tree, node); - _fixup_parity (tree, left); + _fixup_total_count (tree, node); + _fixup_total_count (tree, left); } static void @@ -256,24 +251,25 @@ _gtk_rbtree_insert_fixup (GtkRBTree *tree, static void _gtk_rbtree_remove_node_fixup (GtkRBTree *tree, - GtkRBNode *node) + GtkRBNode *node, + GtkRBNode *parent) { while (node != tree->root && GTK_RBNODE_GET_COLOR (node) == GTK_RBNODE_BLACK) { - if (node == node->parent->left) + if (node == parent->left) { - GtkRBNode *w = node->parent->right; + GtkRBNode *w = parent->right; if (GTK_RBNODE_GET_COLOR (w) == GTK_RBNODE_RED) { GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_BLACK); - GTK_RBNODE_SET_COLOR (node->parent, GTK_RBNODE_RED); - _gtk_rbnode_rotate_left (tree, node->parent); - w = node->parent->right; + GTK_RBNODE_SET_COLOR (parent, GTK_RBNODE_RED); + _gtk_rbnode_rotate_left (tree, parent); + w = parent->right; } if (GTK_RBNODE_GET_COLOR (w->left) == GTK_RBNODE_BLACK && GTK_RBNODE_GET_COLOR (w->right) == GTK_RBNODE_BLACK) { GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_RED); - node = node->parent; + node = parent; } else { @@ -282,29 +278,29 @@ _gtk_rbtree_remove_node_fixup (GtkRBTree *tree, GTK_RBNODE_SET_COLOR (w->left, GTK_RBNODE_BLACK); GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_RED); _gtk_rbnode_rotate_right (tree, w); - w = node->parent->right; + w = parent->right; } - GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_GET_COLOR (node->parent)); - GTK_RBNODE_SET_COLOR (node->parent, GTK_RBNODE_BLACK); + GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_GET_COLOR (parent)); + GTK_RBNODE_SET_COLOR (parent, GTK_RBNODE_BLACK); GTK_RBNODE_SET_COLOR (w->right, GTK_RBNODE_BLACK); - _gtk_rbnode_rotate_left (tree, node->parent); + _gtk_rbnode_rotate_left (tree, parent); node = tree->root; } } else { - GtkRBNode *w = node->parent->left; + GtkRBNode *w = parent->left; if (GTK_RBNODE_GET_COLOR (w) == GTK_RBNODE_RED) { GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_BLACK); - GTK_RBNODE_SET_COLOR (node->parent, GTK_RBNODE_RED); - _gtk_rbnode_rotate_right (tree, node->parent); - w = node->parent->left; + GTK_RBNODE_SET_COLOR (parent, GTK_RBNODE_RED); + _gtk_rbnode_rotate_right (tree, parent); + w = parent->left; } if (GTK_RBNODE_GET_COLOR (w->right) == GTK_RBNODE_BLACK && GTK_RBNODE_GET_COLOR (w->left) == GTK_RBNODE_BLACK) { GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_RED); - node = node->parent; + node = parent; } else { @@ -313,15 +309,17 @@ _gtk_rbtree_remove_node_fixup (GtkRBTree *tree, GTK_RBNODE_SET_COLOR (w->right, GTK_RBNODE_BLACK); GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_RED); _gtk_rbnode_rotate_left (tree, w); - w = node->parent->left; + w = parent->left; } - GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_GET_COLOR (node->parent)); - GTK_RBNODE_SET_COLOR (node->parent, GTK_RBNODE_BLACK); + GTK_RBNODE_SET_COLOR (w, GTK_RBNODE_GET_COLOR (parent)); + GTK_RBNODE_SET_COLOR (parent, GTK_RBNODE_BLACK); GTK_RBNODE_SET_COLOR (w->left, GTK_RBNODE_BLACK); - _gtk_rbnode_rotate_right (tree, node->parent); + _gtk_rbnode_rotate_right (tree, parent); node = tree->root; } } + + parent = node->parent; } GTK_RBNODE_SET_COLOR (node, GTK_RBNODE_BLACK); } @@ -335,16 +333,8 @@ _gtk_rbtree_new (void) retval->parent_tree = NULL; retval->parent_node = NULL; - retval->nil = g_slice_new (GtkRBNode); - retval->nil->left = NULL; - retval->nil->right = NULL; - retval->nil->parent = NULL; - retval->nil->flags = GTK_RBNODE_BLACK; - retval->nil->count = 0; - retval->nil->offset = 0; - retval->nil->parity = 0; + retval->root = (GtkRBNode *) &nil; - retval->root = retval->nil; return retval; } @@ -371,53 +361,61 @@ _gtk_rbtree_free (GtkRBTree *tree) if (tree->parent_node && tree->parent_node->children == tree) tree->parent_node->children = NULL; - _gtk_rbnode_free (tree->nil); g_free (tree); } +static void +gtk_rbnode_adjust (GtkRBTree *tree, + GtkRBNode *node, + int count_diff, + int total_count_diff, + int offset_diff) +{ + while (tree && node && !_gtk_rbtree_is_nil (node)) + { + _fixup_validation (tree, node); + node->offset += offset_diff; + node->count += count_diff; + node->total_count += total_count_diff; + + node = node->parent; + if (_gtk_rbtree_is_nil (node)) + { + node = tree->parent_node; + tree = tree->parent_tree; + count_diff = 0; + } + } +} + void _gtk_rbtree_remove (GtkRBTree *tree) { +#ifdef G_ENABLE_DEBUG GtkRBTree *tmp_tree; - GtkRBNode *tmp_node; - - gint height = tree->root->offset; -#ifdef G_ENABLE_DEBUG - if (gtk_debug_flags & GTK_DEBUG_TREE) + if (gtk_get_debug_flags () & GTK_DEBUG_TREE) _gtk_rbtree_test (G_STRLOC, tree); #endif - tmp_tree = tree->parent_tree; - tmp_node = tree->parent_node; - /* ugly hack to make _fixup_validation work in the first iteration of the * loop below */ GTK_RBNODE_UNSET_FLAG (tree->root, GTK_RBNODE_DESCENDANTS_INVALID); - while (tmp_tree && tmp_node && tmp_node != tmp_tree->nil) - { - _fixup_validation (tmp_tree, tmp_node); - tmp_node->offset -= height; - - /* If the removed tree was odd, flip all parents */ - if (tree->root->parity) - tmp_node->parity = !tmp_node->parity; - - tmp_node = tmp_node->parent; - if (tmp_node == tmp_tree->nil) - { - tmp_node = tmp_tree->parent_node; - tmp_tree = tmp_tree->parent_tree; - } - } + gtk_rbnode_adjust (tree->parent_tree, + tree->parent_node, + 0, + - (int) tree->root->total_count, + - tree->root->offset); +#ifdef G_ENABLE_DEBUG tmp_tree = tree->parent_tree; - tmp_node = tree->parent_node; +#endif + _gtk_rbtree_free (tree); #ifdef G_ENABLE_DEBUG - if (gtk_debug_flags & GTK_DEBUG_TREE) + if (gtk_get_debug_flags () & GTK_DEBUG_TREE) _gtk_rbtree_test (G_STRLOC, tmp_tree); #endif } @@ -431,11 +429,9 @@ _gtk_rbtree_insert_after (GtkRBTree *tree, { GtkRBNode *node; gboolean right = TRUE; - GtkRBNode *tmp_node; - GtkRBTree *tmp_tree; #ifdef G_ENABLE_DEBUG - if (gtk_debug_flags & GTK_DEBUG_TREE) + if (gtk_get_debug_flags () & GTK_DEBUG_TREE) { g_print ("\n\n_gtk_rbtree_insert_after: %p\n", current); _gtk_rbtree_debug_spew (tree); @@ -443,49 +439,33 @@ _gtk_rbtree_insert_after (GtkRBTree *tree, } #endif /* G_ENABLE_DEBUG */ - if (current != NULL && current->right != tree->nil) + if (current != NULL && !_gtk_rbtree_is_nil (current->right)) { current = current->right; - while (current->left != tree->nil) + while (!_gtk_rbtree_is_nil (current->left)) current = current->left; right = FALSE; } /* setup new node */ node = _gtk_rbnode_new (tree, height); - node->parent = (current?current:tree->nil); /* insert node in tree */ if (current) { + node->parent = current; if (right) current->right = node; else current->left = node; - tmp_node = node->parent; - tmp_tree = tree; + gtk_rbnode_adjust (tree, node->parent, + 1, 1, height); } else { + g_assert (_gtk_rbtree_is_nil (tree->root)); tree->root = node; - tmp_node = tree->parent_node; - tmp_tree = tree->parent_tree; - } - - while (tmp_tree && tmp_node && tmp_node != tmp_tree->nil) - { - /* We only want to propagate the count if we are in the tree we - * started in. */ - if (tmp_tree == tree) - tmp_node->count++; - - tmp_node->parity += 1; - tmp_node->offset += height; - tmp_node = tmp_node->parent; - if (tmp_node == tmp_tree->nil) - { - tmp_node = tmp_tree->parent_node; - tmp_tree = tmp_tree->parent_tree; - } + gtk_rbnode_adjust (tree->parent_tree, tree->parent_node, + 0, 1, height); } if (valid) @@ -496,7 +476,7 @@ _gtk_rbtree_insert_after (GtkRBTree *tree, _gtk_rbtree_insert_fixup (tree, node); #ifdef G_ENABLE_DEBUG - if (gtk_debug_flags & GTK_DEBUG_TREE) + if (gtk_get_debug_flags () & GTK_DEBUG_TREE) { g_print ("_gtk_rbtree_insert_after finished...\n"); _gtk_rbtree_debug_spew (tree); @@ -516,11 +496,9 @@ _gtk_rbtree_insert_before (GtkRBTree *tree, { GtkRBNode *node; gboolean left = TRUE; - GtkRBNode *tmp_node; - GtkRBTree *tmp_tree; #ifdef G_ENABLE_DEBUG - if (gtk_debug_flags & GTK_DEBUG_TREE) + if (gtk_get_debug_flags () & GTK_DEBUG_TREE) { g_print ("\n\n_gtk_rbtree_insert_before: %p\n", current); _gtk_rbtree_debug_spew (tree); @@ -528,50 +506,34 @@ _gtk_rbtree_insert_before (GtkRBTree *tree, } #endif /* G_ENABLE_DEBUG */ - if (current != NULL && current->left != tree->nil) + if (current != NULL && !_gtk_rbtree_is_nil (current->left)) { current = current->left; - while (current->right != tree->nil) + while (!_gtk_rbtree_is_nil (current->right)) current = current->right; left = FALSE; } /* setup new node */ node = _gtk_rbnode_new (tree, height); - node->parent = (current?current:tree->nil); /* insert node in tree */ if (current) { + node->parent = current; if (left) current->left = node; else current->right = node; - tmp_node = node->parent; - tmp_tree = tree; + gtk_rbnode_adjust (tree, node->parent, + 1, 1, height); } else { + g_assert (_gtk_rbtree_is_nil (tree->root)); tree->root = node; - tmp_node = tree->parent_node; - tmp_tree = tree->parent_tree; - } - - while (tmp_tree && tmp_node && tmp_node != tmp_tree->nil) - { - /* We only want to propagate the count if we are in the tree we - * started in. */ - if (tmp_tree == tree) - tmp_node->count++; - - tmp_node->parity += 1; - tmp_node->offset += height; - tmp_node = tmp_node->parent; - if (tmp_node == tmp_tree->nil) - { - tmp_node = tmp_tree->parent_node; - tmp_tree = tmp_tree->parent_tree; - } + gtk_rbnode_adjust (tree->parent_tree, tree->parent_node, + 0, 1, height); } if (valid) @@ -582,7 +544,7 @@ _gtk_rbtree_insert_before (GtkRBTree *tree, _gtk_rbtree_insert_fixup (tree, node); #ifdef G_ENABLE_DEBUG - if (gtk_debug_flags & GTK_DEBUG_TREE) + if (gtk_get_debug_flags () & GTK_DEBUG_TREE) { g_print ("_gtk_rbtree_insert_before finished...\n"); _gtk_rbtree_debug_spew (tree); @@ -601,7 +563,7 @@ _gtk_rbtree_find_count (GtkRBTree *tree, GtkRBNode *node; node = tree->root; - while (node != tree->nil && (node->left->count + 1 != count)) + while (!_gtk_rbtree_is_nil (node) && (node->left->count + 1 != count)) { if (node->left->count >= count) node = node->left; @@ -611,7 +573,7 @@ _gtk_rbtree_find_count (GtkRBTree *tree, node = node->right; } } - if (node == tree->nil) + if (_gtk_rbtree_is_nil (node)) return NULL; return node; } @@ -622,24 +584,14 @@ _gtk_rbtree_node_set_height (GtkRBTree *tree, gint height) { gint diff = height - GTK_RBNODE_GET_HEIGHT (node); - GtkRBNode *tmp_node = node; - GtkRBTree *tmp_tree = tree; if (diff == 0) return; - while (tmp_tree && tmp_node && tmp_node != tmp_tree->nil) - { - tmp_node->offset += diff; - tmp_node = tmp_node->parent; - if (tmp_node == tmp_tree->nil) - { - tmp_node = tmp_tree->parent_node; - tmp_tree = tmp_tree->parent_tree; - } - } + gtk_rbnode_adjust (tree, node, 0, 0, diff); + #ifdef G_ENABLE_DEBUG - if (gtk_debug_flags & GTK_DEBUG_TREE) + if (gtk_get_debug_flags () & GTK_DEBUG_TREE) _gtk_rbtree_test (G_STRLOC, tree); #endif } @@ -658,7 +610,7 @@ _gtk_rbtree_node_mark_invalid (GtkRBTree *tree, return; GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID); node = node->parent; - if (node == tree->nil) + if (_gtk_rbtree_is_nil (node)) { node = tree->parent_node; tree = tree->parent_tree; @@ -678,7 +630,7 @@ _gtk_rbtree_node_mark_invalid (GtkRBTree *tree, { _fixup_validation (tree, node); node = node->parent; - if (node == tree->nil) + if (_gtk_rbtree_is_nil (node)) { node = tree->parent_node; tree = tree->parent_tree; @@ -704,13 +656,13 @@ _gtk_rbtree_node_mark_valid (GtkRBTree *tree, if ((GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID)) || (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID)) || (node->children && GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID)) || - (node->left != tree->nil && GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID)) || - (node->right != tree->nil && GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID))) + (GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID)) || + (GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID))) return; GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID); node = node->parent; - if (node == tree->nil) + if (_gtk_rbtree_is_nil (node)) { node = tree->parent_node; tree = tree->parent_tree; @@ -732,7 +684,7 @@ _gtk_rbtree_node_mark_valid (GtkRBTree *tree, { _fixup_validation (tree, node); node = node->parent; - if (node == tree->nil) + if (_gtk_rbtree_is_nil (node)) { node = tree->parent_node; tree = tree->parent_tree; @@ -750,11 +702,8 @@ _gtk_rbtree_column_invalid (GtkRBTree *tree) if (tree == NULL) return; - node = tree->root; - g_assert (node); - while (node->left != tree->nil) - node = node->left; + node = _gtk_rbtree_first (tree); do { @@ -775,11 +724,8 @@ _gtk_rbtree_mark_invalid (GtkRBTree *tree) if (tree == NULL) return; - node = tree->root; - g_assert (node); - while (node->left != tree->nil) - node = node->left; + node = _gtk_rbtree_first (tree); do { @@ -802,11 +748,7 @@ _gtk_rbtree_set_fixed_height (GtkRBTree *tree, if (tree == NULL) return; - node = tree->root; - g_assert (node); - - while (node->left != tree->nil) - node = node->left; + node = _gtk_rbtree_first (tree); do { @@ -823,65 +765,48 @@ _gtk_rbtree_set_fixed_height (GtkRBTree *tree, while ((node = _gtk_rbtree_next (tree, node)) != NULL); } -typedef struct _GtkRBReorder -{ - GtkRBTree *children; - gint height; - gint flags; - gint order; - gint invert_order; - gint parity; -} GtkRBReorder; - -static int -gtk_rbtree_reorder_sort_func (gconstpointer a, - gconstpointer b) +static void +reorder_prepare (GtkRBTree *tree, + GtkRBNode *node, + gpointer data) { - return ((GtkRBReorder *) a)->order - ((GtkRBReorder *) b)->order; + node->offset -= node->left->offset + node->right->offset; + GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID); } -static int -gtk_rbtree_reorder_invert_func (gconstpointer a, - gconstpointer b) +static void +reorder_fixup (GtkRBTree *tree, + GtkRBNode *node, + gpointer data) { - return ((GtkRBReorder *) a)->invert_order - ((GtkRBReorder *) b)->invert_order; + node->offset += node->left->offset + node->right->offset; + node->count = 1 + node->left->count + node->right->count; + _fixup_validation (tree, node); + _fixup_total_count (tree, node); } static void -gtk_rbtree_reorder_fixup (GtkRBTree *tree, - GtkRBNode *node) +reorder_copy_node (GtkRBTree *tree, + GtkRBNode *to, + GtkRBNode *from) { - if (node == tree->nil) - return; - - node->parity = 1; - - if (node->left != tree->nil) - { - gtk_rbtree_reorder_fixup (tree, node->left); - node->offset += node->left->offset; - node->parity += node->left->parity; - } - if (node->right != tree->nil) - { - gtk_rbtree_reorder_fixup (tree, node->right); - node->offset += node->right->offset; - node->parity += node->right->parity; - } - - if (node->children) - { - node->offset += node->children->root->offset; - node->parity += node->children->root->parity; - } - - if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID) || - (node->right != tree->nil && GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID)) || - (node->left != tree->nil && GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID)) || - (node->children && GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID))) - GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID); - else - GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID); + to->flags = (to->flags & GTK_RBNODE_NON_COLORS) | GTK_RBNODE_GET_COLOR (from); + + to->left = from->left; + if (!_gtk_rbtree_is_nil (to->left)) + to->left->parent = to; + + to->right = from->right; + if (!_gtk_rbtree_is_nil (to->right)) + to->right->parent = to; + + to->parent = from->parent; + if (_gtk_rbtree_is_nil (to->parent)) + tree->root = to; + else if (to->parent->left == from) + to->parent->left = to; + else if (to->parent->right == from) + to->parent->right = to; } /* It basically pulls everything out of the tree, rearranges it, and puts it @@ -895,65 +820,89 @@ _gtk_rbtree_reorder (GtkRBTree *tree, gint *new_order, gint length) { - GtkRBReorder reorder = { NULL }; - GArray *array; + GtkRBNode **nodes; GtkRBNode *node; - gint i; + gint i, j; g_return_if_fail (tree != NULL); g_return_if_fail (length > 0); g_return_if_fail (tree->root->count == length); - /* Sort the trees values in the new tree. */ - array = g_array_sized_new (FALSE, FALSE, sizeof (GtkRBReorder), length); - for (i = 0; i < length; i++) - { - reorder.order = new_order[i]; - reorder.invert_order = i; - g_array_append_val (array, reorder); - } + nodes = g_new (GtkRBNode *, length); - g_array_sort(array, gtk_rbtree_reorder_sort_func); + _gtk_rbtree_traverse (tree, tree->root, G_PRE_ORDER, reorder_prepare, NULL); - /* rewind node*/ - node = tree->root; - while (node && node->left != tree->nil) - node = node->left; + for (node = _gtk_rbtree_first (tree), i = 0; + node; + node = _gtk_rbtree_next (tree, node), i++) + { + nodes[i] = node; + } for (i = 0; i < length; i++) { - g_assert (node != tree->nil); - g_array_index (array, GtkRBReorder, i).children = node->children; - g_array_index (array, GtkRBReorder, i).flags = GTK_RBNODE_NON_COLORS & node->flags; - g_array_index (array, GtkRBReorder, i).height = GTK_RBNODE_GET_HEIGHT (node); + GtkRBNode tmp = { 0, }; + GSList *l, *cycle = NULL; - node = _gtk_rbtree_next (tree, node); - } + tmp.offset = -1; - g_array_sort (array, gtk_rbtree_reorder_invert_func); - - /* rewind node*/ - node = tree->root; - while (node && node->left != tree->nil) - node = node->left; + /* already swapped */ + if (nodes[i] == NULL) + continue; + /* no need to swap */ + if (new_order[i] == i) + continue; - /* Go through the tree and change the values to the new ones. */ - for (i = 0; i < length; i++) - { - reorder = g_array_index (array, GtkRBReorder, i); - node->children = reorder.children; - if (node->children) - node->children->parent_node = node; - node->flags = GTK_RBNODE_GET_COLOR (node) | reorder.flags; - /* We temporarily set the height to this. */ - node->offset = reorder.height; - node = _gtk_rbtree_next (tree, node); + /* make a list out of the pending nodes */ + for (j = i; new_order[j] != i; j = new_order[j]) + { + cycle = g_slist_prepend (cycle, nodes[j]); + nodes[j] = NULL; + } + + node = nodes[j]; + reorder_copy_node (tree, &tmp, node); + for (l = cycle; l; l = l->next) + { + reorder_copy_node (tree, node, l->data); + node = l->data; + } + + reorder_copy_node (tree, node, &tmp); + nodes[j] = NULL; + g_slist_free (cycle); } - gtk_rbtree_reorder_fixup (tree, tree->root); - g_array_free (array, TRUE); + _gtk_rbtree_traverse (tree, tree->root, G_POST_ORDER, reorder_fixup, NULL); + + g_free (nodes); } +/** + * _gtk_rbtree_contains: + * @tree: a tree + * @potential_child: a potential child of @tree + * + * Checks if @potential_child is a child (direct or via intermediate + * trees) of @tree. + * + * Returns: %TRUE if @potentitial_child is a child of @tree. + **/ +gboolean +_gtk_rbtree_contains (GtkRBTree *tree, + GtkRBTree *potential_child) +{ + g_return_val_if_fail (tree != NULL, FALSE); + g_return_val_if_fail (potential_child != NULL, FALSE); + + do { + potential_child = potential_child->parent_tree; + if (potential_child == tree) + return TRUE; + } while (potential_child != NULL); + + return FALSE; +} gint _gtk_rbtree_node_find_offset (GtkRBTree *tree, @@ -967,7 +916,7 @@ _gtk_rbtree_node_find_offset (GtkRBTree *tree, retval = node->left->offset; - while (tree && node && node != tree->nil) + while (tree && node && !_gtk_rbtree_is_nil (node)) { last = node; node = node->parent; @@ -976,7 +925,7 @@ _gtk_rbtree_node_find_offset (GtkRBTree *tree, if (node->right == last) retval += node->offset - node->right->offset; - if (node == tree->nil) + if (_gtk_rbtree_is_nil (node)) { node = tree->parent_node; tree = tree->parent_tree; @@ -989,46 +938,46 @@ _gtk_rbtree_node_find_offset (GtkRBTree *tree, return retval; } -gint -_gtk_rbtree_node_find_parity (GtkRBTree *tree, - GtkRBNode *node) +guint +_gtk_rbtree_node_get_index (GtkRBTree *tree, + GtkRBNode *node) { GtkRBNode *last; - gint retval; + guint retval; g_assert (node); g_assert (node->left); - retval = node->left->parity; + retval = node->left->total_count; - while (tree && node && node != tree->nil) + while (tree && node && !_gtk_rbtree_is_nil (node)) { last = node; node = node->parent; /* Add left branch, plus children, iff we came from the right */ if (node->right == last) - retval += node->parity - node->right->parity; + retval += node->total_count - node->right->total_count; - if (node == tree->nil) + if (_gtk_rbtree_is_nil (node)) { node = tree->parent_node; tree = tree->parent_tree; /* Add the parent node, plus the left branch. */ if (node) - retval += node->left->parity + 1; /* 1 == GTK_RBNODE_GET_PARITY() */ + retval += node->left->total_count + 1; /* 1 == GTK_RBNODE_GET_PARITY() */ } } - return retval % 2; + return retval; } -gint -_gtk_rbtree_real_find_offset (GtkRBTree *tree, - gint height, - GtkRBTree **new_tree, - GtkRBNode **new_node) +static gint +gtk_rbtree_real_find_offset (GtkRBTree *tree, + gint height, + GtkRBTree **new_tree, + GtkRBNode **new_node) { GtkRBNode *tmp_node; @@ -1044,7 +993,7 @@ _gtk_rbtree_real_find_offset (GtkRBTree *tree, tmp_node = tree->root; - while (tmp_node != tree->nil && + while (!_gtk_rbtree_is_nil (tmp_node) && (tmp_node->left->offset > height || (tmp_node->offset - tmp_node->right->offset) < height)) { @@ -1056,7 +1005,7 @@ _gtk_rbtree_real_find_offset (GtkRBTree *tree, tmp_node = tmp_node->right; } } - if (tmp_node == tree->nil) + if (_gtk_rbtree_is_nil (tmp_node)) { *new_tree = NULL; *new_node = NULL; @@ -1072,14 +1021,14 @@ _gtk_rbtree_real_find_offset (GtkRBTree *tree, *new_node = tmp_node; return (height - tmp_node->left->offset); } - return _gtk_rbtree_real_find_offset (tmp_node->children, - height - tmp_node->left->offset - - (tmp_node->offset - - tmp_node->left->offset - - tmp_node->right->offset - - tmp_node->children->root->offset), - new_tree, - new_node); + return gtk_rbtree_real_find_offset (tmp_node->children, + height - tmp_node->left->offset - + (tmp_node->offset - + tmp_node->left->offset - + tmp_node->right->offset - + tmp_node->children->root->offset), + new_tree, + new_node); } *new_tree = tree; *new_node = tmp_node; @@ -1088,9 +1037,9 @@ _gtk_rbtree_real_find_offset (GtkRBTree *tree, gint _gtk_rbtree_find_offset (GtkRBTree *tree, - gint height, - GtkRBTree **new_tree, - GtkRBNode **new_node) + gint height, + GtkRBTree **new_tree, + GtkRBNode **new_node) { g_assert (tree); @@ -1102,7 +1051,57 @@ _gtk_rbtree_find_offset (GtkRBTree *tree, return 0; } - return _gtk_rbtree_real_find_offset (tree, height, new_tree, new_node); + return gtk_rbtree_real_find_offset (tree, height, new_tree, new_node); +} + +gboolean +_gtk_rbtree_find_index (GtkRBTree *tree, + guint index, + GtkRBTree **new_tree, + GtkRBNode **new_node) +{ + GtkRBNode *tmp_node; + + g_assert (tree); + + tmp_node = tree->root; + while (!_gtk_rbtree_is_nil (tmp_node)) + { + if (tmp_node->left->total_count > index) + { + tmp_node = tmp_node->left; + } + else if (tmp_node->total_count - tmp_node->right->total_count <= index) + { + index -= tmp_node->total_count - tmp_node->right->total_count; + tmp_node = tmp_node->right; + } + else + { + index -= tmp_node->left->total_count; + break; + } + } + if (_gtk_rbtree_is_nil (tmp_node)) + { + *new_tree = NULL; + *new_node = NULL; + return FALSE; + } + + if (index > 0) + { + g_assert (tmp_node->children); + + return _gtk_rbtree_find_index (tmp_node->children, + index - 1, + new_tree, + new_node); + } + + *new_tree = tree; + *new_node = tmp_node; + return TRUE; } void @@ -1110,16 +1109,15 @@ _gtk_rbtree_remove_node (GtkRBTree *tree, GtkRBNode *node) { GtkRBNode *x, *y; - GtkRBTree *tmp_tree; - GtkRBNode *tmp_node; gint y_height; + guint y_total_count; g_return_if_fail (tree != NULL); g_return_if_fail (node != NULL); #ifdef G_ENABLE_DEBUG - if (gtk_debug_flags & GTK_DEBUG_TREE) + if (gtk_get_debug_flags () & GTK_DEBUG_TREE) { g_print ("\n\n_gtk_rbtree_remove_node: %p\n", node); _gtk_rbtree_debug_spew (tree); @@ -1128,16 +1126,17 @@ _gtk_rbtree_remove_node (GtkRBTree *tree, #endif /* G_ENABLE_DEBUG */ /* make sure we're deleting a node that's actually in the tree */ - for (x = node; x->parent != tree->nil; x = x->parent) + for (x = node; !_gtk_rbtree_is_nil (x->parent); x = x->parent) ; g_return_if_fail (x == tree->root); #ifdef G_ENABLE_DEBUG - if (gtk_debug_flags & GTK_DEBUG_TREE) + if (gtk_get_debug_flags () & GTK_DEBUG_TREE) _gtk_rbtree_test (G_STRLOC, tree); #endif - if (node->left == tree->nil || node->right == tree->nil) + if (_gtk_rbtree_is_nil (node->left) || + _gtk_rbtree_is_nil (node->right)) { y = node; } @@ -1145,43 +1144,24 @@ _gtk_rbtree_remove_node (GtkRBTree *tree, { y = node->right; - while (y->left != tree->nil) + while (!_gtk_rbtree_is_nil (y->left)) y = y->left; } - /* adjust count only beneath tree */ - for (x = y; x != tree->nil; x = x->parent) - { - x->count--; - } - - /* offsets and parity adjust all the way up through parent trees */ - y_height = GTK_RBNODE_GET_HEIGHT (y); - - tmp_tree = tree; - tmp_node = y; - while (tmp_tree && tmp_node && tmp_node != tmp_tree->nil) - { - tmp_node->offset -= (y_height + (y->children?y->children->root->offset:0)); - _fixup_validation (tmp_tree, tmp_node); - _fixup_parity (tmp_tree, tmp_node); - tmp_node = tmp_node->parent; - if (tmp_node == tmp_tree->nil) - { - tmp_node = tmp_tree->parent_node; - tmp_tree = tmp_tree->parent_tree; - } - } + y_height = GTK_RBNODE_GET_HEIGHT (y) + + (y->children ? y->children->root->offset : 0); + y_total_count = 1 + (y->children ? y->children->root->total_count : 0); /* x is y's only child, or nil */ - if (y->left != tree->nil) + if (!_gtk_rbtree_is_nil (y->left)) x = y->left; else x = y->right; /* remove y from the parent chain */ - x->parent = y->parent; - if (y->parent != tree->nil) + if (!_gtk_rbtree_is_nil (x)) + x->parent = y->parent; + if (!_gtk_rbtree_is_nil (y->parent)) { if (y == y->parent->left) y->parent->left = x; @@ -1195,74 +1175,59 @@ _gtk_rbtree_remove_node (GtkRBTree *tree, /* We need to clean up the validity of the tree. */ + gtk_rbnode_adjust (tree, y, -1, - y_total_count, - y_height); - tmp_tree = tree; - tmp_node = x; - do - { - /* We skip the first time, iff x is nil */ - if (tmp_node != tmp_tree->nil) - { - _fixup_validation (tmp_tree, tmp_node); - _fixup_parity (tmp_tree, tmp_node); - } - tmp_node = tmp_node->parent; - if (tmp_node == tmp_tree->nil) - { - tmp_node = tmp_tree->parent_node; - tmp_tree = tmp_tree->parent_tree; - } - } - while (tmp_tree != NULL); + if (GTK_RBNODE_GET_COLOR (y) == GTK_RBNODE_BLACK) + _gtk_rbtree_remove_node_fixup (tree, x, y->parent); if (y != node) { - gint diff; + gint node_height, node_total_count; - /* Copy the node over */ - if (GTK_RBNODE_GET_COLOR (node) == GTK_RBNODE_BLACK) - node->flags = ((y->flags & (GTK_RBNODE_NON_COLORS)) | GTK_RBNODE_BLACK); - else - node->flags = ((y->flags & (GTK_RBNODE_NON_COLORS)) | GTK_RBNODE_RED); - node->children = y->children; - if (y->children) - { - node->children = y->children; - node->children->parent_node = node; - } - else - { - node->children = NULL; - } - _fixup_validation (tree, node); - _fixup_parity (tree, node); - /* We want to see how different our height is from the previous node. - * To do this, we compare our current height with our supposed height. + /* We want to see how much we remove from the aggregate values. + * This is all the children we remove plus the node's values. */ - diff = y_height - GTK_RBNODE_GET_HEIGHT (node); - tmp_tree = tree; - tmp_node = node; + node_height = GTK_RBNODE_GET_HEIGHT (node) + + (node->children ? node->children->root->offset : 0); + node_total_count = 1 + + (node->children ? node->children->root->total_count : 0); + + /* Move the node over */ + if (GTK_RBNODE_GET_COLOR (node) != GTK_RBNODE_GET_COLOR (y)) + y->flags ^= (GTK_RBNODE_BLACK | GTK_RBNODE_RED); + + y->left = node->left; + if (!_gtk_rbtree_is_nil (y->left)) + y->left->parent = y; + y->right = node->right; + if (!_gtk_rbtree_is_nil (y->right)) + y->right->parent = y; + y->parent = node->parent; + if (!_gtk_rbtree_is_nil (y->parent)) + { + if (y->parent->left == node) + y->parent->left = y; + else + y->parent->right = y; + } + else + { + tree->root = y; + } + y->count = node->count; + y->total_count = node->total_count; + y->offset = node->offset; - while (tmp_tree && tmp_node && tmp_node != tmp_tree->nil) - { - tmp_node->offset += diff; - _fixup_validation (tmp_tree, tmp_node); - _fixup_parity (tmp_tree, tmp_node); - tmp_node = tmp_node->parent; - if (tmp_node == tmp_tree->nil) - { - tmp_node = tmp_tree->parent_node; - tmp_tree = tmp_tree->parent_tree; - } - } + gtk_rbnode_adjust (tree, y, + 0, + y_total_count - node_total_count, + y_height - node_height); } - if (GTK_RBNODE_GET_COLOR (y) == GTK_RBNODE_BLACK) - _gtk_rbtree_remove_node_fixup (tree, x); - _gtk_rbnode_free (y); + _gtk_rbnode_free (node); #ifdef G_ENABLE_DEBUG - if (gtk_debug_flags & GTK_DEBUG_TREE) + if (gtk_get_debug_flags () & GTK_DEBUG_TREE) { g_print ("_gtk_rbtree_remove_node finished...\n"); _gtk_rbtree_debug_spew (tree); @@ -1272,6 +1237,22 @@ _gtk_rbtree_remove_node (GtkRBTree *tree, #endif /* G_ENABLE_DEBUG */ } +GtkRBNode * +_gtk_rbtree_first (GtkRBTree *tree) +{ + GtkRBNode *node; + + node = tree->root; + + if (_gtk_rbtree_is_nil (node)) + return NULL; + + while (!_gtk_rbtree_is_nil (node->left)) + node = node->left; + + return node; +} + GtkRBNode * _gtk_rbtree_next (GtkRBTree *tree, GtkRBNode *node) @@ -1280,16 +1261,16 @@ _gtk_rbtree_next (GtkRBTree *tree, g_return_val_if_fail (node != NULL, NULL); /* Case 1: the node's below us. */ - if (node->right != tree->nil) + if (!_gtk_rbtree_is_nil (node->right)) { node = node->right; - while (node->left != tree->nil) + while (!_gtk_rbtree_is_nil (node->left)) node = node->left; return node; } /* Case 2: it's an ancestor */ - while (node->parent != tree->nil) + while (!_gtk_rbtree_is_nil (node->parent)) { if (node->parent->right == node) node = node->parent; @@ -1309,16 +1290,16 @@ _gtk_rbtree_prev (GtkRBTree *tree, g_return_val_if_fail (node != NULL, NULL); /* Case 1: the node's below us. */ - if (node->left != tree->nil) + if (!_gtk_rbtree_is_nil (node->left)) { node = node->left; - while (node->right != tree->nil) + while (!_gtk_rbtree_is_nil (node->right)) node = node->right; return node; } /* Case 2: it's an ancestor */ - while (node->parent != tree->nil) + while (!_gtk_rbtree_is_nil (node->parent)) { if (node->parent->left == node) node = node->parent; @@ -1345,7 +1326,7 @@ _gtk_rbtree_next_full (GtkRBTree *tree, { *new_tree = node->children; *new_node = (*new_tree)->root; - while ((*new_node)->left != (*new_tree)->nil) + while (!_gtk_rbtree_is_nil ((*new_node)->left)) *new_node = (*new_node)->left; return; } @@ -1388,7 +1369,7 @@ _gtk_rbtree_prev_full (GtkRBTree *tree, { *new_tree = (*new_node)->children; *new_node = (*new_tree)->root; - while ((*new_node)->right != (*new_tree)->nil) + while (!_gtk_rbtree_is_nil ((*new_node)->right)) *new_node = (*new_node)->right; } } @@ -1416,7 +1397,7 @@ _gtk_rbtree_traverse_pre_order (GtkRBTree *tree, GtkRBTreeTraverseFunc func, gpointer data) { - if (node == tree->nil) + if (_gtk_rbtree_is_nil (node)) return; (* func) (tree, node, data); @@ -1430,7 +1411,7 @@ _gtk_rbtree_traverse_post_order (GtkRBTree *tree, GtkRBTreeTraverseFunc func, gpointer data) { - if (node == tree->nil) + if (_gtk_rbtree_is_nil (node)) return; _gtk_rbtree_traverse_post_order (tree, node->left, func, data); @@ -1472,8 +1453,8 @@ void _fixup_validation (GtkRBTree *tree, { if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID) || GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID) || - (node->left != tree->nil && GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID)) || - (node->right != tree->nil && GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID)) || + GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID) || + GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID) || (node->children != NULL && GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID))) { GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID); @@ -1485,67 +1466,49 @@ void _fixup_validation (GtkRBTree *tree, } static inline -void _fixup_parity (GtkRBTree *tree, +void _fixup_total_count (GtkRBTree *tree, GtkRBNode *node) { - node->parity = 1 + - ((node->children != NULL && node->children->root != node->children->nil) ? node->children->root->parity : 0) + - ((node->left != tree->nil) ? node->left->parity : 0) + - ((node->right != tree->nil) ? node->right->parity : 0); + node->total_count = 1 + + (node->children != NULL ? node->children->root->total_count : 0) + + node->left->total_count + node->right->total_count; } #ifdef G_ENABLE_DEBUG static guint -get_parity (GtkRBNode *node) +get_total_count (GtkRBNode *node) { guint child_total = 0; - guint rem; - - /* The parity of a node is node->parity minus - * the parity of left, right, and children. - * - * This is equivalent to saying that if left, right, children - * sum to 0 parity, then node->parity is the parity of node, - * and if left, right, children are odd parity, then - * node->parity is the reverse of the node's parity. - */ - - child_total += (guint) node->left->parity; - child_total += (guint) node->right->parity; + + child_total += (guint) node->left->total_count; + child_total += (guint) node->right->total_count; if (node->children) - child_total += (guint) node->children->root->parity; + child_total += (guint) node->children->root->total_count; - rem = child_total % 2; - - if (rem == 0) - return node->parity; - else - return !node->parity; + return child_total + 1; } static guint -count_parity (GtkRBTree *tree, - GtkRBNode *node) +count_total (GtkRBTree *tree, + GtkRBNode *node) { guint res; - if (node == tree->nil) + if (_gtk_rbtree_is_nil (node)) return 0; res = - count_parity (tree, node->left) + - count_parity (tree, node->right) + + count_total (tree, node->left) + + count_total (tree, node->right) + (guint)1 + - (node->children ? count_parity (node->children, node->children->root) : 0); + (node->children ? count_total (node->children, node->children->root) : 0); - res = res % (guint)2; - - if (res != node->parity) - g_print ("parity incorrect for node\n"); + if (res != node->total_count) + g_print ("total count incorrect for node\n"); - if (get_parity (node) != 1) - g_error ("Node has incorrect parity %u", get_parity (node)); + if (get_total_count (node) != node->total_count) + g_error ("Node has incorrect total count %u, should be %u", node->total_count, get_total_count (node)); return res; } @@ -1555,7 +1518,7 @@ _count_nodes (GtkRBTree *tree, GtkRBNode *node) { gint res; - if (node == tree->nil) + if (_gtk_rbtree_is_nil (node)) return 0; g_assert (node->left); @@ -1577,25 +1540,25 @@ _gtk_rbtree_test_height (GtkRBTree *tree, /* This whole test is sort of a useless truism. */ - if (node->left != tree->nil) + if (!_gtk_rbtree_is_nil (node->left)) computed_offset += node->left->offset; - if (node->right != tree->nil) + if (!_gtk_rbtree_is_nil (node->right)) computed_offset += node->right->offset; - if (node->children && node->children->root != node->children->nil) + if (node->children && !_gtk_rbtree_is_nil (node->children->root)) computed_offset += node->children->root->offset; if (GTK_RBNODE_GET_HEIGHT (node) + computed_offset != node->offset) g_error ("node has broken offset\n"); - if (node->left != tree->nil) + if (!_gtk_rbtree_is_nil (node->left)) _gtk_rbtree_test_height (tree, node->left); - if (node->right != tree->nil) + if (!_gtk_rbtree_is_nil (node->right)) _gtk_rbtree_test_height (tree, node->right); - if (node->children && node->children->root != node->children->nil) + if (node->children && !_gtk_rbtree_is_nil (node->children->root)) _gtk_rbtree_test_height (node->children, node->children->root); } @@ -1609,27 +1572,27 @@ _gtk_rbtree_test_dirty (GtkRBTree *tree, { g_assert (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID) || GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID) || - (node->left != tree->nil && GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID)) || - (node->right != tree->nil && GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID)) || + GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID) || + GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID) || (node->children && GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID))); } else { g_assert (! GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID) && ! GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID)); - if (node->left != tree->nil) + if (!_gtk_rbtree_is_nil (node->left)) g_assert (! GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID)); - if (node->right != tree->nil) + if (!_gtk_rbtree_is_nil (node->right)) g_assert (! GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID)); if (node->children != NULL) g_assert (! GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID)); } - if (node->left != tree->nil) + if (!_gtk_rbtree_is_nil (node->left)) _gtk_rbtree_test_dirty (tree, node->left, GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID)); - if (node->right != tree->nil) + if (!_gtk_rbtree_is_nil (node->right)) _gtk_rbtree_test_dirty (tree, node->right, GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID)); - if (node->children != NULL && node->children->root != node->children->nil) + if (node->children != NULL && !_gtk_rbtree_is_nil (node->children->root)) _gtk_rbtree_test_dirty (node->children, node->children->root, GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID)); } @@ -1639,18 +1602,18 @@ static void _gtk_rbtree_test_structure_helper (GtkRBTree *tree, GtkRBNode *node) { - g_assert (node != tree->nil); + g_assert (!_gtk_rbtree_is_nil (node)); g_assert (node->left != NULL); g_assert (node->right != NULL); g_assert (node->parent != NULL); - if (node->left != tree->nil) + if (!_gtk_rbtree_is_nil (node->left)) { g_assert (node->left->parent == node); _gtk_rbtree_test_structure_helper (tree, node->left); } - if (node->right != tree->nil) + if (!_gtk_rbtree_is_nil (node->right)) { g_assert (node->right->parent == node); _gtk_rbtree_test_structure_helper (tree, node->right); @@ -1668,14 +1631,14 @@ static void _gtk_rbtree_test_structure (GtkRBTree *tree) { g_assert (tree->root); - if (tree->root == tree->nil) + if (_gtk_rbtree_is_nil (tree->root)) return; - g_assert (tree->root->parent == tree->nil); + g_assert (_gtk_rbtree_is_nil (tree->root->parent)); _gtk_rbtree_test_structure_helper (tree, tree->root); } -void +static void _gtk_rbtree_test (const gchar *where, GtkRBTree *tree) { @@ -1689,9 +1652,7 @@ _gtk_rbtree_test (const gchar *where, while (tmp_tree->parent_tree) tmp_tree = tmp_tree->parent_tree; - g_assert (tmp_tree->nil != NULL); - - if (tmp_tree->root == tmp_tree->nil) + if (_gtk_rbtree_is_nil (tmp_tree->root)) return; _gtk_rbtree_test_structure (tmp_tree); @@ -1702,7 +1663,7 @@ _gtk_rbtree_test (const gchar *where, _gtk_rbtree_test_height (tmp_tree, tmp_tree->root); _gtk_rbtree_test_dirty (tmp_tree, tmp_tree->root, GTK_RBNODE_FLAG_SET (tmp_tree->root, GTK_RBNODE_DESCENDANTS_INVALID)); - g_assert (count_parity (tmp_tree, tmp_tree->root) == tmp_tree->root->parity); + g_assert (count_total (tmp_tree, tmp_tree->root) == tmp_tree->root->total_count); } static void @@ -1718,7 +1679,7 @@ _gtk_rbtree_debug_spew_helper (GtkRBTree *tree, node, (GTK_RBNODE_GET_COLOR (node) == GTK_RBNODE_BLACK)?"BLACK":" RED ", node->offset, - node->parity?1:0, + node->total_count, (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_DESCENDANTS_INVALID))?1:0, (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID))?1:0, (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID))?1:0); @@ -1728,22 +1689,22 @@ _gtk_rbtree_debug_spew_helper (GtkRBTree *tree, _gtk_rbtree_debug_spew (node->children); g_print ("Done looking at child.\n"); } - if (node->left != tree->nil) + if (!_gtk_rbtree_is_nil (node->left)) { _gtk_rbtree_debug_spew_helper (tree, node->left, depth+1); } - if (node->right != tree->nil) + if (!_gtk_rbtree_is_nil (node->right)) { _gtk_rbtree_debug_spew_helper (tree, node->right, depth+1); } } -void +static void _gtk_rbtree_debug_spew (GtkRBTree *tree) { g_return_if_fail (tree != NULL); - if (tree->root == tree->nil) + if (_gtk_rbtree_is_nil (tree->root)) g_print ("Empty tree...\n"); else _gtk_rbtree_debug_spew_helper (tree, tree->root, 0);