source: rtems/cpukit/score/include/rtems/score/rbtree.h @ f53aa8d

4.115
Last change on this file since f53aa8d was f53aa8d, checked in by Gedare Bloom <gedare@…>, on 05/03/12 at 16:43:29

rbtree: API changes. Remove rbtree control node from RBTree_Next.

The implementation of RBTree_Next was using an awkward construction to detect
and avoid accessing the false root of the red-black tree. To deal with the
false root, RBTree_Next was comparing node parents with the control node.
Instead the false root can be detected by checking if the grandparent of a
node exists; the grandparent of the tree's true root is NULL by definition
so the root of the tree is found while walking up the tree by checking for
the non-existence of a grandparent.

This change propagates into the predecessor/successor and iterate functions.

  • Property mode set to 100644
File size: 9.7 KB
Line 
1/**
2 *  @file  rtems/score/rbtree.h
3 *
4 *  This include file contains all the constants and structures associated
5 *  with the Red-Black Tree Handler.
6 */
7
8/*
9 *  Copyright (c) 2010 Gedare Bloom.
10 *
11 *  The license and distribution terms for this file may be
12 *  found in the file LICENSE in this distribution or at
13 *  http://www.rtems.com/license/LICENSE.
14 *
15 *  $Id$
16 */
17
18#ifndef _RTEMS_SCORE_RBTREE_H
19#define _RTEMS_SCORE_RBTREE_H
20
21#include <stddef.h>
22
23/**
24 *  @defgroup ScoreRBTree Red-Black Tree Handler
25 *
26 *  @ingroup Score
27 *
28 *  The Red-Black Tree Handler is used to manage sets of entities.  This handler
29 *  provides two data structures.  The rbtree Node data structure is included
30 *  as the first part of every data structure that will be placed on
31 *  a RBTree.  The second data structure is rbtree Control which is used
32 *  to manage a set of rbtree Nodes.
33 */
34/**@{*/
35
36#ifdef __cplusplus
37extern "C" {
38#endif
39
40#include <rtems/score/address.h>
41
42/**
43 *  @typedef RBTree_Node
44 *
45 *  This type definition promotes the name for the RBTree Node used by
46 *  all RTEMS code.  It is a separate type definition because a forward
47 *  reference is required to define it.  See @ref RBTree_Node_struct for
48 *  detailed information.
49 */
50typedef struct RBTree_Node_struct RBTree_Node;
51
52/**
53 * This enum type defines the colors available for the RBTree Nodes
54 */
55typedef enum {
56  RBT_BLACK,
57  RBT_RED
58} RBTree_Color;
59
60/**
61 *  @struct RBTree_Node_struct
62 *
63 *  This is used to manage each element (node) which is placed
64 *  on a RBT.
65 *
66 *  @note Typically, a more complicated structure will use the
67 *        rbtree package.  The more complicated structure will
68 *        include a rbtree node as the first element in its
69 *        control structure.  It will then call the rbtree package
70 *        with a pointer to that node element.  The node pointer
71 *        and the higher level structure start at the same address
72 *        so the user can cast the pointers back and forth.
73 *
74 */
75struct RBTree_Node_struct {
76  /** This points to the node's parent */
77  RBTree_Node *parent;
78  /** child[0] points to the left child, child[1] points to the right child */
79  RBTree_Node *child[2];
80  /** The color of the node. Either red or black */
81  RBTree_Color color;
82};
83
84/**
85 * @brief macro to return the structure containing the @a node.
86 *
87 * This macro returns a pointer of type @a container_type that points
88 * to the structure containing @a node, where @a node_field_name is the
89 * field name of the RBTree_Node structure in @a container_type.
90 *
91 */
92#define _RBTree_Container_of(node, container_type, node_field_name) \
93( \
94  (container_type*) \
95    ( (uintptr_t)(node) - offsetof(container_type, node_field_name) ) \
96)
97
98/**
99 *  This type indicates the direction.
100 */
101typedef enum {
102  RBT_LEFT=0,
103  RBT_RIGHT=1
104} RBTree_Direction;
105
106/**
107 * This type defines function pointers for user-provided comparison
108 * function. The function compares two nodes in order to determine
109 * the order in a red-black tree.
110 */
111typedef int (*RBTree_Compare_function)(
112  const RBTree_Node *node1,
113  const RBTree_Node *node2
114);
115
116/**
117 *  @struct RBTree_Control
118 *
119 * This is used to manage a RBT.  A rbtree consists of a tree of zero or more
120 * nodes.
121 *
122 * @note This implementation does not require special checks for
123 *   manipulating the root element of the RBT.
124 *   To accomplish this the @a RBTree_Control structure can be overlaid
125 *   with a @ref RBTree_Node structure to act as a "dummy root",
126 *   which has a NULL parent and its left child is the root.
127 */
128
129/* the RBTree_Control is actually part of the RBTree structure as an
130 * RBTree_Node. The mapping of fields from RBTree_Control to RBTree_Node are:
131 *   permanent_null == parent
132 *   root == left
133 *   first[0] == right
134 */
135typedef struct {
136  /** This points to a NULL. Useful for finding the root. */
137  RBTree_Node *permanent_null;
138  /** This points to the root node of the RBT. */
139  RBTree_Node *root;
140  /** This points to the min and max nodes of this RBT. */
141  RBTree_Node *first[2];
142  /**
143   * Comparison function pointer. Keys to compare have to be found
144   * inside to maintain generality. It has to return 1 if first node
145   * has higher key than second, -1 if lower, 0 if equal.
146   */
147  RBTree_Compare_function compare_function;
148  /** Determines whether the tree accepts duplicate keys. */
149  bool is_unique;
150} RBTree_Control;
151
152/**
153 *  @brief RBTree initializer for an empty rbtree with designator @a name.
154 */
155#define RBTREE_INITIALIZER_EMPTY(name) \
156{ \
157  .permanent_null = NULL, \
158  .root = NULL, \
159  .first[0] = NULL, \
160  .first[1] = NULL, \
161  .compare_function = NULL, \
162  .is_unique = 0 \
163}
164
165/**
166 *  @brief RBTree definition for an empty rbtree with designator @a name.
167 */
168#define RBTREE_DEFINE_EMPTY(name) \
169RBTree_Control name = RBTREE_INITIALIZER_EMPTY(name)
170
171/**
172 *  @brief RBTree_Node initializer for an empty node with designator @a name.
173 */
174#define RBTREE_NODE_INITIALIZER_EMPTY(name) \
175{ \
176  .parent = NULL, \
177  .child[0] = NULL, \
178  .child[1] = NULL, \
179  RBT_RED \
180}
181
182/**
183 *  @brief RBTree definition for an empty rbtree with designator @a name.
184 */
185#define RBTREE_NODE_DEFINE_EMPTY(name) \
186RBTree_Node name = RBTREE_NODE_INITIALIZER_EMPTY(name)
187
188/**
189 *  @brief Initialize a RBTree Header
190 *
191 *  This routine initializes @a the_rbtree structure to manage the
192 *  contiguous array of @a number_nodes nodes which starts at
193 *  @a starting_address.  Each node is of @a node_size bytes.
194 */
195void _RBTree_Initialize(
196  RBTree_Control          *the_rbtree,
197  RBTree_Compare_function  compare_function,
198  void                    *starting_address,
199  size_t                   number_nodes,
200  size_t                   node_size,
201  bool                     is_unique
202);
203
204/**
205 *  @brief Obtain the min or max node of a rbtree
206 *
207 *  This function removes the min or max node from @a the_rbtree and returns
208 *  a pointer to that node.  If @a the_rbtree is empty, then NULL is returned.
209 *  @a dir specifies whether to return the min (0) or max (1).
210 *
211 *  @return This method returns a pointer to a node.  If a node was removed,
212 *          then a pointer to that node is returned.  If @a the_rbtree was
213 *          empty, then NULL is returned.
214 *
215 *  @note It disables interrupts to ensure the atomicity of the get operation.
216 */
217RBTree_Node *_RBTree_Get(
218  RBTree_Control *the_rbtree,
219  RBTree_Direction dir
220);
221
222/**
223 * @brief Find the node with given key in the tree
224 *
225 *  This function returns a pointer to the node with key equal to a key
226 *  of @a the_node if it exists in the Red-Black Tree @a the_rbtree,
227 *  and NULL if not.
228 */
229RBTree_Node *_RBTree_Find(
230  RBTree_Control *the_rbtree,
231  RBTree_Node *the_node
232);
233
234/**
235 * @brief Find the control structure of the tree containing the given node
236 *
237 *  This function returns a pointer to the control structure of the tree
238 *  containing @a the_node, if it exists, and NULL if not.
239 */
240RBTree_Control *_RBTree_Find_header(
241  RBTree_Node *the_node
242);
243
244/**
245 * @brief Insert a Node (unprotected)
246 *
247 *  This routine inserts @a the_node on the Red-Black Tree @a the_rbtree.
248 *
249 *  @retval 0 Successfully inserted.
250 *  @retval -1 NULL @a the_node.
251 *  @retval RBTree_Node* if one with equal value to @a the_node 's key exists
252 *          in an unique @a the_rbtree.
253 *
254 *  @note It does NOT disable interrupts to ensure the atomicity
255 *        of the extract operation.
256 */
257RBTree_Node *_RBTree_Insert_unprotected(
258  RBTree_Control *the_rbtree,
259  RBTree_Node *the_node
260);
261
262/**
263 *  @brief Insert a node on a rbtree
264 *
265 *  This routine inserts @a the_node on the tree @a the_rbtree.
266 *
267 *  @retval 0 Successfully inserted.
268 *  @retval -1 NULL @a the_node.
269 *  @retval RBTree_Node* if one with equal value to @a the_node 's key exists
270 *          in an unique @a the_rbtree.
271 *
272 *  @note It disables interrupts to ensure the atomicity
273 *  of the extract operation.
274 */
275RBTree_Node *_RBTree_Insert(
276  RBTree_Control *the_rbtree,
277  RBTree_Node *the_node
278);
279
280
281/**
282 * @brief Extract a Node (unprotected)
283 *
284 *  This routine extracts (removes) @a the_node from @a the_rbtree.
285 *
286 *  @note It does NOT disable interrupts to ensure the atomicity
287 *        of the extract operation.
288 */
289void _RBTree_Extract_unprotected(
290  RBTree_Control *the_rbtree,
291  RBTree_Node *the_node
292);
293
294/**
295 *  @brief Delete a node from the rbtree
296 *
297 *  This routine deletes @a the_node from @a the_rbtree.
298 *
299 *  @note It disables interrupts to ensure the atomicity of the
300 *  append operation.
301 */
302void _RBTree_Extract(
303  RBTree_Control *the_rbtree,
304  RBTree_Node    *the_node
305);
306
307/**
308 * @brief Returns the in-order next node of a node.
309 *
310 * @param[in] node The node.
311 * @param[in] dir The direction.
312 *
313 * @retval NULL The in-order next node does not exist.
314 * @retval otherwise The next node.
315 */
316RBTree_Node *_RBTree_Next_unprotected(
317  const RBTree_Node *node,
318  RBTree_Direction dir
319);
320
321/**
322 * @copydoc _RBTree_Next_unprotected()
323 *
324 * The function disables the interrupts protect the operation.
325 */
326RBTree_Node *_RBTree_Next(
327  const RBTree_Node *node,
328  RBTree_Direction dir
329);
330
331/**
332 * @brief Red-black tree visitor.
333 *
334 * @param[in] node The node.
335 * @param[in] dir The direction.
336 * @param[in] visitor_arg The visitor argument.
337 *
338 * @retval true Stop the iteration.
339 * @retval false Continue the iteration.
340 *
341 * @see _RBTree_Iterate_unprotected().
342 */
343typedef bool (*RBTree_Visitor)(
344  const RBTree_Node *node,
345  RBTree_Direction dir,
346  void *visitor_arg
347);
348
349/**
350 * @brief Red-black tree iteration.
351 *
352 * @param[in] rbtree The red-black tree.
353 * @param[in] dir The direction.
354 * @param[in] visitor The visitor.
355 * @param[in] visitor_arg The visitor argument.
356 */
357void _RBTree_Iterate_unprotected(
358  const RBTree_Control *rbtree,
359  RBTree_Direction dir,
360  RBTree_Visitor visitor,
361  void *visitor_arg
362);
363
364#ifndef __RTEMS_APPLICATION__
365#include <rtems/score/rbtree.inl>
366#endif
367
368#ifdef __cplusplus
369}
370#endif
371
372/**@}*/
373
374#endif
375/* end of include file */
Note: See TracBrowser for help on using the repository browser.