source: rtems/cpukit/score/include/rtems/score/rbtree.h @ 40dcafa

4.115
Last change on this file since 40dcafa was 40dcafa, checked in by Sebastian Huber <sebastian.huber@…>, on 08/02/14 at 14:22:31

Add and use RTEMS_CONTAINER_OF()

  • Property mode set to 100644
File size: 13.8 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 Compares two red-black tree nodes.
94 *
95 * @param[in] first The first node.
96 * @param[in] second The second node.
97 *
98 * @retval positive The key value of the first node is greater than the one of
99 *   the second node.
100 * @retval 0 The key value of the first node is equal to the one of the second
101 *   node.
102 * @retval negative The key value of the first node is less than the one of the
103 *   second node.
104 */
105typedef int ( *RBTree_Compare )(
106  const RBTree_Node *first,
107  const RBTree_Node *second
108);
109
110/**
111 *  @struct RBTree_Control
112 *
113 * This is used to manage a RBT.  A rbtree consists of a tree of zero or more
114 * nodes.
115 *
116 * @note This implementation does not require special checks for
117 *   manipulating the root element of the RBT.
118 *   To accomplish this the @a RBTree_Control structure can be overlaid
119 *   with a @ref RBTree_Node structure to act as a "dummy root",
120 *   which has a NULL parent and its left child is the root.
121 */
122
123/* the RBTree_Control is actually part of the RBTree structure as an
124 * RBTree_Node. The mapping of fields from RBTree_Control to RBTree_Node are:
125 *   permanent_null == parent
126 *   root == left
127 *   first[0] == right
128 */
129typedef struct {
130  /** This points to a NULL. Useful for finding the root. */
131  RBTree_Node *permanent_null;
132  /** This points to the root node of the RBT. */
133  RBTree_Node *root;
134  /** This points to the min and max nodes of this RBT. */
135  RBTree_Node *first[2];
136} RBTree_Control;
137
138/**
139 *  @brief RBTree initializer for an empty rbtree with designator @a name.
140 */
141#define RBTREE_INITIALIZER_EMPTY( name ) \
142  { NULL, NULL, { NULL, NULL } }
143
144/**
145 *  @brief RBTree definition for an empty rbtree with designator @a name.
146 */
147#define RBTREE_DEFINE_EMPTY( name ) \
148  RBTree_Control name = RBTREE_INITIALIZER_EMPTY( name )
149
150/**
151 *  @brief RBTree_Node initializer for an empty node with designator @a name.
152 */
153#define RBTREE_NODE_INITIALIZER_EMPTY( name ) \
154  { NULL, { NULL, NULL }, RBT_RED }
155
156/**
157 *  @brief RBTree definition for an empty rbtree with designator @a name.
158 */
159#define RBTREE_NODE_DEFINE_EMPTY( name ) \
160  RBTree_Node name = RBTREE_NODE_INITIALIZER_EMPTY( name )
161
162/**
163 *  @brief Initialize a RBTree Header.
164 *
165 *  This routine initializes @a the_rbtree structure to manage the
166 *  contiguous array of @a number_nodes nodes which starts at
167 *  @a starting_address.  Each node is of @a node_size bytes.
168 *
169 *  @param[in] the_rbtree is the pointer to rbtree header
170 *  @param[in] compare The node compare function.
171 *  @param[in] starting_address is the starting address of first node
172 *  @param[in] number_nodes is the number of nodes in rbtree
173 *  @param[in] node_size is the size of node in bytes
174 *  @param[in] is_unique If true, then reject nodes with a duplicate key, else
175 *    otherwise.
176 */
177void _RBTree_Initialize(
178  RBTree_Control *the_rbtree,
179  RBTree_Compare  compare,
180  void           *starting_address,
181  size_t          number_nodes,
182  size_t          node_size,
183  bool            is_unique
184);
185
186/**
187 * @brief Tries to find a node for the specified key in the tree.
188 *
189 * @param[in] the_rbtree The red-black tree control.
190 * @param[in] the_node A node specifying the key.
191 * @param[in] compare The node compare function.
192 * @param[in] is_unique If true, then return the first node with a key equal to
193 *   the one of the node specified if it exits, else return the last node if it
194 *   exists.
195 *
196 * @retval node A node corresponding to the key.  If the tree is not unique
197 * and contains duplicate keys, the set of duplicate keys acts as FIFO.
198 * @retval NULL No node exists in the tree for the key.
199 */
200RBTree_Node *_RBTree_Find(
201  const RBTree_Control *the_rbtree,
202  const RBTree_Node    *the_node,
203  RBTree_Compare        compare,
204  bool                  is_unique
205);
206
207/**
208 * @brief Inserts the node into the red-black tree.
209 *
210 * In case the node is already a node of a tree, then this function yields
211 * unpredictable results.
212 *
213 * @param[in] the_rbtree The red-black tree control.
214 * @param[in] the_node The node to insert.
215 * @param[in] compare The node compare function.
216 * @param[in] is_unique If true, then reject nodes with a duplicate key, else
217 *   insert nodes in FIFO order in case the key value is equal to existing nodes.
218 *
219 * @retval NULL Successfully inserted.
220 * @retval existing_node This is a unique insert and there exists a node with
221 *   an equal key in the tree already.
222 */
223RBTree_Node *_RBTree_Insert(
224  RBTree_Control *the_rbtree,
225  RBTree_Node    *the_node,
226  RBTree_Compare  compare,
227  bool            is_unique
228);
229
230/**
231 * @brief Extracts (removes) the node from the red-black tree.
232 *
233 * This function does not set the node off-tree.  In case this is desired, then
234 * call _RBTree_Set_off_tree() after the extraction.
235 *
236 * In case the node to extract is not a node of the tree, then this function
237 * yields unpredictable results.
238 *
239 * @param[in] the_rbtree The red-black tree control.
240 * @param[in] the_node The node to extract.
241 */
242void _RBTree_Extract(
243  RBTree_Control *the_rbtree,
244  RBTree_Node *the_node
245);
246
247/**
248 * @brief Returns the in-order next node of a node.
249 *
250 * @param[in] node The node.
251 * @param[in] dir The direction.
252 *
253 * @retval NULL The in-order next node does not exist.
254 * @retval otherwise The next node.
255 */
256RBTree_Node *_RBTree_Next(
257  const RBTree_Node *node,
258  RBTree_Direction dir
259);
260
261/**
262 * @brief Sets a red-black tree node as off-tree.
263 *
264 * Do not use this function on nodes which are a part of a tree.
265 *
266 * @param[in] the_node The node to set off-tree.
267 *
268 * @see _RBTree_Is_node_off_tree().
269 */
270RTEMS_INLINE_ROUTINE void _RBTree_Set_off_tree( RBTree_Node *the_node )
271{
272  the_node->parent = NULL;
273}
274
275/**
276 * @brief Returns true, if this red-black tree node is off-tree, and false
277 * otherwise.
278 *
279 * @param[in] the_node The node to test.
280 *
281 * @retval true The node is not a part of a tree (off-tree).
282 * @retval false Otherwise.
283 *
284 * @see _RBTree_Set_off_tree().
285 */
286RTEMS_INLINE_ROUTINE bool _RBTree_Is_node_off_tree(
287  const RBTree_Node *the_node
288)
289{
290  return the_node->parent == NULL;
291}
292
293/**
294 * @brief Return pointer to RBTree's root node.
295 *
296 * This function returns a pointer to the root node of @a the_rbtree.
297 */
298RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Root(
299  const RBTree_Control *the_rbtree
300)
301{
302  return the_rbtree->root;
303}
304
305/**
306 * @brief Return pointer to RBTree's first node.
307 *
308 * This function returns a pointer to the first node on @a the_rbtree,
309 * where @a dir specifies whether to return the minimum (0) or maximum (1).
310 */
311RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_First(
312  const RBTree_Control *the_rbtree,
313  RBTree_Direction dir
314)
315{
316  return the_rbtree->first[dir];
317}
318
319/**
320 * @brief Return pointer to the parent of this node.
321 *
322 * This function returns a pointer to the parent node of @a the_node.
323 */
324RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Parent(
325  const RBTree_Node *the_node
326)
327{
328  if (!the_node->parent->parent) return NULL;
329  return the_node->parent;
330}
331
332/**
333 * @brief Return pointer to the left of this node.
334 *
335 * This function returns a pointer to the left node of this node.
336 *
337 * @param[in] the_node is the node to be operated upon.
338 *
339 * @return This method returns the left node on the rbtree.
340 */
341RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Left(
342  const RBTree_Node *the_node
343)
344{
345  return the_node->child[RBT_LEFT];
346}
347
348/**
349 * @brief Return pointer to the right of this node.
350 *
351 * This function returns a pointer to the right node of this node.
352 *
353 * @param[in] the_node is the node to be operated upon.
354 *
355 * @return This method returns the right node on the rbtree.
356 */
357RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Right(
358  const RBTree_Node *the_node
359)
360{
361  return the_node->child[RBT_RIGHT];
362}
363
364/**
365 * @brief Is the RBTree empty.
366 *
367 * This function returns true if there are no nodes on @a the_rbtree and
368 * false otherwise.
369 *
370 * @param[in] the_rbtree is the rbtree to be operated upon.
371 *
372 * @retval true There are no nodes on @a the_rbtree.
373 * @retval false There are nodes on @a the_rbtree.
374 */
375RTEMS_INLINE_ROUTINE bool _RBTree_Is_empty(
376  const RBTree_Control *the_rbtree
377)
378{
379  return (the_rbtree->root == NULL);
380}
381
382/**
383 * @brief Is this the first node on the RBTree.
384 *
385 * This function returns true if @a the_node is the first node on
386 * @a the_rbtree and false otherwise. @a dir specifies whether first means
387 * minimum (0) or maximum (1).
388 *
389 * @retval true @a the_node is the first node on @a the_rbtree.
390 * @retval false @a the_node is not the first node on @a the_rbtree.
391 *
392 */
393RTEMS_INLINE_ROUTINE bool _RBTree_Is_first(
394  const RBTree_Control *the_rbtree,
395  const RBTree_Node *the_node,
396  RBTree_Direction dir
397)
398{
399  return (the_node == _RBTree_First(the_rbtree, dir));
400}
401
402/**
403 * @brief Is this node the RBTree root.
404 *
405 * This function returns true if @a the_node is the root of @a the_rbtree and
406 * false otherwise.
407 *
408 * @retval true @a the_node is the root of @a the_rbtree.
409 * @retval false @a the_node is not the root of @a the_rbtree.
410 */
411RTEMS_INLINE_ROUTINE bool _RBTree_Is_root(
412  const RBTree_Control *the_rbtree,
413  const RBTree_Node    *the_node
414)
415{
416  return (the_node == _RBTree_Root(the_rbtree));
417}
418
419/**
420 * @brief Finds the red-black tree control given a node in the tree.
421 *
422 * In case the node is not a node of a tree, then this function yields
423 * unpredictable results.
424 *
425 * @param[in] the_node The node of interest.
426 *
427 * @return The red-black tree control of the node.
428 */
429RTEMS_INLINE_ROUTINE RBTree_Control *_RBTree_Find_control(
430  const RBTree_Node *the_node
431)
432{
433  RBTree_Node    *parent = the_node->parent;
434  RBTree_Control *rbtree;
435
436  do {
437    rbtree = (RBTree_Control *) parent;
438    parent = parent->parent;
439  } while ( parent != NULL );
440
441  return rbtree;
442}
443
444/**
445 * @brief Initialize this RBTree as empty.
446 *
447 * This routine initializes @a the_rbtree to contain zero nodes.
448 */
449RTEMS_INLINE_ROUTINE void _RBTree_Initialize_empty(
450  RBTree_Control *the_rbtree
451)
452{
453  the_rbtree->permanent_null   = NULL;
454  the_rbtree->root             = NULL;
455  the_rbtree->first[RBT_LEFT]  = NULL;
456  the_rbtree->first[RBT_RIGHT] = NULL;
457}
458
459/**
460 * @brief Returns the predecessor of a node.
461 *
462 * @param[in] node is the node.
463 *
464 * @retval NULL The predecessor does not exist.  Otherwise it returns
465 *         the predecessor node.
466 */
467RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Predecessor(
468  const RBTree_Node *node
469)
470{
471  return _RBTree_Next( node, RBT_LEFT );
472}
473
474/**
475 * @brief Returns the successor of a node.
476 *
477 * @param[in] node is the node.
478 *
479 * @retval NULL The successor does not exist.  Otherwise the successor node.
480 */
481RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Successor(
482  const RBTree_Node *node
483)
484{
485  return _RBTree_Next( node, RBT_RIGHT );
486}
487
488/**
489 * @brief Gets a node with an extremal key value from the red-black tree.
490 *
491 * This function extracts a node with the minimum or maximum key value from
492 * tree and returns a pointer to that node if it exists.  In case multiple
493 * nodes with a minimum key value exist, then they are extracted in FIFO order.
494 * In case multiple nodes with a maximum key value exist, then they are
495 * extracted in LIFO order.
496 *
497 * @param[in] the_rbtree The red-black tree control.
498 * @param[in] dir Specifies whether to get a node with the minimum (RBT_LEFT)
499 *   or maximum (RBT_RIGHT) key value.
500 *
501 * @retval NULL The tree is empty.
502 * @retval extremal_node A node with a minimal or maximal key value on the
503 *   tree.
504 */
505RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Get(
506  RBTree_Control *the_rbtree,
507  RBTree_Direction dir
508)
509{
510  RBTree_Node *the_node = the_rbtree->first[ dir ];
511
512  if ( the_node != NULL ) {
513    _RBTree_Extract( the_rbtree, the_node );
514  }
515
516  return the_node;
517}
518
519/**@}*/
520
521#ifdef __cplusplus
522}
523#endif
524
525#endif
526/* end of include file */
Note: See TracBrowser for help on using the repository browser.