source: rtems/cpukit/score/include/rtems/score/rbtreeimpl.h @ 0ef6e3bf

4.115
Last change on this file since 0ef6e3bf was 993f5ac, checked in by Sebastian Huber <sebastian.huber@…>, on 07/23/14 at 11:03:54

rbtree: Simplify insert and extract

Simplify _RBTree_Insert() and _RBTree_Extract(). Remove more
superfluous NULL pointer checks. Change _RBTree_Is_root() to use only
the node. Add parent parameter to _RBTree_Sibling(). Delete
_RBTree_Grandparent() and _RBTree_Parent_sibling().

  • Property mode set to 100644
File size: 4.7 KB
Line 
1/**
2 * @file
3 *
4 * @brief Inlined Routines Associated with Red-Black Trees
5 *
6 * This include file contains the bodies of the routines which are
7 * associated with Red-Black Trees and inlined.
8 *
9 * @note  The routines in this file are ordered from simple
10 *        to complex.  No other RBTree Handler routine is referenced
11 *        unless it has already been defined.
12 */
13
14/*
15 *  Copyright (c) 2010-2012 Gedare Bloom.
16 *
17 *  The license and distribution terms for this file may be
18 *  found in the file LICENSE in this distribution or at
19 *  http://www.rtems.org/license/LICENSE.
20 */
21
22#ifndef _RTEMS_SCORE_RBTREEIMPL_H
23#define _RTEMS_SCORE_RBTREEIMPL_H
24
25#include <rtems/score/rbtree.h>
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31/**
32 * @addtogroup ScoreRBTree
33 */
34/**@{**/
35
36/**
37 * @brief Red-black tree visitor.
38 *
39 * @param[in] node The node.
40 * @param[in] dir The direction.
41 * @param[in] visitor_arg The visitor argument.
42 *
43 * @retval true Stop the iteration.
44 * @retval false Continue the iteration.
45 *
46 * @see _RBTree_Iterate().
47 */
48typedef bool (*RBTree_Visitor)(
49  const RBTree_Node *node,
50  RBTree_Direction dir,
51  void *visitor_arg
52);
53
54/**
55 * @brief Red-black tree iteration.
56 *
57 * @param[in] rbtree The red-black tree.
58 * @param[in] dir The direction.
59 * @param[in] visitor The visitor.
60 * @param[in] visitor_arg The visitor argument.
61 */
62void _RBTree_Iterate(
63  const RBTree_Control *rbtree,
64  RBTree_Direction dir,
65  RBTree_Visitor visitor,
66  void *visitor_arg
67);
68
69/**
70 * @brief Get the direction opposite to @a the_dir.
71 */
72RTEMS_INLINE_ROUTINE RBTree_Direction _RBTree_Opposite_direction(
73  RBTree_Direction the_dir
74)
75{
76  return (RBTree_Direction) !((int) the_dir);
77}
78
79/**
80 * @brief Returns the direction of the node.
81 *
82 * @param[in] the_node The node of interest.
83 * @param[in] parent The parent of the node.  The parent must exist, thus it is
84 * invalid to use this function for the root node.
85 */
86RTEMS_INLINE_ROUTINE RBTree_Direction _RBTree_Direction(
87  const RBTree_Node *the_node,
88  const RBTree_Node *parent
89)
90{
91  return (RBTree_Direction) ( the_node != parent->child[ 0 ] );
92}
93
94/**
95 * @brief Is this node red.
96 *
97 * This function returns true if @a the_node is red and false otherwise.
98 *
99 * @retval true @a the_node is red.
100 * @retval false @a the_node in not red.
101 */
102RTEMS_INLINE_ROUTINE bool _RBTree_Is_red(
103    const RBTree_Node *the_node
104    )
105{
106  return (the_node && the_node->color == RBT_RED);
107}
108
109/**
110 * @brief Returns the sibling of the node.
111 *
112 * @param[in] the_node The node of interest.
113 * @param[in] parent The parent of the node.  The parent must exist, thus it is
114 * invalid to use this function for the root node.
115 *
116 * @retval NULL No sibling exists.
117 * @retval sibling The sibling of the node.
118 */
119RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Sibling(
120  const RBTree_Node *the_node,
121  const RBTree_Node *parent
122)
123{
124  RBTree_Node *left_child = parent->child[ RBT_LEFT ];
125
126  return the_node == left_child ? parent->child[ RBT_RIGHT ] : left_child;
127}
128
129RTEMS_INLINE_ROUTINE bool _RBTree_Is_equal(
130  RBTree_Compare_result compare_result
131)
132{
133  return compare_result == 0;
134}
135
136RTEMS_INLINE_ROUTINE bool _RBTree_Is_greater(
137  RBTree_Compare_result compare_result
138)
139{
140  return compare_result > 0;
141}
142
143RTEMS_INLINE_ROUTINE bool _RBTree_Is_lesser(
144  RBTree_Compare_result compare_result
145)
146{
147  return compare_result < 0;
148}
149
150/**
151 * @brief Rotates the node in the specified direction.
152 *
153 * The node is swapped with its child in the opposite direction if it exists.
154 *
155 * Sub-tree before rotation:
156 * @dot
157 * digraph state {
158 *   parent -> the_node;
159 *   the_node -> sibling [label="dir"];
160 *   the_node -> child [label="opp_dir"];
161 *   child -> grandchild [label="dir"];
162 *   child -> grandchildsibling [label="opp_dir"];
163 * }
164 * @enddot
165 *
166 * Sub-tree after rotation:
167 * @dot
168 * digraph state {
169 *   parent -> child;
170 *   the_node -> sibling [label="dir"];
171 *   the_node -> grandchild [label="opp_dir"];
172 *   child -> the_node [label="dir"];
173 *   child -> grandchildsibling [label="opp_dir"];
174 * }
175 * @enddot
176 *
177 * @param[in] the_node The node to rotate.
178 * @param[in] dir The rotation direction.
179 */
180RTEMS_INLINE_ROUTINE void _RBTree_Rotate(
181  RBTree_Node      *the_node,
182  RBTree_Direction  dir
183)
184{
185  RBTree_Direction  opp_dir = _RBTree_Opposite_direction( dir );
186  RBTree_Node      *child = the_node->child[ opp_dir ];
187  RBTree_Node      *grandchild;
188  RBTree_Node      *parent;
189
190  if ( child == NULL)
191    return;
192
193  grandchild = child->child[ dir ];
194  the_node->child[ opp_dir ] = grandchild;
195
196  if ( grandchild != NULL )
197    grandchild->parent = the_node;
198
199  child->child[ dir ] = the_node;
200
201  parent = _RBTree_Parent( the_node );
202  parent->child[ _RBTree_Direction( the_node, parent ) ] = child;
203
204  child->parent = parent;
205  the_node->parent = child;
206}
207
208/** @} */
209
210#ifdef __cplusplus
211}
212#endif
213
214#endif
215/* end of include file */
Note: See TracBrowser for help on using the repository browser.