예제 #1
0
static void
_gtk_rbtree_debug_spew_helper (GtkRBTree *tree,
			       GtkRBNode *node,
			       gint       depth)
{
  gint i;
  for (i = 0; i < depth; i++)
    g_print ("\t");

  g_print ("(%p - %s) (Offset %d) (Parity %d) (Validity %d%d%d)\n",
	   node,
	   (GTK_RBNODE_GET_COLOR (node) == GTK_RBNODE_BLACK)?"BLACK":" RED ",
	   node->offset,
	   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);
  if (node->children != NULL)
    {
      g_print ("Looking at child.\n");
      _gtk_rbtree_debug_spew (node->children);
      g_print ("Done looking at child.\n");
    }
  if (!_gtk_rbtree_is_nil (node->left))
    {
      _gtk_rbtree_debug_spew_helper (tree, node->left, depth+1);
    }
  if (!_gtk_rbtree_is_nil (node->right))
    {
      _gtk_rbtree_debug_spew_helper (tree, node->right, depth+1);
    }
}
예제 #2
0
GtkRBNode *
_gtk_rbtree_insert_before (GtkRBTree *tree,
			   GtkRBNode *current,
			   gint       height,
			   gboolean   valid)
{
  GtkRBNode *node;
  gboolean left = TRUE;

#ifdef G_ENABLE_DEBUG  
  if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
    {
      g_print ("\n\n_gtk_rbtree_insert_before: %p\n", current);
      _gtk_rbtree_debug_spew (tree);
      _gtk_rbtree_test (G_STRLOC, tree);
    }
#endif /* G_ENABLE_DEBUG */
  
  if (current != NULL && !_gtk_rbtree_is_nil (current->left))
    {
      current = current->left;
      while (!_gtk_rbtree_is_nil (current->right))
	current = current->right;
      left = FALSE;
    }

  /* setup new node */
  node = _gtk_rbnode_new (tree, height);

  /* insert node in tree */
  if (current)
    {
      node->parent = current;
      if (left)
	current->left = node;
      else
	current->right = node;
      gtk_rbnode_adjust (tree, node->parent,
                         1, 1, height);
    }
  else
    {
      g_assert (_gtk_rbtree_is_nil (tree->root));
      tree->root = node;
      gtk_rbnode_adjust (tree->parent_tree, tree->parent_node,
                         0, 1, height);
    }

  if (valid)
    _gtk_rbtree_node_mark_valid (tree, node);
  else
    _gtk_rbtree_node_mark_invalid (tree, node);

  _gtk_rbtree_insert_fixup (tree, node);

#ifdef G_ENABLE_DEBUG  
  if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
    {
      g_print ("_gtk_rbtree_insert_before finished...\n");
      _gtk_rbtree_debug_spew (tree);
      g_print ("\n\n");
      _gtk_rbtree_test (G_STRLOC, tree);
    }
#endif /* G_ENABLE_DEBUG */
  
  return node;
}
예제 #3
0
void
_gtk_rbtree_remove_node (GtkRBTree *tree,
			 GtkRBNode *node)
{
  GtkRBNode *x, *y;
  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_get_debug_flags () & GTK_DEBUG_TREE)
    {
      g_print ("\n\n_gtk_rbtree_remove_node: %p\n", node);
      _gtk_rbtree_debug_spew (tree);
      _gtk_rbtree_test (G_STRLOC, tree);
    }
#endif /* G_ENABLE_DEBUG */
  
  /* make sure we're deleting a node that's actually in the tree */
  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_get_debug_flags () & GTK_DEBUG_TREE)
    _gtk_rbtree_test (G_STRLOC, tree);
