source: rtems/cpukit/score/include/rtems/score/rbtree.h @ 8a83a86

Last change on this file since 8a83a86 was 8a83a86, checked in by Sebastian Huber <sebastian.huber@…>, on 04/10/12 at 08:54:22

rbtree: New function _RBTree_Iterate_unprotected()

  • Property mode set to 100644
File size: 10.3 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 Check the min or max node on a rbtree
224 *
225 *  This function returns a pointer to the min or max node of @a the_rbtree.
226 *  If @a the_rbtree is empty, then NULL is returned. @a dir specifies
227 *  whether to return the min (0) or max (1).
228 *
229 *  @return This method returns a pointer to a node.
230 *          If @a the_rbtree was empty, then NULL is returned.
231 *
232 *  @note It disables interrupts to ensure the atomicity of the get operation.
233 */
234RBTree_Node *_RBTree_Peek(
235  const RBTree_Control *the_rbtree,
236  RBTree_Direction dir
237);
238
239/**
240 * @brief Find the node with given key in the tree
241 *
242 *  This function returns a pointer to the node with key equal to a key
243 *  of @a the_node if it exists in the Red-Black Tree @a the_rbtree,
244 *  and NULL if not.
245 */
246RBTree_Node *_RBTree_Find(
247  RBTree_Control *the_rbtree,
248  RBTree_Node *the_node
249);
250
251/**
252 * @brief Find the control structure of the tree containing the given node
253 *
254 *  This function returns a pointer to the control structure of the tree
255 *  containing @a the_node, if it exists, and NULL if not.
256 */
257RBTree_Control *_RBTree_Find_header(
258  RBTree_Node *the_node
259);
260
261/**
262 * @brief Insert a Node (unprotected)
263 *
264 *  This routine inserts @a the_node on the Red-Black Tree @a the_rbtree.
265 *
266 *  @retval 0 Successfully inserted.
267 *  @retval -1 NULL @a the_node.
268 *  @retval RBTree_Node* if one with equal value to @a the_node 's key exists
269 *          in an unique @a the_rbtree.
270 *
271 *  @note It does NOT disable interrupts to ensure the atomicity
272 *        of the extract operation.
273 */
274RBTree_Node *_RBTree_Insert_unprotected(
275  RBTree_Control *the_rbtree,
276  RBTree_Node *the_node
277);
278
279/**
280 *  @brief Insert a node on a rbtree
281 *
282 *  This routine inserts @a the_node on the tree @a the_rbtree.
283 *
284 *  @retval 0 Successfully inserted.
285 *  @retval -1 NULL @a the_node.
286 *  @retval RBTree_Node* if one with equal value to @a the_node 's key exists
287 *          in an unique @a the_rbtree.
288 *
289 *  @note It disables interrupts to ensure the atomicity
290 *  of the extract operation.
291 */
292RBTree_Node *_RBTree_Insert(
293  RBTree_Control *the_rbtree,
294  RBTree_Node *the_node
295);
296
297
298/**
299 * @brief Extract a Node (unprotected)
300 *
301 *  This routine extracts (removes) @a the_node from @a the_rbtree.
302 *
303 *  @note It does NOT disable interrupts to ensure the atomicity
304 *        of the extract operation.
305 */
306void _RBTree_Extract_unprotected(
307  RBTree_Control *the_rbtree,
308  RBTree_Node *the_node
309);
310
311/**
312 *  @brief Delete a node from the rbtree
313 *
314 *  This routine deletes @a the_node from @a the_rbtree.
315 *
316 *  @note It disables interrupts to ensure the atomicity of the
317 *  append operation.
318 */
319void _RBTree_Extract(
320  RBTree_Control *the_rbtree,
321  RBTree_Node    *the_node
322);
323
324/**
325 * @brief Returns the in-order next node of a node.
326 *
327 * @param[in] rbtree The red-black tree.
328 * @param[in] node The node.
329 * @param[in] dir The direction.
330 *
331 * @retval NULL The in-order next node does not exist.
332 * @retval otherwise The next node.
333 */
334RBTree_Node *_RBTree_Next_unprotected(
335  const RBTree_Control *rbtree,
336  const RBTree_Node *node,
337  RBTree_Direction dir
338);
339
340/**
341 * @copydoc _RBTree_Next_unprotected()
342 *
343 * The function disables the interrupts protect the operation.
344 */
345RBTree_Node *_RBTree_Next(
346  const RBTree_Control *rbtree,
347  const RBTree_Node *node,
348  RBTree_Direction dir
349);
350
351/**
352 * @brief Red-black tree visitor.
353 *
354 * @param[in] node The node.
355 * @param[in] dir The direction.
356 * @param[in] visitor_arg The visitor argument.
357 *
358 * @retval true Stop the iteration.
359 * @retval false Continue the iteration.
360 *
361 * @see _RBTree_Iterate_unprotected().
362 */
363typedef bool (*RBTree_Visitor)(
364  const RBTree_Node *node,
365  RBTree_Direction dir,
366  void *visitor_arg
367);
368
369/**
370 * @brief Red-black tree iteration.
371 *
372 * @param[in] rbtree The red-black tree.
373 * @param[in] dir The direction.
374 * @param[in] visitor The visitor.
375 * @param[in] visitor_arg The visitor argument.
376 */
377void _RBTree_Iterate_unprotected(
378  const RBTree_Control *rbtree,
379  RBTree_Direction dir,
380  RBTree_Visitor visitor,
381  void *visitor_arg
382);
383
384#ifndef __RTEMS_APPLICATION__
385#include <rtems/score/rbtree.inl>
386#endif
387
388#ifdef __cplusplus
389}
390#endif
391
392/**@}*/
393
394#endif
395/* end of include file */
Note: See TracBrowser for help on using the repository browser.