source: rtems/cpukit/score/inline/rtems/score/rbtree.inl @ bd9baa81

4.115
Last change on this file since bd9baa81 was bd9baa81, checked in by Joel Sherrill <joel.sherrill@…>, on 04/04/11 at 18:44:16

2010-07-28 Gedare Bloom <giddyup44@…>

PR 1641/cpukit

  • sapi/Makefile.am, sapi/preinstall.am, score/Makefile.am, score/preinstall.am: Add Red Black Tree data structure to score.
  • sapi/include/rtems/rbtree.h, sapi/inline/rtems/rbtree.inl, score/include/rtems/score/rbtree.h, score/inline/rtems/score/rbtree.inl, score/src/rbtree.c, score/src/rbtreeextract.c, score/src/rbtreefind.c, score/src/rbtreefindheader.c, score/src/rbtreeget.c, score/src/rbtreeinsert.c, score/src/rbtreepeek.c: New files.
  • Property mode set to 100644
File size: 11.3 KB
Line 
1/**
2 *  @file  rtems/score/rbtree.inl
3 *
4 *  This include file contains the bodies of the routines which are
5 *  associated with Red-Black Trees and inlined.
6 *
7 *  @note  The routines in this file are ordered from simple
8 *         to complex.  No other RBTree Handler routine is referenced
9 *         unless it has already been defined.
10 */
11
12/*
13 *  Copyright (c) 2010 Gedare Bloom.
14 *
15 *  The license and distribution terms for this file may be
16 *  found in the file LICENSE in this distribution or at
17 *  http://www.rtems.com/license/LICENSE.
18 *
19 *  $Id$
20 */
21
22#ifndef _RTEMS_SCORE_RBTREE_H
23# error "Never use <rtems/score/rbtree.inl> directly; include <rtems/score/rbtree.h> instead."
24#endif
25
26#ifndef _RTEMS_SCORE_RBTREE_INL
27#define _RTEMS_SCORE_RBTREE_INL
28
29/**
30 *  @addtogroup ScoreRBTree
31 *  @{
32 */
33
34/** @brief Set off rbtree
35 *
36 *  This function sets the parent and child fields of the @a node to NULL
37 *  indicating the @a node is not part of a rbtree.
38 *
39 */
40RTEMS_INLINE_ROUTINE void _RBTree_Set_off_rbtree(
41    RBTree_Node *node
42    )
43{
44  node->parent = node->child[RBT_LEFT] = node->child[RBT_RIGHT] = NULL;
45}
46
47/** @brief Is the Node off RBTree
48 *
49 *  This function returns true if the @a node is not on a rbtree. A @a node is
50 *  off rbtree if the parent and child fields are set to NULL.
51 */
52RTEMS_INLINE_ROUTINE bool _RBTree_Is_node_off_rbtree(
53    const RBTree_Node *node
54    )
55{
56  return (node->parent == NULL) && (node->child[RBT_LEFT] == NULL) && (node->child[RBT_RIGHT] == NULL);
57}
58
59/** @brief Are Two Nodes Equal
60 *
61 *  This function returns true if @a left and @a right are equal,
62 *  and false otherwise.
63 */
64RTEMS_INLINE_ROUTINE bool _RBTree_Are_nodes_equal(
65    const RBTree_Node *left,
66    const RBTree_Node *right
67    )
68{
69  return left == right;
70}
71
72/** @brief Is this RBTree Control Pointer Null
73 *
74 *  This function returns true if @a the_rbtree is NULL and false otherwise.
75 */
76RTEMS_INLINE_ROUTINE bool _RBTree_Is_null(
77    const RBTree_Control *the_rbtree
78    )
79{
80  return (the_rbtree == NULL);
81}
82
83/** @brief Is the RBTree Node Pointer NULL
84 *
85 *  This function returns true if @a the_node is NULL and false otherwise.
86 */
87RTEMS_INLINE_ROUTINE bool _RBTree_Is_null_node(
88    const RBTree_Node *the_node
89    )
90{
91  return (the_node == NULL);
92}
93
94
95/** @brief Return pointer to RBTree's root node
96 *
97 *  This function returns a pointer to the root node of @a the_rbtree.
98 */
99RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Root(
100    RBTree_Control *the_rbtree
101    )
102{
103  return the_rbtree->root;
104}
105
106/** @brief Return pointer to RBTree's First node
107 *
108 *  This function returns a pointer to the first node on @a the_rbtree,
109 *  where @a dir specifies whether to return the minimum (0) or maximum (1).
110 */
111RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_First(
112    RBTree_Control *the_rbtree,
113    RBTree_Direction dir
114    )
115{
116  return the_rbtree->first[dir];
117}
118
119/** @brief Return pointer to the parent of this node
120 *
121 *  This function returns a pointer to the parent node of @a the_node.
122 */
123RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Parent(
124    RBTree_Node *the_node
125    )
126{
127  if (!the_node->parent->parent) return NULL;
128  return the_node->parent;
129}
130
131/** @brief Return pointer to the left of this node
132 *
133 *  This function returns a pointer to the left node of this node.
134 *
135 *  @param[in] the_node is the node to be operated upon.
136 *
137 *  @return This method returns the left node on the rbtree.
138 */
139RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Left(
140    RBTree_Node *the_node
141    )
142{
143  return the_node->child[RBT_LEFT];
144}
145
146/** @brief Return pointer to the right of this node
147 *
148 *  This function returns a pointer to the right node of this node.
149 *
150 *  @param[in] the_node is the node to be operated upon.
151 *
152 *  @return This method returns the right node on the rbtree.
153 */
154RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Right(
155    RBTree_Node *the_node
156    )
157{
158  return the_node->child[RBT_RIGHT];
159}
160
161/** @brief Is the RBTree Empty
162 *
163 *  This function returns true if there are no nodes on @a the_rbtree and
164 *  false otherwise.
165 *
166 *  @param[in] the_rbtree is the rbtree to be operated upon.
167 *
168 *  @return This function returns true if there are no nodes on
169 *  @a the_rbtree and false otherwise.
170 */
171RTEMS_INLINE_ROUTINE bool _RBTree_Is_empty(
172    RBTree_Control *the_rbtree
173    )
174{
175  return (the_rbtree->root == NULL);
176}
177
178/** @brief Is this the First Node on the RBTree
179 *
180 *  This function returns true if @a the_node is the first node on
181 *  @a the_rbtree and false otherwise. @a dir specifies whether first means
182 *  minimum (0) or maximum (1).
183 *
184 */
185RTEMS_INLINE_ROUTINE bool _RBTree_Is_first(
186    RBTree_Control *the_rbtree,
187    const RBTree_Node *the_node,
188    RBTree_Direction dir
189    )
190{
191  return (the_node == _RBTree_First(the_rbtree, dir));
192}
193
194/** @brief Is this node red?
195 *
196 *  This function returns true if @a the_node is red and false otherwise.
197 */
198RTEMS_INLINE_ROUTINE bool _RBTree_Is_red(
199    const RBTree_Node *the_node
200    )
201{
202  return (the_node && the_node->color == RBT_RED);
203}
204
205
206/** @brief Does this RBTree have only One Node
207 *
208 *  This function returns true if there is only one node on @a the_rbtree and
209 *  false otherwise.
210 *
211 */
212RTEMS_INLINE_ROUTINE bool _RBTree_Has_only_one_node(
213    const RBTree_Control *the_rbtree
214    )
215{
216  if(!the_rbtree) return NULL; /* TODO: expected behavior? */
217  return (the_rbtree->root->child[RBT_LEFT] == NULL && the_rbtree->root->child[RBT_RIGHT] == NULL);
218}
219
220/** @brief Is this Node the RBTree root
221 *
222 *  This function returns true if @a the_node is the root of @a the_rbtree and
223 *  false otherwise.
224 */
225RTEMS_INLINE_ROUTINE bool _RBTree_Is_root(
226    RBTree_Control *the_rbtree,
227    const RBTree_Node    *the_node
228    )
229{
230  return (the_node == _RBTree_Root(the_rbtree));
231}
232
233/** @brief Initialize this RBTree as Empty
234 *
235 *  This routine initializes @a the_rbtree to contain zero nodes.
236 */
237RTEMS_INLINE_ROUTINE void _RBTree_Initialize_empty(
238    RBTree_Control *the_rbtree
239    )
240{
241  the_rbtree->permanent_null = NULL;
242  the_rbtree->root           = NULL;
243  the_rbtree->first[0]       = NULL;
244  the_rbtree->first[1]       = NULL;
245}
246
247/** @brief Return a pointer to node's grandparent
248 *
249 *  This function returns a pointer to the grandparent of @a the_node if it
250 *  exists, and NULL if not.
251 * 
252 */
253RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Grandparent(
254    RBTree_Node *the_node
255    )
256{
257  if(!the_node) return NULL;
258  if(!(the_node->parent)) return NULL;
259  if(!(the_node->parent->parent)) return NULL;
260  if(!(the_node->parent->parent->parent)) return NULL;
261  return(the_node->parent->parent);
262}
263
264/** @brief Return a pointer to node's sibling
265 *
266 *  This function returns a pointer to the sibling of @a the_node if it
267 *  exists, and NULL if not.
268 */
269RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Sibling(
270    RBTree_Node *the_node
271    )
272{
273  if(!the_node) return NULL;
274  if(!(the_node->parent)) return NULL;
275  if(!(the_node->parent->parent)) return NULL;
276
277  if(the_node == the_node->parent->child[RBT_LEFT])
278    return the_node->parent->child[RBT_RIGHT];
279  else
280    return the_node->parent->child[RBT_LEFT];
281}
282
283/** @brief Return a pointer to node's parent's sibling
284 *
285 *  This function returns a pointer to the sibling of the parent of
286 *  @a the_node if it exists, and NULL if not.
287 */
288RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Parent_sibling(
289    RBTree_Node *the_node
290    )
291{
292  if(!the_node) return NULL;
293  if(_RBTree_Grandparent(the_node) == NULL) return NULL;
294
295  return _RBTree_Sibling(the_node->parent);
296}
297
298/** @brief Find the RBTree_Control header given a node in the tree
299 *
300 *  This function returns a pointer to the header of the Red Black
301 *  Tree containing @a the_node if it exists, and NULL if not.
302 */
303RTEMS_INLINE_ROUTINE RBTree_Control *_RBTree_Find_header_unprotected(
304    RBTree_Node *the_node
305    )
306{
307  if(!the_node) return NULL;
308  if(!(the_node->parent)) return NULL;
309  while(the_node->parent) the_node = the_node->parent;
310  return (RBTree_Control*)the_node;
311}
312
313/** @brief Find the node with given value in the tree
314 *
315 *  This function returns a pointer to the node in @a the_rbtree
316 *  having value equal to @a the_value if it exists, and NULL if not.
317 */
318RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Find_unprotected(
319    RBTree_Control *the_rbtree,
320    unsigned int the_value
321    )
322{
323  RBTree_Node* iter_node = the_rbtree->root;
324  while (iter_node) {
325    if (the_value == iter_node->value) return(iter_node);
326
327    RBTree_Direction dir = the_value > iter_node->value;
328    iter_node = iter_node->child[dir];
329  } /* while(iter_node) */
330
331  return 0;
332}
333
334/** @brief Find the nodes in-order predecessor
335 *
336 *  This function returns a pointer to the in-order predecessor
337 *  of @a the_node if it exists, and NULL if not.
338 */
339RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Predecessor(
340    RBTree_Node *the_node
341    )
342{
343  RBTree_Node* iter_node;
344  if (!the_node) return NULL;
345  iter_node = the_node->child[RBT_LEFT];
346  if (!iter_node) return NULL;
347  while (iter_node->child[RBT_RIGHT]) {
348    iter_node = iter_node->child[RBT_RIGHT];
349  }
350  return iter_node;
351}
352
353/** @brief Find the nodes in-order successor
354 *
355 *  This function returns a pointer to the in-order successor 
356 *  of @a the_node if it exists, and NULL if not.
357 */
358RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Successor(
359    RBTree_Node *the_node
360    )
361{
362  RBTree_Node* iter_node;
363  if (!the_node) return NULL;
364  iter_node = the_node->child[RBT_RIGHT];
365  if (!iter_node) return NULL;
366  while (iter_node->child[RBT_LEFT]) {
367    iter_node = iter_node->child[RBT_LEFT];
368  }
369  return iter_node;
370}
371
372/** @brief Get the First Node (unprotected)
373 *
374 *  This function removes the minimum or maximum node from the_rbtree and
375 *  returns a pointer to that node.  It does NOT disable interrupts to ensure
376 *  the atomicity of the get operation.
377 *
378 *  @param[in] the_rbtree is the rbtree to attempt to get the min node from.
379 *  @param[in] dir specifies whether to get minimum (0) or maximum (1)
380 *
381 *  @return This method returns the min or max node on the rbtree, or NULL.
382 *
383 *  @note This routine may return NULL if the RBTree is empty.
384 */
385RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Get_unprotected(
386    RBTree_Control *the_rbtree,
387    RBTree_Direction dir
388    )
389{
390  RBTree_Node *the_node = the_rbtree->first[dir];
391  _RBTree_Extract_unprotected(the_rbtree, the_node);
392  return the_node;
393}
394
395/** @brief Peek at the First Node (unprotected)
396 *
397 *  This function returns a pointer to the first node, minimum if @a dir is 0
398 *  or maximum if @a dir is 1, from @a the_rbtree without extracting it. 
399 *  It does NOT disable interrupts to ensure the atomicity of the peek.
400 *
401 *  @retval NULL if @a the_rbtree is empty.
402 */
403RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Peek_unprotected(
404    RBTree_Control *the_rbtree,
405    RBTree_Direction dir
406    )
407{
408  return(the_rbtree->first[dir]);
409}
410
411/** @brief Rotate the_node in the direction passed as second argument
412 * 
413 *  This routine rotates @a the_node to the direction @a dir, swapping
414 *  @a the_node with its child\[@a dir\].
415 */
416RTEMS_INLINE_ROUTINE void _RBTree_Rotate(
417    RBTree_Node *the_node,
418    RBTree_Direction dir
419    )
420{
421  RBTree_Node *c;
422  if (the_node == NULL) return;
423  if (the_node->child[(1-dir)] == NULL) return;
424 
425
426  c = the_node->child[(1-dir)];
427  the_node->child[(1-dir)] = c->child[dir];
428
429  if (c->child[dir])
430    c->child[dir]->parent = the_node;
431
432  c->child[dir] = the_node;
433
434  the_node->parent->child[the_node != the_node->parent->child[0]] = c;
435
436  c->parent = the_node->parent;
437  the_node->parent = c;
438}
439/**@}*/
440
441#endif
442/* end of include file */
Note: See TracBrowser for help on using the repository browser.