#endif
  
  if (_gtk_rbtree_is_nil (node->left) ||
      _gtk_rbtree_is_nil (node->right))
    {
      y = node;
    }
  else
    {
      y = node->right;

      while (!_gtk_rbtree_is_nil (y->left))
	y = y->left;
    }

  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 (!_gtk_rbtree_is_nil (y->left))
    x = y->left;
  else
    x = y->right;

  /* remove y from the parent chain */
  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;
      else
	y->parent->right = x;
    }
  else
    {
      tree->root = x;
    }

  /* We need to clean up the validity of the tree.
   */
  gtk_rbnode_adjust (tree, y, -1, - y_total_count, - y_height);

  if (GTK_RBNODE_GET_COLOR (y) == GTK_RBNODE_BLACK)
    _gtk_rbtree_remove_node_fixup (tree, x, y->parent);

  if (y != node)
    {
      gint node_height, node_total_count;

      /* We want to see how much we remove from the aggregate values.
       * This is all the children we remove plus the node's values.
       */
      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;

      gtk_rbnode_adjust (tree, y, 
                         0,
                         y_total_count - node_total_count,
                         y_height - node_height);
    }

  _gtk_rbnode_free (node);

#ifdef G_ENABLE_DEBUG  
  if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
    {
      g_print ("_gtk_rbtree_remove_node finished...\n");
      _gtk_rbtree_debug_spew (tree);
      g_print ("\n\n");
      _gtk_rbtree_test (G_STRLOC, tree);
    }
#endif /* G_ENABLE_DEBUG */  
}
예제 #4
0
파일: gtkrbtree.c 프로젝트: sam-m888/gtk
GtkRBNode *
_gtk_rbtree_insert_before (GtkRBTree *tree,
			   GtkRBNode *current,
			   gint       height,
			   gboolean   valid)
{
  GtkRBNode *node;
  gboolean left = TRUE;

#ifdef G_ENABLE_DEBUG
  if (GTK_DEBUG_CHECK (TREE))
    {
      GString *s;

      s = g_string_new ("");
      g_string_append_printf (s, "_gtk_rbtree_insert_before: %p\n", current);
      _gtk_rbtree_debug_spew (tree, s);
      g_message ("%s", s->str);
      g_string_free (s, TRUE);
      _gtk_rbtree_test (G_STRLOC, tree);
    }
#endif

  if (current != NULL && !_gtk_rbtree_is_nil (current->left))
    {
      current = current->left;
      while (!_gtk_rbtree_is_nil (current->right))
	current = current->right;
      left = FALSE;
    }

  /* setup new node */
  node = _gtk_rbnode_new (tree, height);

  /* insert node in tree */
  if (current)
    {
      node->parent = current;
      if (left)
	current->left = node;
      else
	current->right = node;
      gtk_rbnode_adjust (tree, node->parent,
                         1, 1, height);
    }
  else
    {
      g_assert (_gtk_rbtree_is_nil (tree->root));
      tree->root = node;
      gtk_rbnode_adjust (tree->parent_tree, tree->parent_node,
                         0, 1, height);
    }

  if (valid)
    _gtk_rbtree_node_mark_valid (tree, node);
  else
    _gtk_rbtree_node_mark_invalid (tree, node);

  _gtk_rbtree_insert_fixup (tree, node);

#ifdef G_ENABLE_DEBUG
  if (GTK_DEBUG_CHECK (TREE))
    {
      GString *s;

      s = g_string_new ("_gtk_rbtree_insert_before finished...\n");
      _gtk_rbtree_debug_spew (tree, s);
      g_message ("%s", s->str);
      g_string_free (s, TRUE);
      _gtk_rbtree_test (G_STRLOC, tree);
    }
#endif

  return node;
}
예제 #5
0
파일: gtkrbtree.c 프로젝트: Aridna/gtk2
GtkRBNode *
_gtk_rbtree_insert_before (GtkRBTree *tree,
			   GtkRBNode *current,
			   gint       height,
			   gboolean   valid)
{
  GtkRBNode *node;
  gboolean left = TRUE;
  GtkRBNode *tmp_node;
  GtkRBTree *tmp_tree;

#ifdef G_ENABLE_DEBUG  
  if (gtk_debug_flags & GTK_DEBUG_TREE)
    {
      g_print ("\n\n_gtk_rbtree_insert_before: %p\n", current);
      _gtk_rbtree_debug_spew (tree);
      _gtk_rbtree_test (G_STRLOC, tree);
    }
#endif /* G_ENABLE_DEBUG */
  
  if (current != NULL && current->left != tree->nil)
    {
      current = current->left;
      while (current->right != tree->nil)
	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)
    {
      if (left)
	current->left = node;
      else
	current->right = node;
      tmp_node = node->parent;
      tmp_tree = tree;
    }
  else
    {
      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;
	}
    }

  if (valid)
    _gtk_rbtree_node_mark_valid (tree, node);
  else
    _gtk_rbtree_node_mark_invalid (tree, node);

  _gtk_rbtree_insert_fixup (tree, node);

