ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/vendor/pxys2-2.0.0/pxyservd/dbprim/rt_add.c
Revision: 3252
Committed: Wed Apr 2 20:41:43 2014 UTC (11 years, 4 months ago) by michael
Content type: text/x-csrc
File size: 3557 byte(s)
Log Message:
- Imported pxys2-2.0.0

File Contents

# User Rev Content
1 michael 3252 /*
2     ** Copyright (C) 2003 by Kevin L. Mitchell <klmitch@mit.edu>
3     **
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.
8     **
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.
13     **
14     ** You should have received a copy of the GNU Library General Public
15     ** License along with this library; if not, write to the Free
16     ** Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
17     ** MA 02111-1307, USA
18     **
19     ** @(#)$Id: rt_add.c,v 1.1 2003/06/28 18:48:21 klmitch Exp $
20     */
21     #include "dbprim.h"
22     #include "dbprim_int.h"
23    
24     RCSTAG("@(#)$Id: rt_add.c,v 1.1 2003/06/28 18:48:21 klmitch Exp $");
25    
26     /* Locate the uncle of the given node */
27     #define uncle(node) (rn_isleft((node)->rn_parent) ? \
28     (node)->rn_parent->rn_parent->rn_right : \
29     (node)->rn_parent->rn_parent->rn_left)
30    
31     /* Flip the color of the given node */
32     #define flip(node) ((node)->rn_color = \
33     ((node)->rn_color == RB_COLOR_BLACK) ? \
34     RB_COLOR_RED : RB_COLOR_BLACK)
35    
36     /** \ingroup dbprim_rbtree
37     * \brief Add a node to a red-black tree.
38     *
39     * This function adds a node to a red-black tree.
40     *
41     * \param tree A pointer to a #rb_tree_t.
42     * \param node A pointer to a #rb_node_t to be added to the tree.
43     * \param key A pointer to a #db_key_t containing the key for the
44     * node.
45     *
46     * \retval DB_ERR_BADARGS An invalid argument was given.
47     * \retval DB_ERR_BUSY The node is already in a tree.
48     * \retval DB_ERR_FROZEN The tree is currently frozen.
49     * \retval DB_ERR_DUPLICATE The entry is a duplicate of an
50     * existing node.
51     */
52     unsigned long
53     rt_add(rb_tree_t *tree, rb_node_t *node, db_key_t *key)
54     {
55     initialize_dbpr_error_table(); /* initialize error table */
56    
57     if (!rt_verify(tree) || !rn_verify(node) || !key) /* verify arguments */
58     return DB_ERR_BADARGS;
59    
60     if (node->rn_tree) /* it's already in a tree... */
61     return DB_ERR_BUSY;
62    
63     if (tree->rt_flags & RBT_FLAG_FREEZE) /* don't add to frozen trees */
64     return DB_ERR_FROZEN;
65    
66     if (_rb_locate(tree, node, key) != node) /* add it to the tree... */
67     return DB_ERR_DUPLICATE; /* We don't allow duplication! */
68    
69     /* OK, node has been added, now let's rebalance the tree... */
70     while (!rn_isblack(node) && !rn_isblack(node->rn_parent))
71     if (rn_isred(uncle(node))) {
72     flip(node->rn_parent); /* Flip the colors of parent and grandparent */
73     flip(node->rn_parent->rn_parent);
74     flip(uncle(node)); /* and flip the color of the uncle */
75     node = node->rn_parent->rn_parent; /* grandparent need balancing? */
76     } else if ((rn_isleft(node->rn_parent) && rn_isright(node)) ||
77     (rn_isright(node->rn_parent) && rn_isleft(node))) {
78     flip(node); /* flip the colors that need flipping... */
79     flip(node->rn_parent->rn_parent);
80     _rb_rotate(tree, node); /* rotate the node up two levels */
81     _rb_rotate(tree, node);
82     } else {
83     flip(node->rn_parent); /* flip the colors that need flipping... */
84     flip(node->rn_parent->rn_parent);
85     _rb_rotate(tree, node->rn_parent); /* move the parent up a level */
86     node = node->rn_parent; /* new parent need balancing? */
87     }
88    
89     /* Make sure the root node is black */
90     tree->rt_root->rn_color = RB_COLOR_BLACK;
91    
92     return 0;
93     }