コード例 #1
0
ファイル: gtkrbtree.c プロジェクト: Aridna/gtk2
static void
_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);
  
  node->left = left->right;
  if (left->right != tree->nil)
    left->right->parent = node;

  if (left != tree->nil)
    left->parent = node->parent;
  if (node->parent != tree->nil)
    {
      if (node == node->parent->right)
	node->parent->right = left;
      else
	node->parent->left = left;
    }
  else
    {
      tree->root = left;
    }

  /* 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);

  _fixup_validation (tree, node);
  _fixup_validation (tree, left);
  _fixup_parity (tree, node);
  _fixup_parity (tree, left);
}
コード例 #2
0
ファイル: gtkrbtree.c プロジェクト: Aridna/gtk2
static void
_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);
  node->right = right->left;
  if (right->left != tree->nil)
    right->left->parent = node;

  if (right != tree->nil)
    right->parent = node->parent;
  if (node->parent != tree->nil)
    {
      if (node == node->parent->left)
	node->parent->left = right;
      else
	node->parent->right = right;
    } else {
      tree->root = right;
    }

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

  _fixup_validation (tree, node);
  _fixup_validation (tree, right);
  _fixup_parity (tree, node);
  _fixup_parity (tree, right);
}
コード例 #3
0
ファイル: gtkrbtree.c プロジェクト: 3dfxmadscientist/gtk
static void
_gtk_rbnode_rotate_right (GtkRBTree *tree,
			  GtkRBNode *node)
{
  gint node_height, left_height;
  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 (!_gtk_rbtree_is_nil (left->right))
    left->right->parent = node;

  left->parent = node->parent;
  if (!_gtk_rbtree_is_nil (node->parent))
    {
      if (node == node->parent->right)
	node->parent->right = left;
      else
	node->parent->left = left;
    }
  else
    {
      tree->root = left;
    }

  /* link node and left */
  left->right = node;
  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_total_count (tree, node);
  _fixup_total_count (tree, left);
}
コード例 #4
0
ファイル: gtkrbtree.c プロジェクト: 3dfxmadscientist/gtk
static void
_gtk_rbnode_rotate_left (GtkRBTree *tree,
			 GtkRBNode *node)
{
  gint node_height, right_height;
  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 (!_gtk_rbtree_is_nil (right->left))
    right->left->parent = node;

  right->parent = node->parent;
  if (!_gtk_rbtree_is_nil (node->parent))
    {
      if (node == node->parent->left)
	node->parent->left = right;
      else
	node->parent->right = right;
    } else {
      tree->root = right;
    }

  right->left = node;
  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_total_count (tree, node);
  _fixup_total_count (tree, right);
}
コード例 #5
0
ファイル: gtkrbtree.c プロジェクト: 3dfxmadscientist/gtk
static void
reorder_fixup (GtkRBTree *tree,
               GtkRBNode *node,
               gpointer   data)
{
  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);
}
コード例 #6
0
ファイル: gtkrbtree.c プロジェクト: 3dfxmadscientist/gtk
/* Draconian version. */
void
_gtk_rbtree_node_mark_invalid (GtkRBTree *tree,
			       GtkRBNode *node)
{
  GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_INVALID);
  do
    {
      _fixup_validation (tree, node);
      node = node->parent;
      if (_gtk_rbtree_is_nil (node))
	{
	  node = tree->parent_node;
	  tree = tree->parent_tree;
	}
    }
  while (node);
}
コード例 #7
0
ファイル: gtkrbtree.c プロジェクト: Aridna/gtk2
void
_gtk_rbtree_remove (GtkRBTree *tree)
{
  GtkRBTree *tmp_tree;
  GtkRBNode *tmp_node;

  gint height = tree->root->offset;

#ifdef G_ENABLE_DEBUG  
  if (gtk_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;
	}
    }

  tmp_tree = tree->parent_tree;
  tmp_node = tree->parent_node;
  _gtk_rbtree_free (tree);

#ifdef G_ENABLE_DEBUG  
  if (gtk_debug_flags & GTK_DEBUG_TREE)
    _gtk_rbtree_test (G_STRLOC, tmp_tree);
#endif
}
コード例 #8
0
ファイル: gtkrbtree.c プロジェクト: Aridna/gtk2
/* Draconian version */
void
_gtk_rbtree_node_mark_valid (GtkRBTree *tree,
			     GtkRBNode *node)
{
  GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_INVALID);
  GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_COLUMN_INVALID);

  do
    {
      _fixup_validation (tree, node);
      node = node->parent;
      if (node == tree->nil)
	{
	  node = tree->parent_node;
	  tree = tree->parent_tree;
	}
    }
  while (node);
}
コード例 #9
0
ファイル: gtkrbtree.c プロジェクト: 3dfxmadscientist/gtk
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;
	}
    }
}
コード例 #10
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 */  
}