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

# Content
1 /*
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 }