source: rtems/cpukit/sapi/inline/rtems/rbtree.inl @ f53aa8d

4.115
Last change on this file since f53aa8d was f53aa8d, checked in by Gedare Bloom <gedare@…>, on 05/03/12 at 16:43:29

rbtree: API changes. Remove rbtree control node from RBTree_Next.

The implementation of RBTree_Next was using an awkward construction to detect
and avoid accessing the false root of the red-black tree. To deal with the
false root, RBTree_Next was comparing node parents with the control node.
Instead the false root can be detected by checking if the grandparent of a
node exists; the grandparent of the tree's true root is NULL by definition
so the root of the tree is found while walking up the tree by checking for
the non-existence of a grandparent.

This change propagates into the predecessor/successor and iterate functions.

  • Property mode set to 100644
File size: 12.3 KB
Line 
1/**
2 * @file rtems/rbtree.inl
3 *
4 *  This include file contains all the constants and structures associated
5 *  with the RBTree API in RTEMS. The rbtree is a Red Black Tree that
6 *  is part of the Super Core. This is the published interface to that
7 *  code.
8 */
9 
10/*
11 *  Copyright (c) 2010-2012 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.com/license/LICENSE.
16 */
17
18#ifndef _RTEMS_RBTREE_H
19# error "Never use <rtems/rbtree.inl> directly; include <rtems/rbtree.h> instead."
20#endif
21
22#ifndef _RTEMS_RBTREE_INL
23#define _RTEMS_RBTREE_INL
24
25#include <rtems/score/rbtree.inl>
26
27/**
28 *  @brief Initialize a RBTree Header
29 *
30 *  This routine initializes @a the_rbtree structure to manage the
31 *  contiguous array of @a number_nodes nodes which starts at
32 *  @a starting_address.  Each node is of @a node_size bytes.
33 */
34RTEMS_INLINE_ROUTINE void rtems_rbtree_initialize(
35  rtems_rbtree_control          *the_rbtree,
36  rtems_rbtree_compare_function  compare_function,
37  void                          *starting_address,
38  size_t                         number_nodes,
39  size_t                         node_size,
40  bool                           is_unique
41)
42{
43  _RBTree_Initialize( the_rbtree, compare_function, starting_address,
44    number_nodes, node_size, is_unique);
45}
46
47/**
48 *  @brief Initialize this RBTree as Empty
49 *
50 *  This routine initializes @a the_rbtree to contain zero nodes.
51 */
52RTEMS_INLINE_ROUTINE void rtems_rbtree_initialize_empty(
53  rtems_rbtree_control          *the_rbtree,
54  rtems_rbtree_compare_function  compare_function,
55  bool                           is_unique
56)
57{
58  _RBTree_Initialize_empty( the_rbtree, compare_function, is_unique );
59}
60
61/**
62 *  @brief Set off rbtree
63 *
64 *  This function sets the next and previous fields of the @a node to NULL
65 *  indicating the @a node is not part of any rbtree.
66 */
67RTEMS_INLINE_ROUTINE void rtems_rbtree_set_off_rbtree(
68  rtems_rbtree_node *node
69)
70{
71  _RBTree_Set_off_rbtree( node );
72}
73
74/**
75 *  @brief Is the Node off RBTree
76 *
77 *  This function returns true if the @a node is not on a rbtree. A @a node is
78 *  off rbtree if the next and previous fields are set to NULL.
79 */
80RTEMS_INLINE_ROUTINE bool rtems_rbtree_is_node_off_rbtree(
81  const rtems_rbtree_node *node
82)
83{
84  return _RBTree_Is_node_off_rbtree( node );
85}
86
87/**
88 *  @brief Is the RBTree Node Pointer NULL
89 *
90 *  This function returns true if @a the_node is NULL and false otherwise.
91 */
92RTEMS_INLINE_ROUTINE bool rtems_rbtree_is_null_node(
93  const rtems_rbtree_node *the_node
94)
95{
96  return _RBTree_Is_null_node( the_node );
97}
98
99/**
100 *  @brief Return pointer to RBTree Root
101 *
102 *  This function returns a pointer to the root node of @a the_rbtree.
103 */
104RTEMS_INLINE_ROUTINE rtems_rbtree_node *rtems_rbtree_root(
105  const rtems_rbtree_control *the_rbtree
106)
107{
108  return _RBTree_Root( the_rbtree );
109}
110
111/**
112 *  @brief Return pointer to RBTree Minimum
113 *
114 *  This function returns a pointer to the minimum node of @a the_rbtree.
115 */
116RTEMS_INLINE_ROUTINE rtems_rbtree_node *rtems_rbtree_min(
117  const rtems_rbtree_control *the_rbtree
118)
119{
120  return _RBTree_First( the_rbtree, RBT_LEFT );
121}
122
123/**
124 *  @brief Return pointer to RBTree Maximum
125 *
126 *  This function returns a pointer to the maximum node of @a the_rbtree.
127 */
128RTEMS_INLINE_ROUTINE rtems_rbtree_node *rtems_rbtree_max(
129  const rtems_rbtree_control *the_rbtree
130)
131{
132  return _RBTree_First( the_rbtree, RBT_RIGHT );
133}
134
135/**
136 *  @brief Return pointer to the left child node from this node
137 *
138 *  This function returns a pointer to the left child node of @a the_node.
139 */
140RTEMS_INLINE_ROUTINE rtems_rbtree_node *rtems_rbtree_left(
141  const rtems_rbtree_node *the_node
142)
143{
144  return _RBTree_Left( the_node );
145}
146
147/**
148 *  @brief Return pointer to the right child node from this node
149 *
150 *  This function returns a pointer to the right child node of @a the_node.
151 */
152RTEMS_INLINE_ROUTINE rtems_rbtree_node *rtems_rbtree_right(
153  const rtems_rbtree_node *the_node
154)
155{
156  return _RBTree_Right( the_node );
157}
158
159/**
160 *  @brief Return pointer to the parent child node from this node
161 *
162 *  This function returns a pointer to the parent node of @a the_node.
163 */
164RTEMS_INLINE_ROUTINE rtems_rbtree_node *rtems_rbtree_parent(
165  const rtems_rbtree_node *the_node
166)
167{
168  return _RBTree_Parent( the_node );
169}
170
171/**
172 *  @brief Are Two Nodes Equal
173 *
174 *  This function returns true if @a left and @a right are equal,
175 *  and false otherwise.
176 */
177RTEMS_INLINE_ROUTINE bool rtems_rbtree_are_nodes_equal(
178  const rtems_rbtree_node *left,
179  const rtems_rbtree_node *right
180)
181{
182  return _RBTree_Are_nodes_equal( left, right );
183}
184
185/**
186 *  @brief Is the RBTree Empty
187 *
188 *  This function returns true if there a no nodes on @a the_rbtree and
189 *  false otherwise.
190 */
191RTEMS_INLINE_ROUTINE bool rtems_rbtree_is_empty(
192  const rtems_rbtree_control *the_rbtree
193)
194{
195  return _RBTree_Is_empty( the_rbtree );
196}
197
198/**
199 *  @brief Is this the Minimum Node on the RBTree
200 *
201 *  This function returns true if @a the_node is the min node on @a the_rbtree
202 *  and false otherwise.
203 */
204RTEMS_INLINE_ROUTINE bool rtems_rbtree_is_min(
205  const rtems_rbtree_control *the_rbtree,
206  const rtems_rbtree_node *the_node
207)
208{
209  return _RBTree_Is_first( the_rbtree, the_node, RBT_LEFT );
210}
211
212/**
213 *  @brief Is this the Maximum Node on the RBTree
214 *
215 *  This function returns true if @a the_node is the max node on @a the_rbtree
216 *  and false otherwise.
217 */
218RTEMS_INLINE_ROUTINE bool rtems_rbtree_is_max(
219  const rtems_rbtree_control *the_rbtree,
220  const rtems_rbtree_node *the_node
221)
222{
223  return _RBTree_Is_first( the_rbtree, the_node, RBT_RIGHT );
224}
225
226
227/**
228 *  @brief Does this RBTree have only One Node
229 *
230 *  This function returns true if there is only one node on @a the_rbtree and
231 *  false otherwise.
232 */
233RTEMS_INLINE_ROUTINE bool rtems_rbtree_has_only_one_node(
234  const rtems_rbtree_control *the_rbtree
235)
236{
237  return _RBTree_Has_only_one_node( the_rbtree );
238}
239
240/**
241 *  @brief Is this Node the RBTree Root
242 *
243 *  This function returns true if @a the_node is the root of @a the_rbtree and
244 *  false otherwise.
245 */
246RTEMS_INLINE_ROUTINE bool rtems_rbtree_is_root(
247  const rtems_rbtree_control *the_rbtree,
248  const rtems_rbtree_node *the_node
249)
250{
251  return _RBTree_Is_root( the_rbtree, the_node );
252}
253
254/**
255 * @copydoc _RBTree_Find_unprotected()
256 */
257RTEMS_INLINE_ROUTINE rtems_rbtree_node* rtems_rbtree_find_unprotected(
258    rtems_rbtree_control *the_rbtree,
259    rtems_rbtree_node *the_node
260)
261{
262  return _RBTree_Find_unprotected( the_rbtree, the_node );
263}
264
265/** @brief Find the node with given key in the tree
266 *
267 *  This function returns a pointer to the node having key equal to the key
268 *  of @a the_node if it exists within @a the_rbtree, and NULL if not.
269 *  @a the_node has to be made up before a search.
270 *
271 *  @note If the tree is not unique and contains duplicate keys, the set
272 *        of duplicate keys acts as FIFO.
273 */
274RTEMS_INLINE_ROUTINE rtems_rbtree_node* rtems_rbtree_find(
275  rtems_rbtree_control *the_rbtree,
276  rtems_rbtree_node *the_node
277)
278{
279  return _RBTree_Find( the_rbtree, the_node );
280}
281
282/**
283 * @copydoc _RBTree_Predecessor_unprotected()
284 */
285RTEMS_INLINE_ROUTINE rtems_rbtree_node* rtems_rbtree_predecessor_unprotected(
286  const rtems_rbtree_node *node
287)
288{
289  return _RBTree_Predecessor_unprotected( node );
290}
291
292/**
293 * @copydoc _RBTree_Predecessor()
294 */
295RTEMS_INLINE_ROUTINE rtems_rbtree_node* rtems_rbtree_predecessor(
296  const rtems_rbtree_node *node
297)
298{
299  return _RBTree_Predecessor( node );
300}
301
302/**
303 * @copydoc _RBTree_Successor_unprotected()
304 */
305RTEMS_INLINE_ROUTINE rtems_rbtree_node* rtems_rbtree_successor_unprotected(
306  const rtems_rbtree_node *node
307)
308{
309  return _RBTree_Successor_unprotected( node );
310}
311
312/**
313 * @copydoc _RBTree_Successor()
314 */
315RTEMS_INLINE_ROUTINE rtems_rbtree_node* rtems_rbtree_successor(
316  const rtems_rbtree_node *node
317)
318{
319  return _RBTree_Successor( node );
320}
321
322/**
323 * @copydoc _RBTree_Extract_unprotected()
324 */
325RTEMS_INLINE_ROUTINE void rtems_rbtree_extract_unprotected(
326  rtems_rbtree_control *the_rbtree,
327  rtems_rbtree_node *the_node
328)
329{
330  _RBTree_Extract_unprotected( the_rbtree, the_node );
331}
332
333/**
334 *  @brief Extract the specified node from a rbtree
335 *
336 *  This routine extracts @a the_node from @a the_rbtree on which it resides.
337 *  It disables interrupts to ensure the atomicity of the extract operation.
338 */
339RTEMS_INLINE_ROUTINE void rtems_rbtree_extract(
340  rtems_rbtree_control *the_rbtree,
341  rtems_rbtree_node *the_node
342)
343{
344  _RBTree_Extract( the_rbtree, the_node );
345}
346
347/**
348 *  @brief Obtain the min node on a rbtree
349 *
350 *  This function removes the min node from @a the_rbtree and returns
351 *  a pointer to that node.  If @a the_rbtree is empty, then NULL is returned.
352 */
353
354RTEMS_INLINE_ROUTINE rtems_rbtree_node *rtems_rbtree_get_min_unprotected(
355  rtems_rbtree_control *the_rbtree
356)
357{
358  return _RBTree_Get_unprotected( the_rbtree, RBT_LEFT );
359}
360
361/**
362 *  @brief Obtain the min node on a rbtree
363 *
364 *  This function removes the min node from @a the_rbtree and returns
365 *  a pointer to that node.  If @a the_rbtree is empty, then NULL is returned.
366 *  It disables interrupts to ensure the atomicity of the get operation.
367 */
368RTEMS_INLINE_ROUTINE rtems_rbtree_node *rtems_rbtree_get_min(
369  rtems_rbtree_control *the_rbtree
370)
371{
372  return _RBTree_Get( the_rbtree, RBT_LEFT );
373}
374
375/**
376 *  @brief Obtain the max node on a rbtree
377 *
378 *  This function removes the max node from @a the_rbtree and returns
379 *  a pointer to that node.  If @a the_rbtree is empty, then NULL is returned.
380 */
381
382RTEMS_INLINE_ROUTINE rtems_rbtree_node *rtems_rbtree_get_max_unprotected(
383  rtems_rbtree_control *the_rbtree
384)
385{
386  return _RBTree_Get_unprotected( the_rbtree, RBT_RIGHT );
387}
388
389/**
390 *  @brief Obtain the max node on a rbtree
391 *
392 *  This function removes the max node from @a the_rbtree and returns
393 *  a pointer to that node.  If @a the_rbtree is empty, then NULL is returned.
394 *  It disables interrupts to ensure the atomicity of the get operation.
395 */
396RTEMS_INLINE_ROUTINE rtems_rbtree_node *rtems_rbtree_get_max(
397  rtems_rbtree_control *the_rbtree
398)
399{
400  return _RBTree_Get( the_rbtree, RBT_RIGHT );
401}
402
403/**
404 *  @brief Peek at the min node on a rbtree
405 *
406 *  This function returns a pointer to the min node from @a the_rbtree
407 *  without changing the tree.  If @a the_rbtree is empty,
408 *  then NULL is returned.
409 */
410RTEMS_INLINE_ROUTINE rtems_rbtree_node *rtems_rbtree_peek_min(
411  const rtems_rbtree_control *the_rbtree
412)
413{
414  return _RBTree_First( the_rbtree, RBT_LEFT );
415}
416
417/**
418 *  @brief Peek at the max node on a rbtree
419 *
420 *  This function returns a pointer to the max node from @a the_rbtree
421 *  without changing the tree.  If @a the_rbtree is empty,
422 *  then NULL is returned.
423 */
424RTEMS_INLINE_ROUTINE rtems_rbtree_node *rtems_rbtree_peek_max(
425  const rtems_rbtree_control *the_rbtree
426)
427{
428  return _RBTree_First( the_rbtree, RBT_RIGHT );
429}
430
431/**
432 * @copydoc _RBTree_Find_header_unprotected()
433 */
434RTEMS_INLINE_ROUTINE rtems_rbtree_control *rtems_rbtree_find_header_unprotected(
435  rtems_rbtree_node *the_node
436)
437{
438  return _RBTree_Find_header_unprotected( the_node );
439}
440
441/**
442 *  @brief Find the control header of the tree containing a given node.
443 *
444 *  This routine finds the rtems_rbtree_control structure of the tree
445 *  containing @a the_node.
446 *  It disables interrupts to ensure the atomicity of the find operation.
447 */
448RTEMS_INLINE_ROUTINE rtems_rbtree_control *rtems_rbtree_find_header(
449  rtems_rbtree_node *the_node
450)
451{
452  return _RBTree_Find_header( the_node );
453}
454
455/**
456 * @copydoc _RBTree_Insert_unprotected()
457 */
458RTEMS_INLINE_ROUTINE rtems_rbtree_node *rtems_rbtree_insert_unprotected(
459  rtems_rbtree_control *the_rbtree,
460  rtems_rbtree_node *the_node
461)
462{
463  return _RBTree_Insert_unprotected( the_rbtree, the_node );
464}
465
466/**
467 *  @brief Insert a node on a rbtree
468 *
469 *  This routine inserts @a the_node on @a the_rbtree.
470 *  It disables interrupts to ensure the atomicity of the insert operation.
471 *
472 *  @retval 0 Successfully inserted.
473 *  @retval -1 NULL @a the_node.
474 *  @retval RBTree_Node* if one with equal key to the key of @a the_node exists
475 *          in an unique @a the_rbtree.
476 */
477RTEMS_INLINE_ROUTINE rtems_rbtree_node *rtems_rbtree_insert(
478  rtems_rbtree_control *the_rbtree,
479  rtems_rbtree_node *the_node
480)
481{
482  return _RBTree_Insert( the_rbtree, the_node );
483}
484
485/** @brief Determines whether the tree is unique
486 */
487RTEMS_INLINE_ROUTINE bool rtems_rbtree_is_unique(
488  const rtems_rbtree_control *the_rbtree
489)
490{
491  return _RBTree_Is_unique(the_rbtree);
492}
493
494#endif
495/* end of include file */
Note: See TracBrowser for help on using the repository browser.