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

4.115
Last change on this file since d8134178 was d8134178, checked in by Alex Ivanov <alexivanov97@…>, on 01/09/13 at 16:20:58

score: Doxygen Clean Up Task #18

http://www.google-melange.com/gci/task/view/google/gci2012/8137204

  • Property mode set to 100644
File size: 12.2 KB
Line 
1/**
2 * @file
3 *
4 * @brief Inlined Routines Associated with Red-Black Trees
5 *
6 * This include file contains the bodies of the routines which are
7 * associated with Red-Black Trees and inlined.
8 *
9 * @note  The routines in this file are ordered from simple
10 *        to complex.  No other RBTree Handler routine is referenced
11 *        unless it has already been defined.
12 */
13
14/*
15 *  Copyright (c) 2010-2012 Gedare Bloom.
16 *
17 *  The license and distribution terms for this file may be
18 *  found in the file LICENSE in this distribution or at
19 *  http://www.rtems.com/license/LICENSE.
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
35/**
36 * @brief Get the direction opposite to @a the_dir.
37 */
38RTEMS_INLINE_ROUTINE RBTree_Direction _RBTree_Opposite_direction(
39  RBTree_Direction the_dir
40)
41{
42  return (RBTree_Direction) !((int) the_dir);
43}
44
45/**
46 * @brief Set off RBtree.
47 *
48 * This function sets the parent and child fields of the @a node to NULL
49 * indicating the @a node is not part of a rbtree.
50 *
51 */
52RTEMS_INLINE_ROUTINE void _RBTree_Set_off_rbtree(
53    RBTree_Node *node
54    )
55{
56  node->parent = node->child[RBT_LEFT] = node->child[RBT_RIGHT] = NULL;
57}
58
59/**
60 * @brief Is the node off RBTree.
61 *
62 * This function returns true if the @a node is not on a rbtree. A @a node is
63 * off rbtree if the parent and child fields are set to NULL.
64 */
65RTEMS_INLINE_ROUTINE bool _RBTree_Is_node_off_rbtree(
66    const RBTree_Node *node
67    )
68{
69  return (node->parent == NULL) && (node->child[RBT_LEFT] == NULL) && (node->child[RBT_RIGHT] == NULL);
70}
71
72/**
73 * @brief Are two Nodes equal.
74 *
75 * This function returns true if @a left and @a right are equal,
76 * and false otherwise.
77 *
78 * @retval true @a left and @a right are equal.
79 * @retval false @a left and @a right are not equal.
80 */
81RTEMS_INLINE_ROUTINE bool _RBTree_Are_nodes_equal(
82    const RBTree_Node *left,
83    const RBTree_Node *right
84    )
85{
86  return left == right;
87}
88
89/**
90 * @brief Is this RBTree control pointer NULL.
91 *
92 * This function returns true if @a the_rbtree is NULL and false otherwise.
93 *
94 * @retval true @a the_rbtree is @c NULL.
95 * @retval false @a the_rbtree is not @c NULL.
96 */
97RTEMS_INLINE_ROUTINE bool _RBTree_Is_null(
98    const RBTree_Control *the_rbtree
99    )
100{
101  return (the_rbtree == NULL);
102}
103
104/**
105 * @brief Is the RBTree node pointer NUL.
106 *
107 * This function returns true if @a the_node is NULL and false otherwise.
108 *
109 * @retval true @a the_node is @c NULL.
110 * @retval false @a the_node is not @c NULL.
111 */
112RTEMS_INLINE_ROUTINE bool _RBTree_Is_null_node(
113    const RBTree_Node *the_node
114    )
115{
116  return (the_node == NULL);
117}
118
119
120/**
121 * @brief Return pointer to RBTree's root node.
122 *
123 * This function returns a pointer to the root node of @a the_rbtree.
124 */
125RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Root(
126  const RBTree_Control *the_rbtree
127)
128{
129  return the_rbtree->root;
130}
131
132/**
133 * @brief Return pointer to RBTree's first node.
134 *
135 * This function returns a pointer to the first node on @a the_rbtree,
136 * where @a dir specifies whether to return the minimum (0) or maximum (1).
137 */
138RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_First(
139  const RBTree_Control *the_rbtree,
140  RBTree_Direction dir
141)
142{
143  return the_rbtree->first[dir];
144}
145
146/**
147 * @brief Return pointer to the parent of this node.
148 *
149 * This function returns a pointer to the parent node of @a the_node.
150 */
151RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Parent(
152  const RBTree_Node *the_node
153)
154{
155  if (!the_node->parent->parent) return NULL;
156  return the_node->parent;
157}
158
159/**
160 * @brief Return pointer to the left of this node.
161 *
162 * This function returns a pointer to the left node of this node.
163 *
164 * @param[in] the_node is the node to be operated upon.
165 *
166 * @return This method returns the left node on the rbtree.
167 */
168RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Left(
169  const RBTree_Node *the_node
170)
171{
172  return the_node->child[RBT_LEFT];
173}
174
175/**
176 * @brief Return pointer to the right of this node.
177 *
178 * This function returns a pointer to the right node of this node.
179 *
180 * @param[in] the_node is the node to be operated upon.
181 *
182 * @return This method returns the right node on the rbtree.
183 */
184RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Right(
185  const RBTree_Node *the_node
186)
187{
188  return the_node->child[RBT_RIGHT];
189}
190
191/**
192 * @brief Is the RBTree empty.
193 *
194 * This function returns true if there are no nodes on @a the_rbtree and
195 * false otherwise.
196 *
197 * @param[in] the_rbtree is the rbtree to be operated upon.
198 *
199 * @retval true There are no nodes on @a the_rbtree.
200 * @retval false There are nodes on @a the_rbtree.
201 */
202RTEMS_INLINE_ROUTINE bool _RBTree_Is_empty(
203  const RBTree_Control *the_rbtree
204)
205{
206  return (the_rbtree->root == NULL);
207}
208
209/**
210 * @brief Is this the first node on the RBTree.
211 *
212 * This function returns true if @a the_node is the first node on
213 * @a the_rbtree and false otherwise. @a dir specifies whether first means
214 * minimum (0) or maximum (1).
215 *
216 * @retval true @a the_node is the first node on @a the_rbtree.
217 * @retval false @a the_node is not the first node on @a the_rbtree.
218 *
219 */
220RTEMS_INLINE_ROUTINE bool _RBTree_Is_first(
221  const RBTree_Control *the_rbtree,
222  const RBTree_Node *the_node,
223  RBTree_Direction dir
224)
225{
226  return (the_node == _RBTree_First(the_rbtree, dir));
227}
228
229/**
230 * @brief Is this node red.
231 *
232 * This function returns true if @a the_node is red and false otherwise.
233 *
234 * @retval true @a the_node is red.
235 * @retval false @a the_node in not red.
236 */
237RTEMS_INLINE_ROUTINE bool _RBTree_Is_red(
238    const RBTree_Node *the_node
239    )
240{
241  return (the_node && the_node->color == RBT_RED);
242}
243
244
245/**
246 * @brief Does this RBTree have only one node.
247 *
248 * This function returns true if there is only one node on @a the_rbtree and
249 * false otherwise.
250 *
251 * @retval true @a the_rbtree has only one node.
252 * @retval false @a the_rbtree has more than one nodes.
253 */
254RTEMS_INLINE_ROUTINE bool _RBTree_Has_only_one_node(
255    const RBTree_Control *the_rbtree
256    )
257{
258  if(!the_rbtree) return false; /* TODO: expected behavior? */
259  return (the_rbtree->root->child[RBT_LEFT] == NULL && the_rbtree->root->child[RBT_RIGHT] == NULL);
260}
261
262/**
263 * @brief Is this node the RBTree root.
264 *
265 * This function returns true if @a the_node is the root of @a the_rbtree and
266 * false otherwise.
267 *
268 * @retval true @a the_node is the root of @a the_rbtree.
269 * @retval false @a the_node is not the root of @a the_rbtree.
270 */
271RTEMS_INLINE_ROUTINE bool _RBTree_Is_root(
272  const RBTree_Control *the_rbtree,
273  const RBTree_Node    *the_node
274)
275{
276  return (the_node == _RBTree_Root(the_rbtree));
277}
278
279/**
280 * @brief Initialize this RBTree as empty.
281 *
282 * This routine initializes @a the_rbtree to contain zero nodes.
283 */
284RTEMS_INLINE_ROUTINE void _RBTree_Initialize_empty(
285    RBTree_Control          *the_rbtree,
286    RBTree_Compare_function  compare_function,
287    bool                     is_unique
288    )
289{
290  the_rbtree->permanent_null   = NULL;
291  the_rbtree->root             = NULL;
292  the_rbtree->first[0]         = NULL;
293  the_rbtree->first[1]         = NULL;
294  the_rbtree->compare_function = compare_function;
295  the_rbtree->is_unique        = is_unique;
296}
297
298/**
299 * @brief Return a pointer to node's grandparent.
300 *
301 * This function returns a pointer to the grandparent of @a the_node if it
302 * exists, and NULL if not.
303 */
304RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Grandparent(
305  const RBTree_Node *the_node
306)
307{
308  if(!the_node) return NULL;
309  if(!(the_node->parent)) return NULL;
310  if(!(the_node->parent->parent)) return NULL;
311  if(!(the_node->parent->parent->parent)) return NULL;
312  return(the_node->parent->parent);
313}
314
315/**
316 * @brief Return a pointer to node's sibling.
317 *
318 * This function returns a pointer to the sibling of @a the_node if it
319 * exists, and NULL if not.
320 */
321RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Sibling(
322  const RBTree_Node *the_node
323)
324{
325  if(!the_node) return NULL;
326  if(!(the_node->parent)) return NULL;
327  if(!(the_node->parent->parent)) return NULL;
328
329  if(the_node == the_node->parent->child[RBT_LEFT])
330    return the_node->parent->child[RBT_RIGHT];
331  else
332    return the_node->parent->child[RBT_LEFT];
333}
334
335/**
336 * @brief Return a pointer to node's parent's sibling.
337 *
338 * This function returns a pointer to the sibling of the parent of
339 * @a the_node if it exists, and NULL if not.
340 */
341RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Parent_sibling(
342  const RBTree_Node *the_node
343)
344{
345  if(!the_node) return NULL;
346  if(_RBTree_Grandparent(the_node) == NULL) return NULL;
347
348  return _RBTree_Sibling(the_node->parent);
349}
350
351/**
352 * @brief Find the RBTree_Control header given a node in the tree.
353 *
354 * This function returns a pointer to the header of the Red Black
355 * Tree containing @a the_node if it exists, and NULL if not.
356 */
357RTEMS_INLINE_ROUTINE RBTree_Control *_RBTree_Find_header_unprotected(
358    RBTree_Node *the_node
359    )
360{
361  if(!the_node) return NULL;
362  if(!(the_node->parent)) return NULL;
363  while(the_node->parent) the_node = the_node->parent;
364  return (RBTree_Control*)the_node;
365}
366
367RTEMS_INLINE_ROUTINE bool _RBTree_Is_equal( int compare_result )
368{
369  return compare_result == 0;
370}
371
372RTEMS_INLINE_ROUTINE bool _RBTree_Is_greater(
373  int compare_result
374)
375{
376  return compare_result > 0;
377}
378
379RTEMS_INLINE_ROUTINE bool _RBTree_Is_lesser(
380  int compare_result
381)
382{
383  return compare_result < 0;
384}
385
386/**
387 * @brief Returns the predecessor of a node.
388 *
389 * @param[in] rbtree is the red-black tree.
390 * @param[in] node is the node.
391 *
392 * @retval NULL The predecessor does not exist.
393 * @retval otherwise The predecessor node.
394 */
395RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Predecessor_unprotected(
396  const RBTree_Node *node
397)
398{
399  return _RBTree_Next_unprotected( node, RBT_LEFT );
400}
401
402/**
403 * @copydoc _RBTree_Predecessor_unprotected()
404 *
405 * The function disables the interrupts protect the operation.
406 */
407RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Predecessor(
408  const RBTree_Node *node
409)
410{
411  return _RBTree_Next( node, RBT_LEFT );
412}
413
414/**
415 * @brief Returns the successor of a node.
416 *
417 * @param[in] rbtree is the red-black tree.
418 * @param[in] node is the node.
419 *
420 * @retval NULL The successor does not exist.
421 * @retval otherwise The successor node.
422 */
423RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Successor_unprotected(
424  const RBTree_Node *node
425)
426{
427  return _RBTree_Next_unprotected( node, RBT_RIGHT );
428}
429
430/**
431 * @copydoc _RBTree_Successor_unprotected()
432 *
433 * The function disables the interrupts protect the operation.
434 */
435RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Successor(
436  const RBTree_Node *node
437)
438{
439  return _RBTree_Next( node, RBT_RIGHT );
440}
441
442/**
443 * @brief Get the first node (unprotected).
444 *
445 * This function removes the minimum or maximum node from the_rbtree and
446 * returns a pointer to that node.  It does NOT disable interrupts to ensure
447 * the atomicity of the get operation.
448 *
449 * @param[in] the_rbtree is the rbtree to attempt to get the min node from.
450 * @param[in] dir specifies whether to get minimum (0) or maximum (1)
451 *
452 * @return This method returns the min or max node on the rbtree, or NULL.
453 *
454 * @note This routine may return NULL if the RBTree is empty.
455 */
456RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Get_unprotected(
457    RBTree_Control *the_rbtree,
458    RBTree_Direction dir
459    )
460{
461  RBTree_Node *the_node = the_rbtree->first[dir];
462  _RBTree_Extract_unprotected(the_rbtree, the_node);
463  return the_node;
464}
465
466/**
467 * @brief Rotate the_node in the direction passed as second argument.
468 *
469 * This routine rotates @a the_node to the direction @a dir, swapping
470 * @a the_node with its child\[@a dir\].
471 */
472RTEMS_INLINE_ROUTINE void _RBTree_Rotate(
473    RBTree_Node *the_node,
474    RBTree_Direction dir
475    )
476{
477  RBTree_Node *c;
478  if (the_node == NULL) return;
479  if (the_node->child[_RBTree_Opposite_direction(dir)] == NULL) return;
480
481  c = the_node->child[_RBTree_Opposite_direction(dir)];
482  the_node->child[_RBTree_Opposite_direction(dir)] = c->child[dir];
483
484  if (c->child[dir])
485    c->child[dir]->parent = the_node;
486
487  c->child[dir] = the_node;
488
489  the_node->parent->child[the_node != the_node->parent->child[0]] = c;
490
491  c->parent = the_node->parent;
492  the_node->parent = c;
493}
494
495/**
496 * @brief Determines whether the tree is unique.
497 */
498RTEMS_INLINE_ROUTINE bool _RBTree_Is_unique(
499  const RBTree_Control *the_rbtree
500)
501{
502  return( the_rbtree && the_rbtree->is_unique );
503}
504
505/** @} */
506
507#endif
508/* end of include file */
Note: See TracBrowser for help on using the repository browser.