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

5
Last change on this file since f71e67d was f71e67d, checked in by Sebastian Huber <sebastian.huber@…>, on 08/21/15 at 03:59:19

rbtree: Delete unused RBTREE_NODE_*() macros

  • Property mode set to 100644
File size: 12.6 KB
Line 
1/**
2 *  @file  rtems/score/rbtree.h
3 *
4 *  @brief Constants and Structures Associated with the Red-Black Tree Handler
5 *
6 *  This include file contains all the constants and structures associated
7 *  with the Red-Black Tree Handler.
8 */
9
10/*
11 *  Copyright (c) 2010 Gedare Bloom.
12 *
13 *  The license and distribution terms for this file may be
14 *  found in the file LICENSE in this distribution or at
15 *  http://www.rtems.org/license/LICENSE.
16 */
17
18#ifndef _RTEMS_SCORE_RBTREE_H
19#define _RTEMS_SCORE_RBTREE_H
20
21#include <stddef.h>
22
23#include <rtems/score/address.h>
24
25#ifdef __cplusplus
26extern "C" {
27#endif
28
29/**
30 *  @defgroup ScoreRBTree Red-Black Tree Handler
31 *
32 *  @ingroup Score
33 *
34 *  The Red-Black Tree Handler is used to manage sets of entities.  This handler
35 *  provides two data structures.  The rbtree Node data structure is included
36 *  as the first part of every data structure that will be placed on
37 *  a RBTree.  The second data structure is rbtree Control which is used
38 *  to manage a set of rbtree Nodes.
39 */
40/**@{*/
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 *  This type indicates the direction.
86 */
87typedef enum {
88  RBT_LEFT=0,
89  RBT_RIGHT=1
90} RBTree_Direction;
91
92/**
93 * @brief Integer type for compare results.
94 *
95 * The type is large enough to represent pointers and 32-bit signed integers.
96 *
97 * @see RBTree_Compare.
98 */
99typedef long RBTree_Compare_result;
100
101/**
102 * @brief Compares two red-black tree nodes.
103 *
104 * @param[in] first The first node.
105 * @param[in] second The second node.
106 *
107 * @retval positive The key value of the first node is greater than the one of
108 *   the second node.
109 * @retval 0 The key value of the first node is equal to the one of the second
110 *   node.
111 * @retval negative The key value of the first node is less than the one of the
112 *   second node.
113 */
114typedef RBTree_Compare_result ( *RBTree_Compare )(
115  const RBTree_Node *first,
116  const RBTree_Node *second
117);
118
119/**
120 *  @struct RBTree_Control
121 *
122 * This is used to manage a RBT.  A rbtree consists of a tree of zero or more
123 * nodes.
124 *
125 * @note This implementation does not require special checks for
126 *   manipulating the root element of the RBT.
127 *   To accomplish this the @a RBTree_Control structure can be overlaid
128 *   with a @ref RBTree_Node structure to act as a "dummy root",
129 *   which has a NULL parent and its left child is the root.
130 */
131
132/* the RBTree_Control is actually part of the RBTree structure as an
133 * RBTree_Node. The mapping of fields from RBTree_Control to RBTree_Node are:
134 *   permanent_null == parent
135 *   root == left
136 *   first[0] == right
137 */
138typedef struct {
139  /** This points to a NULL. Useful for finding the root. */
140  RBTree_Node *permanent_null;
141  /** This points to the root node of the RBT. */
142  RBTree_Node *root;
143  /** This points to the min and max nodes of this RBT. */
144  RBTree_Node *first[2];
145} RBTree_Control;
146
147/**
148 *  @brief RBTree initializer for an empty rbtree with designator @a name.
149 */
150#define RBTREE_INITIALIZER_EMPTY( name ) \
151  { NULL, NULL, { NULL, NULL } }
152
153/**
154 *  @brief RBTree definition for an empty rbtree with designator @a name.
155 */
156#define RBTREE_DEFINE_EMPTY( name ) \
157  RBTree_Control name = RBTREE_INITIALIZER_EMPTY( name )
158
159/**
160 * @brief Tries to find a node for the specified key in the tree.
161 *
162 * @param[in] the_rbtree The red-black tree control.
163 * @param[in] the_node A node specifying the key.
164 * @param[in] compare The node compare function.
165 * @param[in] is_unique If true, then return the first node with a key equal to
166 *   the one of the node specified if it exits, else return the last node if it
167 *   exists.
168 *
169 * @retval node A node corresponding to the key.  If the tree is not unique
170 * and contains duplicate keys, the set of duplicate keys acts as FIFO.
171 * @retval NULL No node exists in the tree for the key.
172 */
173RBTree_Node *_RBTree_Find(
174  const RBTree_Control *the_rbtree,
175  const RBTree_Node    *the_node,
176  RBTree_Compare        compare,
177  bool                  is_unique
178);
179
180/**
181 * @brief Inserts the node into the red-black tree.
182 *
183 * In case the node is already a node of a tree, then this function yields
184 * unpredictable results.
185 *
186 * @param[in] the_rbtree The red-black tree control.
187 * @param[in] the_node The node to insert.
188 * @param[in] compare The node compare function.
189 * @param[in] is_unique If true, then reject nodes with a duplicate key, else
190 *   insert nodes in FIFO order in case the key value is equal to existing nodes.
191 *
192 * @retval NULL Successfully inserted.
193 * @retval existing_node This is a unique insert and there exists a node with
194 *   an equal key in the tree already.
195 */
196RBTree_Node *_RBTree_Insert(
197  RBTree_Control *the_rbtree,
198  RBTree_Node    *the_node,
199  RBTree_Compare  compare,
200  bool            is_unique
201);
202
203/**
204 * @brief Extracts (removes) the node from the red-black tree.
205 *
206 * This function does not set the node off-tree.  In case this is desired, then
207 * call _RBTree_Set_off_tree() after the extraction.
208 *
209 * In case the node to extract is not a node of the tree, then this function
210 * yields unpredictable results.
211 *
212 * @param[in] the_rbtree The red-black tree control.
213 * @param[in] the_node The node to extract.
214 */
215void _RBTree_Extract(
216  RBTree_Control *the_rbtree,
217  RBTree_Node *the_node
218);
219
220/**
221 * @brief Returns the in-order next node of a node.
222 *
223 * @param[in] node The node.
224 * @param[in] dir The direction.
225 *
226 * @retval NULL The in-order next node does not exist.
227 * @retval otherwise The next node.
228 */
229RBTree_Node *_RBTree_Next(
230  const RBTree_Node *node,
231  RBTree_Direction dir
232);
233
234/**
235 * @brief Sets a red-black tree node as off-tree.
236 *
237 * Do not use this function on nodes which are a part of a tree.
238 *
239 * @param[in] the_node The node to set off-tree.
240 *
241 * @see _RBTree_Is_node_off_tree().
242 */
243RTEMS_INLINE_ROUTINE void _RBTree_Set_off_tree( RBTree_Node *the_node )
244{
245  the_node->parent = NULL;
246}
247
248/**
249 * @brief Returns true, if this red-black tree node is off-tree, and false
250 * otherwise.
251 *
252 * @param[in] the_node The node to test.
253 *
254 * @retval true The node is not a part of a tree (off-tree).
255 * @retval false Otherwise.
256 *
257 * @see _RBTree_Set_off_tree().
258 */
259RTEMS_INLINE_ROUTINE bool _RBTree_Is_node_off_tree(
260  const RBTree_Node *the_node
261)
262{
263  return the_node->parent == NULL;
264}
265
266/**
267 * @brief Returns a pointer to root node of the red-black tree.
268 *
269 * The root node may change after insert or extract operations.
270 *
271 * @param[in] the_rbtree The red-black tree control.
272 *
273 * @retval NULL The tree is empty.
274 * @retval root The root node.
275 *
276 * @see _RBTree_Is_root().
277 */
278RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Root(
279  const RBTree_Control *the_rbtree
280)
281{
282  return the_rbtree->root;
283}
284
285/**
286 * @brief Return pointer to RBTree's first node.
287 *
288 * This function returns a pointer to the first node on @a the_rbtree,
289 * where @a dir specifies whether to return the minimum (0) or maximum (1).
290 */
291RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_First(
292  const RBTree_Control *the_rbtree,
293  RBTree_Direction dir
294)
295{
296  return the_rbtree->first[dir];
297}
298
299/**
300 * @brief Returns a pointer to the parent of this node.
301 *
302 * The node must have a parent, thus it is invalid to use this function for the
303 * root node or a node that is not part of a tree.  To test for the root node
304 * compare with _RBTree_Root() or use _RBTree_Is_root().
305 *
306 * @param[in] the_node The node of interest.
307 *
308 * @retval parent The parent of this node.
309 * @retval undefined The node is the root node or not part of a tree.
310 */
311RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Parent(
312  const RBTree_Node *the_node
313)
314{
315  return the_node->parent;
316}
317
318/**
319 * @brief Return pointer to the left of this node.
320 *
321 * This function returns a pointer to the left node of this node.
322 *
323 * @param[in] the_node is the node to be operated upon.
324 *
325 * @return This method returns the left node on the rbtree.
326 */
327RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Left(
328  const RBTree_Node *the_node
329)
330{
331  return the_node->child[RBT_LEFT];
332}
333
334/**
335 * @brief Return pointer to the right of this node.
336 *
337 * This function returns a pointer to the right node of this node.
338 *
339 * @param[in] the_node is the node to be operated upon.
340 *
341 * @return This method returns the right node on the rbtree.
342 */
343RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Right(
344  const RBTree_Node *the_node
345)
346{
347  return the_node->child[RBT_RIGHT];
348}
349
350/**
351 * @brief Is the RBTree empty.
352 *
353 * This function returns true if there are no nodes on @a the_rbtree and
354 * false otherwise.
355 *
356 * @param[in] the_rbtree is the rbtree to be operated upon.
357 *
358 * @retval true There are no nodes on @a the_rbtree.
359 * @retval false There are nodes on @a the_rbtree.
360 */
361RTEMS_INLINE_ROUTINE bool _RBTree_Is_empty(
362  const RBTree_Control *the_rbtree
363)
364{
365  return (the_rbtree->root == NULL);
366}
367
368/**
369 * @brief Returns true if this node is the root node of a red-black tree, and
370 * false otherwise.
371 *
372 * The root node may change after insert or extract operations.  In case the
373 * node is not a node of a tree, then this function yields unpredictable
374 * results.
375 *
376 * @param[in] the_node The node of interest.
377 *
378 * @retval true The node is the root node.
379 * @retval false Otherwise.
380 *
381 * @see _RBTree_Root().
382 */
383RTEMS_INLINE_ROUTINE bool _RBTree_Is_root(
384  const RBTree_Node *the_node
385)
386{
387  return _RBTree_Parent( _RBTree_Parent( the_node ) ) == NULL;
388}
389
390/**
391 * @brief Finds the red-black tree control given a node in the tree.
392 *
393 * In case the node is not a node of a tree, then this function yields
394 * unpredictable results.
395 *
396 * @param[in] the_node The node of interest.
397 *
398 * @return The red-black tree control of the node.
399 */
400RTEMS_INLINE_ROUTINE RBTree_Control *_RBTree_Find_control(
401  const RBTree_Node *the_node
402)
403{
404  RBTree_Node    *parent = the_node->parent;
405  RBTree_Control *rbtree;
406
407  do {
408    rbtree = (RBTree_Control *) parent;
409    parent = parent->parent;
410  } while ( parent != NULL );
411
412  return rbtree;
413}
414
415/**
416 * @brief Initialize this RBTree as empty.
417 *
418 * This routine initializes @a the_rbtree to contain zero nodes.
419 */
420RTEMS_INLINE_ROUTINE void _RBTree_Initialize_empty(
421  RBTree_Control *the_rbtree
422)
423{
424  the_rbtree->permanent_null   = NULL;
425  the_rbtree->root             = NULL;
426  the_rbtree->first[RBT_LEFT]  = NULL;
427  the_rbtree->first[RBT_RIGHT] = NULL;
428}
429
430/**
431 * @brief Returns the minimum node of the red-black tree.
432 *
433 * @param[in] the_rbtree The red-black tree control.
434 *
435 * @retval NULL The red-black tree is empty.
436 * @retval node The minimum node.
437 */
438RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Minimum(
439  const RBTree_Control *the_rbtree
440)
441{
442  return _RBTree_First( the_rbtree, RBT_LEFT );
443}
444
445/**
446 * @brief Returns the maximum node of the red-black tree.
447 *
448 * @param[in] the_rbtree The red-black tree control.
449 *
450 * @retval NULL The red-black tree is empty.
451 * @retval node The maximum node.
452 */
453RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Maximum(
454  const RBTree_Control *the_rbtree
455)
456{
457  return _RBTree_First( the_rbtree, RBT_RIGHT );
458}
459
460/**
461 * @brief Returns the predecessor of a node.
462 *
463 * @param[in] node is the node.
464 *
465 * @retval NULL The predecessor does not exist.  Otherwise it returns
466 *         the predecessor node.
467 */
468RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Predecessor(
469  const RBTree_Node *node
470)
471{
472  return _RBTree_Next( node, RBT_LEFT );
473}
474
475/**
476 * @brief Returns the successor of a node.
477 *
478 * @param[in] node is the node.
479 *
480 * @retval NULL The successor does not exist.  Otherwise the successor node.
481 */
482RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Successor(
483  const RBTree_Node *node
484)
485{
486  return _RBTree_Next( node, RBT_RIGHT );
487}
488
489/**@}*/
490
491#ifdef __cplusplus
492}
493#endif
494
495#endif
496/* end of include file */
Note: See TracBrowser for help on using the repository browser.