summaryrefslogtreecommitdiff
path: root/subprojects/gfm/gtkrbtree.c
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/gfm/gtkrbtree.c')
-rw-r--r--subprojects/gfm/gtkrbtree.c800
1 files changed, 0 insertions, 800 deletions
diff --git a/subprojects/gfm/gtkrbtree.c b/subprojects/gfm/gtkrbtree.c
deleted file mode 100644
index 8d706467..00000000
--- a/subprojects/gfm/gtkrbtree.c
+++ /dev/null
@@ -1,800 +0,0 @@
-/* gtkrbtree.c
- * Copyright (C) 2000 Red Hat, Inc., Jonathan Blandford <jrb@redhat.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-// #include "config.h"
-
-#include "gtkrbtreeprivate.h"
-
-// #include "gtkdebug.h"
-
-/* Define the following to print adds and removals to stdout.
- * The format of the printout will be suitable for addition as a new test to
- * testsuite/gtk/rbtree-crash.c
- * by just grepping the printouts from the relevant rbtree.
- *
- * This is meant to be a trivial way to add rbtree tests to the testsuite.
- */
-#undef DUMP_MODIFICATION
-
-typedef struct _GtkRbNode GtkRbNode;
-
-struct _GtkRbTree
-{
- guint ref_count;
-
- gsize element_size;
- gsize augment_size;
- GtkRbTreeAugmentFunc augment_func;
- GDestroyNotify clear_func;
- GDestroyNotify clear_augment_func;
-
- GtkRbNode *root;
-};
-
-struct _GtkRbNode
-{
- guint red :1;
- guint dirty :1;
-
- GtkRbNode *left;
- GtkRbNode *right;
- /* The difference between tree and parent here is that we OR the tree with 1 and because
- * pointers are always multiples of 4, we can know if we've stored a parent or the tree here */
- union {
- gpointer parent_or_tree;
- GtkRbNode *parent;
- GtkRbTree *tree;
- };
-};
-
-#define NODE_FROM_POINTER(ptr) ((GtkRbNode *) ((ptr) ? (((guchar *) (ptr)) - sizeof (GtkRbNode)) : NULL))
-#define NODE_TO_POINTER(node) ((gpointer) ((node) ? (((guchar *) (node)) + sizeof (GtkRbNode)) : NULL))
-#define NODE_TO_AUG_POINTER(tree, node) ((gpointer) ((node) ? (((guchar *) (node)) + sizeof (GtkRbNode) + (tree)->element_size) : NULL))
-
-static inline gboolean
-is_root (GtkRbNode *node)
-{
- return GPOINTER_TO_SIZE (node->parent_or_tree) & 1 ? TRUE : FALSE;
-}
-
-static inline GtkRbNode *
-parent (GtkRbNode *node)
-{
- if (is_root (node))
- return NULL;
- else
- return node->parent;
-}
-
-static GtkRbTree *
-tree (GtkRbNode *node)
-{
- while (!is_root (node))
- node = parent (node);
-
- return GSIZE_TO_POINTER (GPOINTER_TO_SIZE (node->tree) & ~1);
-}
-
-static void
-set_parent (GtkRbTree *tree,
- GtkRbNode *node,
- GtkRbNode *new_parent)
-{
-
- if (new_parent != NULL)
- {
- node->parent = new_parent;
- }
- else
- {
- node->tree = GSIZE_TO_POINTER (GPOINTER_TO_SIZE (tree) | 1);
- tree->root = node;
- }
-}
-
-static inline gsize
-gtk_rb_node_get_size (GtkRbTree *tree)
-{
- return sizeof (GtkRbNode) + tree->element_size + tree->augment_size;
-}
-
-static GtkRbNode *
-gtk_rb_node_new (GtkRbTree *tree)
-{
- GtkRbNode *result;
-
- result = g_slice_alloc0 (gtk_rb_node_get_size (tree));
-
- result->red = TRUE;
- result->dirty = TRUE;
-
- return result;
-}
-
-static void
-gtk_rb_node_free (GtkRbTree *tree,
- GtkRbNode *node)
-{
- if (tree->clear_func)
- tree->clear_func (NODE_TO_POINTER (node));
- if (tree->clear_augment_func)
- tree->clear_augment_func (NODE_TO_AUG_POINTER (tree, node));
-
- g_slice_free1 (gtk_rb_node_get_size (tree), node);
-}
-
-static void
-gtk_rb_node_free_deep (GtkRbTree *tree,
- GtkRbNode *node)
-{
- GtkRbNode *right = node->right;
-
- if (node->left)
- gtk_rb_node_free_deep (tree, node->left);
-
- gtk_rb_node_free (tree, node);
-
- if (right)
- gtk_rb_node_free_deep (tree, right);
-}
-
-static void
-gtk_rb_node_mark_dirty (GtkRbNode *node,
- gboolean mark_parent)
-{
- if (node->dirty)
- return;
-
- node->dirty = TRUE;
-
- if (mark_parent && parent (node))
- gtk_rb_node_mark_dirty (parent (node), TRUE);
-}
-
-static void
-gtk_rb_node_clean (GtkRbTree *tree,
- GtkRbNode *node)
-{
- if (!node->dirty)
- return;
-
- node->dirty = FALSE;
- if (tree->augment_func)
- tree->augment_func (tree,
- NODE_TO_AUG_POINTER (tree, node),
- NODE_TO_POINTER (node),
- NODE_TO_POINTER (node->left),
- NODE_TO_POINTER (node->right));
-}
-
-static GtkRbNode *
-gtk_rb_node_get_first (GtkRbNode *node)
-{
- while (node->left)
- node = node->left;
-
- return node;
-}
-
-static GtkRbNode *
-gtk_rb_node_get_last (GtkRbNode *node)
-{
- while (node->right)
- node = node->right;
-
- return node;
-}
-
-static GtkRbNode *
-gtk_rb_node_get_previous (GtkRbNode *node)
-{
- GtkRbNode *p;
-
- if (node->left)
- return gtk_rb_node_get_last (node->left);
-
- for (p = parent (node); p != NULL; p = parent (node))
- {
- if (p->right == node)
- return p;
-
- node = p;
- }
-
- return NULL;
-}
-
-static GtkRbNode *
-gtk_rb_node_get_next (GtkRbNode *node)
-{
- GtkRbNode *p;
-
- if (node->right)
- return gtk_rb_node_get_first (node->right);
-
- for (p = parent (node); p != NULL; p = parent (node))
- {
- if (p->left == node)
- return p;
-
- node = p;
- }
-
- return NULL;
-}
-
-#ifdef DUMP_MODIFICATION
-static guint
-position (GtkRbTree *tree,
- GtkRbNode *node)
-{
- GtkRbNode *n;
- guint i;
-
- i = 0;
- for (n = gtk_rb_node_get_first (tree->root);
- n != node;
- n = gtk_rb_node_get_next (n))
- i++;
-
- return i;
-}
-#endif
-
-static void
-gtk_rb_node_rotate_left (GtkRbTree *tree,
- GtkRbNode *node)
-{
- GtkRbNode *right, *p;
-
- right = node->right;
- p = parent (node);
-
- node->right = right->left;
- if (right->left)
- set_parent (tree, right->left, node);
-
- set_parent (tree, right, p);
- if (p)
- {
- if (node == p->left)
- p->left = right;
- else
- p->right = right;
- }
-
- right->left = node;
- set_parent (tree, node, right);
-
- gtk_rb_node_mark_dirty (node, FALSE);
- gtk_rb_node_mark_dirty (right, FALSE);
-}
-
-static void
-gtk_rb_node_rotate_right (GtkRbTree *tree,
- GtkRbNode *node)
-{
- GtkRbNode *left, *p;
-
- left = node->left;
- p = parent (node);
-
- node->left = left->right;
- if (left->right)
- set_parent (tree, left->right, node);
-
- set_parent (tree, left, p);
- if (p)
- {
- if (node == p->right)
- p->right = left;
- else
- p->left = left;
- }
-
- /* link node and left */
- left->right = node;
- set_parent (tree, node, left);
-
- gtk_rb_node_mark_dirty (node, FALSE);
- gtk_rb_node_mark_dirty (left, FALSE);
-}
-
-static gboolean
-is_red (GtkRbNode *node_or_null)
-{
- if (node_or_null == NULL)
- return FALSE;
- else
- return node_or_null->red;
-}
-
-static inline gboolean
-is_black (GtkRbNode *node_or_null)
-{
- return !is_red (node_or_null);
-}
-
-static void
-set_black (GtkRbNode *node_or_null)
-{
- if (node_or_null == NULL)
- return;
-
- node_or_null->red = FALSE;
-}
-
-static void
-set_red (GtkRbNode *node_or_null)
-{
- if (node_or_null == NULL)
- return;
-
- node_or_null->red = TRUE;
-}
-
-static void
-gtk_rb_tree_insert_fixup (GtkRbTree *tree,
- GtkRbNode *node)
-{
- GtkRbNode *p;
-
- /* check Red-Black properties */
- for (p = parent (node);
- p && is_red (p);
- p = parent (node))
- {
- GtkRbNode *pp = parent (p);
-
- /* we have a violation */
- g_assert (pp);
-
- if (p == pp->left)
- {
- GtkRbNode *uncle = pp->right;
-
- if (is_red (uncle))
- {
- /* uncle is red */
- set_black (p);
- set_black (uncle);
- set_red (pp);
- node = pp;
- }
- else
- {
- /* uncle is black */
- if (node == p->right)
- {
- /* make node a left child */
- node = p;
- gtk_rb_node_rotate_left (tree, node);
- p = parent (node);
- pp = parent (p);
- }
- /* recolor and rotate */
- set_black (p);
- set_red (pp);
- gtk_rb_node_rotate_right (tree, pp);
- }
- }
- else
- {
- /* mirror image of above code */
- GtkRbNode *uncle = pp->left;
-
- if (is_red (uncle))
- {
- /* uncle is red */
- set_black (p);
- set_black (uncle);
- set_red (pp);
- node = pp;
- }
- else
- {
- /* uncle is black */
- if (node == p->left)
- {
- node = p;
- gtk_rb_node_rotate_right (tree, node);
- p = parent (node);
- pp = parent (p);
- }
- set_black (p);
- set_red (pp);
- gtk_rb_node_rotate_left (tree, pp);
- }
- }
- }
-
- set_black (tree->root);
-}
-
-static void
-gtk_rb_tree_remove_node_fixup (GtkRbTree *tree,
- GtkRbNode *node,
- GtkRbNode *p)
-{
- while (node != tree->root && is_black (node))
- {
- if (node == p->left)
- {
- GtkRbNode *w = p->right;
-
- if (is_red (w))
- {
- set_black (w);
- set_red (p);
- gtk_rb_node_rotate_left (tree, p);
- w = p->right;
- }
- if (is_black (w->left) && is_black (w->right))
- {
- set_red (w);
- node = p;
- }
- else
- {
- if (is_black (w->right))
- {
- set_black (w->left);
- set_red (w);
- gtk_rb_node_rotate_right (tree, w);
- w = p->right;
- }
- w->red = p->red;
- set_black (p);
- set_black (w->right);
- gtk_rb_node_rotate_left (tree, p);
- node = tree->root;
- }
- }
- else
- {
- GtkRbNode *w = p->left;
- if (is_red (w))
- {
- set_black (w);
- set_red (p);
- gtk_rb_node_rotate_right (tree, p);
- w = p->left;
- }
- if (is_black (w->right) && is_black (w->left))
- {
- set_red (w);
- node = p;
- }
- else
- {
- if (is_black (w->left))
- {
- set_black (w->right);
- set_red (w);
- gtk_rb_node_rotate_left (tree, w);
- w = p->left;
- }
- w->red = p->red;
- set_black (p);
- set_black (w->left);
- gtk_rb_node_rotate_right (tree, p);
- node = tree->root;
- }
- }
-
- p = parent (node);
- }
-
- set_black (node);
-}
-
-GtkRbTree *
-gtk_rb_tree_new_for_size (gsize element_size,
- gsize augment_size,
- GtkRbTreeAugmentFunc augment_func,
- GDestroyNotify clear_func,
- GDestroyNotify clear_augment_func)
-{
- GtkRbTree *tree;
-
- tree = g_slice_new0 (GtkRbTree);
- tree->ref_count = 1;
-
- tree->element_size = element_size;
- tree->augment_size = augment_size;
- tree->augment_func = augment_func;
- tree->clear_func = clear_func;
- tree->clear_augment_func = clear_augment_func;
-
- return tree;
-}
-
-GtkRbTree *
-gtk_rb_tree_ref (GtkRbTree *tree)
-{
- tree->ref_count++;
-
- return tree;
-}
-
-void
-gtk_rb_tree_unref (GtkRbTree *tree)
-{
- tree->ref_count--;
- if (tree->ref_count > 0)
- return;
-
- if (tree->root)
- gtk_rb_node_free_deep (tree, tree->root);
-
- g_slice_free (GtkRbTree, tree);
-}
-
-gpointer
-gtk_rb_tree_get_first (GtkRbTree *tree)
-{
- if (tree->root == NULL)
- return NULL;
-
- return NODE_TO_POINTER (gtk_rb_node_get_first (tree->root));
-}
-
-gpointer
-gtk_rb_tree_get_last (GtkRbTree *tree)
-{
- if (tree->root == NULL)
- return NULL;
-
- return NODE_TO_POINTER (gtk_rb_node_get_last (tree->root));
-}
-
-gpointer
-gtk_rb_tree_node_get_previous (gpointer node)
-{
- return NODE_TO_POINTER (gtk_rb_node_get_previous (NODE_FROM_POINTER (node)));
-}
-
-gpointer
-gtk_rb_tree_node_get_next (gpointer node)
-{
- return NODE_TO_POINTER (gtk_rb_node_get_next (NODE_FROM_POINTER (node)));
-}
-
-gpointer
-gtk_rb_tree_get_root (GtkRbTree *tree)
-{
- return NODE_TO_POINTER (tree->root);
-}
-
-gpointer
-gtk_rb_tree_node_get_parent (gpointer node)
-{
- return NODE_TO_POINTER (parent (NODE_FROM_POINTER (node)));
-}
-
-gpointer
-gtk_rb_tree_node_get_left (gpointer node)
-{
- return NODE_TO_POINTER (NODE_FROM_POINTER (node)->left);
-}
-
-gpointer
-gtk_rb_tree_node_get_right (gpointer node)
-{
- return NODE_TO_POINTER (NODE_FROM_POINTER (node)->right);
-}
-
-gpointer
-gtk_rb_tree_get_augment (GtkRbTree *tree,
- gpointer node)
-{
- GtkRbNode *rbnode = NODE_FROM_POINTER (node);
-
- gtk_rb_node_clean (tree, rbnode);
-
- return NODE_TO_AUG_POINTER (tree, rbnode);
-}
-
-GtkRbTree *
-gtk_rb_tree_node_get_tree (gpointer node)
-{
- return tree (NODE_FROM_POINTER (node));
-}
-
-void
-gtk_rb_tree_node_mark_dirty (gpointer node)
-{
- gtk_rb_node_mark_dirty (NODE_FROM_POINTER (node), TRUE);
-}
-
-gpointer
-gtk_rb_tree_insert_before (GtkRbTree *tree,
- gpointer node)
-{
- GtkRbNode *result;
-
-
- if (tree->root == NULL)
- {
-#ifdef DUMP_MODIFICATION
- g_print ("add (tree, 0); /* 0x%p */\n", tree);
-#endif /* DUMP_MODIFICATION */
-
- g_assert (node == NULL);
-
- result = gtk_rb_node_new (tree);
- tree->root = result;
- }
- else if (node == NULL)
- {
- return gtk_rb_tree_insert_after (tree, gtk_rb_tree_get_last (tree));
- }
- else
- {
- GtkRbNode *current = NODE_FROM_POINTER (node);
-
-#ifdef DUMP_MODIFICATION
- g_print ("add (tree, %u); /* 0x%p */\n", position (tree, current), tree);
-#endif /* DUMP_MODIFICATION */
-
- /* setup new node */
- result = gtk_rb_node_new (tree);
-
- if (current->left)
- {
- current = gtk_rb_node_get_last (current->left);
- current->right = result;
- }
- else
- {
- current->left = result;
- }
- set_parent (tree, result, current);
- gtk_rb_node_mark_dirty (current, TRUE);
- }
-
- gtk_rb_tree_insert_fixup (tree, result);
-
- return NODE_TO_POINTER (result);
-}
-
-gpointer
-gtk_rb_tree_insert_after (GtkRbTree *tree,
- gpointer node)
-{
- GtkRbNode *current, *result;
-
- if (node == NULL)
- return gtk_rb_tree_insert_before (tree, gtk_rb_tree_get_first (tree));
-
- current = NODE_FROM_POINTER (node);
-
-#ifdef DUMP_MODIFICATION
- g_print ("add (tree, %u); /* 0x%p */\n", position (tree, current) + 1, tree);
-#endif /* DUMP_MODIFICATION */
-
- /* setup new node */
- result = gtk_rb_node_new (tree);
-
- if (current->right)
- {
- current = gtk_rb_node_get_first (current->right);
- current->left = result;
- }
- else
- {
- current->right = result;
- }
- set_parent (tree, result, current);
- gtk_rb_node_mark_dirty (current, TRUE);
-
- gtk_rb_tree_insert_fixup (tree, result);
-
- return NODE_TO_POINTER (result);
-}
-
-void
-gtk_rb_tree_remove (GtkRbTree *tree,
- gpointer node)
-{
- GtkRbNode *x, *y, *p, *real_node;
-
- real_node = NODE_FROM_POINTER (node);
-
-#ifdef DUMP_MODIFICATION
- g_print ("delete (tree, %u); /* 0x%p */\n", position (tree, real_node), tree);
-#endif /* DUMP_MODIFICATION */
-
- y = real_node;
- if (y->left && y->right)
- {
- y = y->right;
-
- while (y->left)
- y = y->left;
- }
-
- /* x is y's only child, or nil */
- if (y->left)
- x = y->left;
- else
- x = y->right;
-
- /* remove y from the parent chain */
- p = parent (y);
- if (x != NULL)
- set_parent (tree, x, p);
- if (p)
- {
- if (y == p->left)
- p->left = x;
- else
- p->right = x;
- gtk_rb_node_mark_dirty (p, TRUE);
- }
- else
- {
- if (x == NULL)
- tree->root = NULL;
- }
-
- /* We need to clean up the validity of the tree.
- */
- if (is_black (y))
- gtk_rb_tree_remove_node_fixup (tree, x, p);
-
- if (y != real_node)
- {
- /* Move the node over */
- if (is_red (real_node) != is_red (y))
- y->red = !y->red;
-
- y->left = real_node->left;
- if (y->left)
- set_parent (tree, y->left, y);
- y->right = real_node->right;
- if (y->right)
- set_parent (tree, y->right, y);
- p = parent (real_node);
- set_parent (tree, y, p);
- if (p)
- {
- if (p->left == real_node)
- p->left = y;
- else
- p->right = y;
- gtk_rb_node_mark_dirty (p, TRUE);
- }
- gtk_rb_node_mark_dirty (y, TRUE);
- }
-
- gtk_rb_node_free (tree, real_node);
-}
-
-void
-gtk_rb_tree_remove_all (GtkRbTree *tree)
-{
-#ifdef DUMP_MODIFICATION
- g_print ("delete_all (tree); /* 0x%p */\n", tree);
-#endif /* DUMP_MODIFICATION */
-
- if (tree->root)
- gtk_rb_node_free_deep (tree, tree->root);
-
- tree->root = NULL;
-}
-