#ifdef G_ENABLE_DEBUG  
  if (gtk_debug_flags & GTK_DEBUG_TREE)
    {
      g_print ("_gtk_rbtree_insert_before finished...\n");
      _gtk_rbtree_debug_spew (tree);
      g_print ("\n\n");
      _gtk_rbtree_test (G_STRLOC, tree);
    }
#endif /* G_ENABLE_DEBUG */
  
  return node;
}
예제 #6
0
파일: gtkrbtree.c 프로젝트: Aridna/gtk2
void
_gtk_rbtree_remove_node (GtkRBTree *tree,
			 GtkRBNode *node)
{
  GtkRBNode *x, *y;
  GtkRBTree *tmp_tree;
  GtkRBNode *tmp_node;
  gint y_height;
  
  g_return_if_fail (tree != NULL);
  g_return_if_fail (node != NULL);

  
#ifdef G_ENABLE_DEBUG
  if (gtk_debug_flags & GTK_DEBUG_TREE)
    {
      g_print ("\n\n_gtk_rbtree_remove_node: %p\n", node);
      _gtk_rbtree_debug_spew (tree);
      _gtk_rbtree_test (G_STRLOC, 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)
    ;
  g_return_if_fail (x == tree->root);

#ifdef G_ENABLE_DEBUG  
  if (gtk_debug_flags & GTK_DEBUG_TREE)
    _gtk_rbtree_test (G_STRLOC, tree);
#endif
  
  if (node->left == tree->nil || node->right == tree->nil)
    {
      y = node;
    }
  else
    {
      y = node->right;

      while (y->left != tree->nil)
	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;
	}
    }

  /* x is y's only child, or nil */
  if (y->left != tree->nil)
    x = y->left;
  else
    x = y->right;

  /* remove y from the parent chain */
  x->parent = y->parent;
  if (y->parent != tree->nil)
    {
      if (y == y->parent->left)
	y->parent->left = x;
      else
	y->parent->right = x;
    }
  else
    {
      tree->root = x;
    }

  /* We need to clean up the validity of the tree.
   */

  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 (y != node)
    {
      gint diff;

      /* 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.
       */
      diff = y_height - GTK_RBNODE_GET_HEIGHT (node);
      tmp_tree = tree;
      tmp_node = node;

      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;
	    }
	}
    }

  if (GTK_RBNODE_GET_COLOR (y) == GTK_RBNODE_BLACK)
    _gtk_rbtree_remove_node_fixup (tree, x);
  _gtk_rbnode_free (y);

#ifdef G_ENABLE_DEBUG  
  if (gtk_debug_flags & GTK_DEBUG_TREE)
    {
      g_print ("_gtk_rbtree_remove_node finished...\n");
      _gtk_rbtree_debug_spew (tree);
      g_print ("\n\n");
      _gtk_rbtree_test (G_STRLOC, tree);
    }
#endif /* G_ENABLE_DEBUG */  
}