source: rtems/cpukit/include/rtems/rbtree.h @ a660e9dc

Last change on this file since a660e9dc was a660e9dc, checked in by Sebastian Huber <sebastian.huber@…>, on 09/08/22 at 08:37:05

Do not use RTEMS_INLINE_ROUTINE

Directly use "static inline" which is available in C99 and later. This brings
the RTEMS implementation closer to standard C.

Close #3935.

  • Property mode set to 100644
File size: 12.1 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @ingroup RTEMSAPIClassicRBTrees
7 *
8 * @brief This header file provides the Red-Black Trees API.
9 */
10
11/*
12 *  Copyright (c) 2010 Gedare Bloom.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 * 1. Redistributions of source code must retain the above copyright
18 *    notice, this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 *    notice, this list of conditions and the following disclaimer in the
21 *    documentation and/or other materials provided with the distribution.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 */
35
36#ifndef _RTEMS_RBTREE_H
37#define _RTEMS_RBTREE_H
38
39#include <rtems/score/rbtree.h>
40
41#ifdef __cplusplus
42extern "C" {
43#endif
44
45/**
46 * @defgroup RTEMSAPIRBTrees Red-Black Trees
47 *
48 * @ingroup RTEMSAPIClassic
49 *
50 * @brief The red-black tree container provides data structures and directives
51 *   to manage user-defined data structures in red-black trees.
52 *
53 * The red-black tree container offers no internal protection against
54 * concurrent access.  The user must ensure that at most one thread at once can
55 * access a red-black tree instance.
56 *
57 * @{
58 */
59
60/**
61 * @typedef rtems_rbtree_node
62 *
63 * A node that can be manipulated in the rbtree.
64 */
65typedef RBTree_Node rtems_rbtree_node;
66
67/**
68 * @typedef rtems_rbtree_control
69 *
70 * The rbtree's control anchors the rbtree.
71 */
72typedef RBTree_Control rtems_rbtree_control;
73
74/**
75 * @brief Integer type for compare results.
76 *
77 * The type is large enough to represent pointers and 32-bit signed integers.
78 *
79 * @see rtems_rbtree_compare.
80 */
81typedef long rtems_rbtree_compare_result;
82
83/**
84 * @brief Compares two red-black tree nodes.
85 *
86 * @param[in] first The first node.
87 * @param[in] second The second node.
88 *
89 * @retval positive The key value of the first node is greater than the one of
90 *   the second node.
91 * @retval 0 The key value of the first node is equal to the one of the second
92 *   node.
93 * @retval negative The key value of the first node is less than the one of the
94 *   second node.
95 */
96typedef rtems_rbtree_compare_result ( *rtems_rbtree_compare )(
97  const RBTree_Node *first,
98  const RBTree_Node *second
99);
100
101/**
102 * @brief RBTree initializer for an empty rbtree with designator @a name.
103 */
104#define RTEMS_RBTREE_INITIALIZER_EMPTY(name) \
105  RBTREE_INITIALIZER_EMPTY(name)
106
107/**
108 * @brief RBTree definition for an empty rbtree with designator @a name.
109 */
110#define RTEMS_RBTREE_DEFINE_EMPTY(name) \
111  RBTREE_DEFINE_EMPTY(name)
112
113/**
114 * @brief Initialize a RBTree header.
115 *
116 * This routine initializes @a the_rbtree structure to manage the
117 * contiguous array of @a number_nodes nodes which starts at
118 * @a starting_address.  Each node is of @a node_size bytes.
119 *
120 * @param[in] the_rbtree is the pointer to rbtree header
121 * @param[in] compare The node compare function.
122 * @param[in] starting_address is the starting address of first node
123 * @param[in] number_nodes is the number of nodes in rbtree
124 * @param[in] node_size is the size of node in bytes
125 * @param[in] is_unique If true, then reject nodes with a duplicate key, else
126 *   otherwise.
127 */
128void rtems_rbtree_initialize(
129  rtems_rbtree_control *the_rbtree,
130  rtems_rbtree_compare  compare,
131  void                 *starting_address,
132  size_t                number_nodes,
133  size_t                node_size,
134  bool                  is_unique
135);
136
137/**
138 * @brief Initialize this RBTree as Empty
139 *
140 * This routine initializes @a the_rbtree to contain zero nodes.
141 */
142static inline void rtems_rbtree_initialize_empty(
143  rtems_rbtree_control *the_rbtree
144)
145{
146  _RBTree_Initialize_empty( the_rbtree );
147}
148
149/**
150 * @brief Set off RBtree.
151 *
152 * This function sets the next and previous fields of the @a node to NULL
153 * indicating the @a node is not part of any rbtree.
154 */
155static inline void rtems_rbtree_set_off_tree(
156  rtems_rbtree_node *node
157)
158{
159  _RBTree_Set_off_tree( node );
160}
161
162/**
163 * @brief Is the Node off RBTree.
164 *
165 * This function returns true if the @a node is not on a rbtree. A @a node is
166 * off rbtree if the next and previous fields are set to NULL.
167 */
168static inline bool rtems_rbtree_is_node_off_tree(
169  const rtems_rbtree_node *node
170)
171{
172  return _RBTree_Is_node_off_tree( node );
173}
174
175/**
176 * @brief Return pointer to RBTree root.
177 *
178 * This function returns a pointer to the root node of @a the_rbtree.
179 */
180static inline rtems_rbtree_node *rtems_rbtree_root(
181  const rtems_rbtree_control *the_rbtree
182)
183{
184  return _RBTree_Root( the_rbtree );
185}
186
187/**
188 * @copydoc _RBTree_Minimum()
189 */
190static inline rtems_rbtree_node *rtems_rbtree_min(
191  const rtems_rbtree_control *the_rbtree
192)
193{
194  return _RBTree_Minimum( the_rbtree );
195}
196
197/**
198 * @copydoc _RBTree_Maximum()
199 */
200static inline rtems_rbtree_node *rtems_rbtree_max(
201  const rtems_rbtree_control *the_rbtree
202)
203{
204  return _RBTree_Maximum( the_rbtree );
205}
206
207/**
208 * @brief Return pointer to the left child node from this node.
209 *
210 * This function returns a pointer to the left child node of @a the_node.
211 */
212static inline rtems_rbtree_node *rtems_rbtree_left(
213  const rtems_rbtree_node *the_node
214)
215{
216  return _RBTree_Left( the_node );
217}
218
219/**
220 * @brief Return pointer to the right child node from this node.
221 *
222 * This function returns a pointer to the right child node of @a the_node.
223 */
224static inline rtems_rbtree_node *rtems_rbtree_right(
225  const rtems_rbtree_node *the_node
226)
227{
228  return _RBTree_Right( the_node );
229}
230
231/**
232 * @copydoc _RBTree_Parent()
233 */
234static inline rtems_rbtree_node *rtems_rbtree_parent(
235  const rtems_rbtree_node *the_node
236)
237{
238  return _RBTree_Parent( the_node );
239}
240
241/**
242 * @brief Is the RBTree empty.
243 *
244 * This function returns true if there a no nodes on @a the_rbtree and
245 * false otherwise.
246 */
247static inline bool rtems_rbtree_is_empty(
248  const rtems_rbtree_control *the_rbtree
249)
250{
251  return _RBTree_Is_empty( the_rbtree );
252}
253
254/**
255 * @brief Is this the minimum node on the RBTree.
256 *
257 * This function returns true if @a the_node is the min node on @a the_rbtree
258 * and false otherwise.
259 */
260static inline bool rtems_rbtree_is_min(
261  const rtems_rbtree_control *the_rbtree,
262  const rtems_rbtree_node *the_node
263)
264{
265  return rtems_rbtree_min( the_rbtree ) == the_node;
266}
267
268/**
269 * @brief Is this the maximum node on the RBTree.
270 *
271 * This function returns true if @a the_node is the max node on @a the_rbtree
272 * and false otherwise.
273 */
274static inline bool rtems_rbtree_is_max(
275  const rtems_rbtree_control *the_rbtree,
276  const rtems_rbtree_node *the_node
277)
278{
279  return rtems_rbtree_max( the_rbtree ) == the_node;
280}
281
282/**
283 * @copydoc _RBTree_Is_root()
284 */
285static inline bool rtems_rbtree_is_root(
286  const rtems_rbtree_node *the_node
287)
288{
289  return _RBTree_Is_root( the_node );
290}
291
292static inline bool rtems_rbtree_is_equal(
293  rtems_rbtree_compare_result compare_result
294)
295{
296  return compare_result == 0;
297}
298
299static inline bool rtems_rbtree_is_greater(
300  rtems_rbtree_compare_result compare_result
301)
302{
303  return compare_result > 0;
304}
305
306static inline bool rtems_rbtree_is_lesser(
307  rtems_rbtree_compare_result compare_result
308)
309{
310  return compare_result < 0;
311}
312
313/**
314 * @brief Tries to find a node for the specified key in the tree.
315 *
316 * @param[in] the_rbtree The red-black tree control.
317 * @param[in] the_node A node specifying the key.
318 * @param[in] compare The node compare function.
319 * @param[in] is_unique If true, then return the first node with a key equal to
320 *   the one of the node specified if it exits, else return the last node if it
321 *   exists.
322 *
323 * @retval node A node corresponding to the key.  If the tree is not unique
324 * and contains duplicate keys, the set of duplicate keys acts as FIFO.
325 * @retval NULL No node exists in the tree for the key.
326 */
327rtems_rbtree_node* rtems_rbtree_find(
328  const rtems_rbtree_control *the_rbtree,
329  const rtems_rbtree_node    *the_node,
330  rtems_rbtree_compare              compare,
331  bool                        is_unique
332);
333
334/**
335 * @copydoc _RBTree_Predecessor()
336 */
337static inline rtems_rbtree_node* rtems_rbtree_predecessor(
338  const rtems_rbtree_node *node
339)
340{
341  return _RBTree_Predecessor( node );
342}
343
344/**
345 * @copydoc _RBTree_Successor()
346 */
347static inline rtems_rbtree_node* rtems_rbtree_successor(
348  const rtems_rbtree_node *node
349)
350{
351  return _RBTree_Successor( node );
352}
353
354/**
355 * @copydoc _RBTree_Extract()
356 */
357static inline void rtems_rbtree_extract(
358  rtems_rbtree_control *the_rbtree,
359  rtems_rbtree_node *the_node
360)
361{
362  _RBTree_Extract( the_rbtree, the_node );
363}
364
365/**
366 * @brief Gets a node with the minimum key value from the red-black tree.
367 *
368 * This function extracts a node with the minimum key value from
369 * tree and returns a pointer to that node if it exists.  In case multiple
370 * nodes with a minimum key value exist, then they are extracted in FIFO order.
371 *
372 * @param[in] the_rbtree The red-black tree control.
373 *
374 * @retval NULL The tree is empty.
375 * @retval node A node with the minimal key value on the tree.
376 */
377static inline rtems_rbtree_node *rtems_rbtree_get_min(
378  rtems_rbtree_control *the_rbtree
379)
380{
381  rtems_rbtree_node *the_node = rtems_rbtree_min( the_rbtree );
382
383  if ( the_node != NULL ) {
384    rtems_rbtree_extract( the_rbtree, the_node );
385  }
386
387  return the_node;
388}
389
390/**
391 * @brief Gets a node with the maximal key value from the red-black tree.
392 *
393 * This function extracts a node with the maximum key value from tree and
394 * returns a pointer to that node if it exists.  In case multiple nodes with a
395 * maximum key value exist, then they are extracted in LIFO order.
396 *
397 * @param[in] the_rbtree The red-black tree control.
398 *
399 * @retval NULL The tree is empty.
400 * @retval node A node with the maximal key value on the tree.
401 */
402static inline rtems_rbtree_node *rtems_rbtree_get_max(
403  rtems_rbtree_control *the_rbtree
404)
405{
406  rtems_rbtree_node *the_node = rtems_rbtree_max( the_rbtree );
407
408  if ( the_node != NULL ) {
409    rtems_rbtree_extract( the_rbtree, the_node );
410  }
411
412  return the_node;
413}
414
415/**
416 * @brief Peek at the min node on a rbtree.
417 *
418 * This function returns a pointer to the min node from @a the_rbtree
419 * without changing the tree.  If @a the_rbtree is empty,
420 * then NULL is returned.
421 */
422static inline rtems_rbtree_node *rtems_rbtree_peek_min(
423  const rtems_rbtree_control *the_rbtree
424)
425{
426  return rtems_rbtree_min( the_rbtree );
427}
428
429/**
430 * @brief Peek at the max node on a rbtree.
431 *
432 * This function returns a pointer to the max node from @a the_rbtree
433 * without changing the tree.  If @a the_rbtree is empty,
434 * then NULL is returned.
435 */
436static inline rtems_rbtree_node *rtems_rbtree_peek_max(
437  const rtems_rbtree_control *the_rbtree
438)
439{
440  return rtems_rbtree_max( the_rbtree );
441}
442
443/**
444 * @brief Inserts the node into the red-black tree.
445 *
446 * In case the node is already a node of a tree, then this function yields
447 * unpredictable results.
448 *
449 * @param[in] the_rbtree The red-black tree control.
450 * @param[in] the_node The node to insert.
451 * @param[in] compare The node compare function.
452 * @param[in] is_unique If true, then reject nodes with a duplicate key, else
453 *   insert nodes in FIFO order in case the key value is equal to existing nodes.
454 *
455 * @retval NULL Successfully inserted.
456 * @retval existing_node This is a unique insert and there exists a node with
457 *   an equal key in the tree already.
458 */
459rtems_rbtree_node *rtems_rbtree_insert(
460  RBTree_Control *the_rbtree,
461  RBTree_Node    *the_node,
462  rtems_rbtree_compare  compare,
463  bool            is_unique
464);
465
466/** @} */
467
468#ifdef __cplusplus
469}
470#endif
471
472#endif
473/* end of include file */
Note: See TracBrowser for help on using the repository browser.