[bd9baa81] | 1 | /** |
---|
| 2 | * @file rtems/score/rbtree.h |
---|
| 3 | * |
---|
[319cb20] | 4 | * @brief Constants and Structures Associated with the Red-Black Tree Handler |
---|
| 5 | * |
---|
[bd9baa81] | 6 | * This include file contains all the constants and structures associated |
---|
| 7 | * with the Red-Black Tree Handler. |
---|
| 8 | */ |
---|
| 9 | |
---|
| 10 | /* |
---|
| 11 | * Copyright (c) 2010 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 |
---|
[c499856] | 15 | * http://www.rtems.org/license/LICENSE. |
---|
[bd9baa81] | 16 | */ |
---|
| 17 | |
---|
| 18 | #ifndef _RTEMS_SCORE_RBTREE_H |
---|
| 19 | #define _RTEMS_SCORE_RBTREE_H |
---|
| 20 | |
---|
[050adc2] | 21 | #include <stddef.h> |
---|
| 22 | |
---|
[93fb3cb0] | 23 | #include <rtems/score/address.h> |
---|
| 24 | |
---|
| 25 | #ifdef __cplusplus |
---|
| 26 | extern "C" { |
---|
| 27 | #endif |
---|
| 28 | |
---|
[bd9baa81] | 29 | /** |
---|
| 30 | * @defgroup ScoreRBTree Red-Black Tree Handler |
---|
| 31 | * |
---|
[d8cd045c] | 32 | * @ingroup Score |
---|
| 33 | * |
---|
[bd9baa81] | 34 | * The Red-Black Tree Handler is used to manage sets of entities. This handler |
---|
| 35 | * provides two data structures. The rbtree Node data structure is included |
---|
| 36 | * as the first part of every data structure that will be placed on |
---|
| 37 | * a RBTree. The second data structure is rbtree Control which is used |
---|
| 38 | * to manage a set of rbtree Nodes. |
---|
| 39 | */ |
---|
| 40 | /**@{*/ |
---|
| 41 | |
---|
[4b72da4] | 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 | */ |
---|
| 50 | typedef struct RBTree_Node_struct RBTree_Node; |
---|
[bd9baa81] | 51 | |
---|
[4b72da4] | 52 | /** |
---|
| 53 | * This enum type defines the colors available for the RBTree Nodes |
---|
| 54 | */ |
---|
| 55 | typedef enum { |
---|
| 56 | RBT_BLACK, |
---|
| 57 | RBT_RED |
---|
| 58 | } RBTree_Color; |
---|
[bd9baa81] | 59 | |
---|
[4b72da4] | 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 | */ |
---|
| 75 | struct 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 | }; |
---|
[dacdda30] | 83 | |
---|
[4b72da4] | 84 | /** |
---|
| 85 | * This type indicates the direction. |
---|
| 86 | */ |
---|
| 87 | typedef enum { |
---|
| 88 | RBT_LEFT=0, |
---|
| 89 | RBT_RIGHT=1 |
---|
| 90 | } RBTree_Direction; |
---|
[bd9baa81] | 91 | |
---|
[60fe374] | 92 | /** |
---|
| 93 | * @brief Integer type for compare results. |
---|
| 94 | * |
---|
| 95 | * The type is large enough to represent pointers and 32-bit signed integers. |
---|
| 96 | * |
---|
| 97 | * @see RBTree_Compare. |
---|
| 98 | */ |
---|
| 99 | typedef long RBTree_Compare_result; |
---|
| 100 | |
---|
[74f1c73e] | 101 | /** |
---|
[64939bc] | 102 | * @brief Compares two red-black tree nodes. |
---|
| 103 | * |
---|
| 104 | * @param[in] first The first node. |
---|
| 105 | * @param[in] second The second node. |
---|
| 106 | * |
---|
| 107 | * @retval positive The key value of the first node is greater than the one of |
---|
| 108 | * the second node. |
---|
| 109 | * @retval 0 The key value of the first node is equal to the one of the second |
---|
| 110 | * node. |
---|
| 111 | * @retval negative The key value of the first node is less than the one of the |
---|
| 112 | * second node. |
---|
[74f1c73e] | 113 | */ |
---|
[60fe374] | 114 | typedef RBTree_Compare_result ( *RBTree_Compare )( |
---|
[64939bc] | 115 | const RBTree_Node *first, |
---|
| 116 | const RBTree_Node *second |
---|
[74f1c73e] | 117 | ); |
---|
| 118 | |
---|
[4b72da4] | 119 | /** |
---|
| 120 | * @struct RBTree_Control |
---|
| 121 | * |
---|
| 122 | * This is used to manage a RBT. A rbtree consists of a tree of zero or more |
---|
| 123 | * nodes. |
---|
| 124 | * |
---|
| 125 | * @note This implementation does not require special checks for |
---|
| 126 | * manipulating the root element of the RBT. |
---|
| 127 | * To accomplish this the @a RBTree_Control structure can be overlaid |
---|
| 128 | * with a @ref RBTree_Node structure to act as a "dummy root", |
---|
| 129 | * which has a NULL parent and its left child is the root. |
---|
| 130 | */ |
---|
[bd9baa81] | 131 | |
---|
[4b72da4] | 132 | /* the RBTree_Control is actually part of the RBTree structure as an |
---|
| 133 | * RBTree_Node. The mapping of fields from RBTree_Control to RBTree_Node are: |
---|
| 134 | * permanent_null == parent |
---|
| 135 | * root == left |
---|
| 136 | * first[0] == right |
---|
| 137 | */ |
---|
| 138 | typedef struct { |
---|
| 139 | /** This points to a NULL. Useful for finding the root. */ |
---|
| 140 | RBTree_Node *permanent_null; |
---|
| 141 | /** This points to the root node of the RBT. */ |
---|
| 142 | RBTree_Node *root; |
---|
| 143 | /** This points to the min and max nodes of this RBT. */ |
---|
| 144 | RBTree_Node *first[2]; |
---|
| 145 | } RBTree_Control; |
---|
[bd9baa81] | 146 | |
---|
[4b72da4] | 147 | /** |
---|
| 148 | * @brief RBTree initializer for an empty rbtree with designator @a name. |
---|
| 149 | */ |
---|
[64939bc] | 150 | #define RBTREE_INITIALIZER_EMPTY( name ) \ |
---|
| 151 | { NULL, NULL, { NULL, NULL } } |
---|
[bd9baa81] | 152 | |
---|
[4b72da4] | 153 | /** |
---|
| 154 | * @brief RBTree definition for an empty rbtree with designator @a name. |
---|
| 155 | */ |
---|
[64939bc] | 156 | #define RBTREE_DEFINE_EMPTY( name ) \ |
---|
| 157 | RBTree_Control name = RBTREE_INITIALIZER_EMPTY( name ) |
---|
[bd9baa81] | 158 | |
---|
[4b72da4] | 159 | /** |
---|
| 160 | * @brief RBTree_Node initializer for an empty node with designator @a name. |
---|
| 161 | */ |
---|
[64939bc] | 162 | #define RBTREE_NODE_INITIALIZER_EMPTY( name ) \ |
---|
| 163 | { NULL, { NULL, NULL }, RBT_RED } |
---|
[bd9baa81] | 164 | |
---|
[4b72da4] | 165 | /** |
---|
| 166 | * @brief RBTree definition for an empty rbtree with designator @a name. |
---|
| 167 | */ |
---|
[64939bc] | 168 | #define RBTREE_NODE_DEFINE_EMPTY( name ) \ |
---|
| 169 | RBTree_Node name = RBTREE_NODE_INITIALIZER_EMPTY( name ) |
---|
[bd9baa81] | 170 | |
---|
[4b72da4] | 171 | /** |
---|
[319cb20] | 172 | * @brief Initialize a RBTree Header. |
---|
[4b72da4] | 173 | * |
---|
| 174 | * This routine initializes @a the_rbtree structure to manage the |
---|
| 175 | * contiguous array of @a number_nodes nodes which starts at |
---|
| 176 | * @a starting_address. Each node is of @a node_size bytes. |
---|
[319cb20] | 177 | * |
---|
[f2f63d1] | 178 | * @param[in] the_rbtree is the pointer to rbtree header |
---|
[64939bc] | 179 | * @param[in] compare The node compare function. |
---|
[f2f63d1] | 180 | * @param[in] starting_address is the starting address of first node |
---|
| 181 | * @param[in] number_nodes is the number of nodes in rbtree |
---|
| 182 | * @param[in] node_size is the size of node in bytes |
---|
[64939bc] | 183 | * @param[in] is_unique If true, then reject nodes with a duplicate key, else |
---|
| 184 | * otherwise. |
---|
[4b72da4] | 185 | */ |
---|
| 186 | void _RBTree_Initialize( |
---|
[64939bc] | 187 | RBTree_Control *the_rbtree, |
---|
| 188 | RBTree_Compare compare, |
---|
| 189 | void *starting_address, |
---|
| 190 | size_t number_nodes, |
---|
| 191 | size_t node_size, |
---|
| 192 | bool is_unique |
---|
[4b72da4] | 193 | ); |
---|
[bd9baa81] | 194 | |
---|
[4b72da4] | 195 | /** |
---|
[833dd90] | 196 | * @brief Tries to find a node for the specified key in the tree. |
---|
[4b72da4] | 197 | * |
---|
[833dd90] | 198 | * @param[in] the_rbtree The red-black tree control. |
---|
| 199 | * @param[in] the_node A node specifying the key. |
---|
[64939bc] | 200 | * @param[in] compare The node compare function. |
---|
| 201 | * @param[in] is_unique If true, then return the first node with a key equal to |
---|
| 202 | * the one of the node specified if it exits, else return the last node if it |
---|
| 203 | * exists. |
---|
[4b72da4] | 204 | * |
---|
[833dd90] | 205 | * @retval node A node corresponding to the key. If the tree is not unique |
---|
| 206 | * and contains duplicate keys, the set of duplicate keys acts as FIFO. |
---|
| 207 | * @retval NULL No node exists in the tree for the key. |
---|
[53afcfd2] | 208 | */ |
---|
[4ea97d24] | 209 | RBTree_Node *_RBTree_Find( |
---|
[0ca61727] | 210 | const RBTree_Control *the_rbtree, |
---|
[64939bc] | 211 | const RBTree_Node *the_node, |
---|
| 212 | RBTree_Compare compare, |
---|
| 213 | bool is_unique |
---|
[53afcfd2] | 214 | ); |
---|
| 215 | |
---|
[4b72da4] | 216 | /** |
---|
[639117f] | 217 | * @brief Inserts the node into the red-black tree. |
---|
[4b72da4] | 218 | * |
---|
[639117f] | 219 | * In case the node is already a node of a tree, then this function yields |
---|
| 220 | * unpredictable results. |
---|
[4b72da4] | 221 | * |
---|
[64939bc] | 222 | * @param[in] the_rbtree The red-black tree control. |
---|
| 223 | * @param[in] the_node The node to insert. |
---|
| 224 | * @param[in] compare The node compare function. |
---|
| 225 | * @param[in] is_unique If true, then reject nodes with a duplicate key, else |
---|
[639117f] | 226 | * insert nodes in FIFO order in case the key value is equal to existing nodes. |
---|
[64939bc] | 227 | * |
---|
[d7a94693] | 228 | * @retval NULL Successfully inserted. |
---|
| 229 | * @retval existing_node This is a unique insert and there exists a node with |
---|
| 230 | * an equal key in the tree already. |
---|
[4b72da4] | 231 | */ |
---|
[4ea97d24] | 232 | RBTree_Node *_RBTree_Insert( |
---|
[4b72da4] | 233 | RBTree_Control *the_rbtree, |
---|
[64939bc] | 234 | RBTree_Node *the_node, |
---|
| 235 | RBTree_Compare compare, |
---|
| 236 | bool is_unique |
---|
[4b72da4] | 237 | ); |
---|
[bd9baa81] | 238 | |
---|
[4b72da4] | 239 | /** |
---|
[8abbbdde] | 240 | * @brief Extracts (removes) the node from the red-black tree. |
---|
[4b72da4] | 241 | * |
---|
[8abbbdde] | 242 | * This function does not set the node off-tree. In case this is desired, then |
---|
[6e93c836] | 243 | * call _RBTree_Set_off_tree() after the extraction. |
---|
[8abbbdde] | 244 | * |
---|
| 245 | * In case the node to extract is not a node of the tree, then this function |
---|
| 246 | * yields unpredictable results. |
---|
| 247 | * |
---|
| 248 | * @param[in] the_rbtree The red-black tree control. |
---|
| 249 | * @param[in] the_node The node to extract. |
---|
[4b72da4] | 250 | */ |
---|
[4ea97d24] | 251 | void _RBTree_Extract( |
---|
[4b72da4] | 252 | RBTree_Control *the_rbtree, |
---|
| 253 | RBTree_Node *the_node |
---|
| 254 | ); |
---|
[bd9baa81] | 255 | |
---|
[dc62a48c] | 256 | /** |
---|
| 257 | * @brief Returns the in-order next node of a node. |
---|
| 258 | * |
---|
| 259 | * @param[in] node The node. |
---|
| 260 | * @param[in] dir The direction. |
---|
| 261 | * |
---|
| 262 | * @retval NULL The in-order next node does not exist. |
---|
| 263 | * @retval otherwise The next node. |
---|
| 264 | */ |
---|
[4ea97d24] | 265 | RBTree_Node *_RBTree_Next( |
---|
[dc62a48c] | 266 | const RBTree_Node *node, |
---|
| 267 | RBTree_Direction dir |
---|
| 268 | ); |
---|
| 269 | |
---|
[112396de] | 270 | /** |
---|
[6e93c836] | 271 | * @brief Sets a red-black tree node as off-tree. |
---|
[112396de] | 272 | * |
---|
[6e93c836] | 273 | * Do not use this function on nodes which are a part of a tree. |
---|
[112396de] | 274 | * |
---|
[6e93c836] | 275 | * @param[in] the_node The node to set off-tree. |
---|
| 276 | * |
---|
| 277 | * @see _RBTree_Is_node_off_tree(). |
---|
[93fb3cb0] | 278 | */ |
---|
[6e93c836] | 279 | RTEMS_INLINE_ROUTINE void _RBTree_Set_off_tree( RBTree_Node *the_node ) |
---|
[93fb3cb0] | 280 | { |
---|
[6e93c836] | 281 | the_node->parent = NULL; |
---|
[93fb3cb0] | 282 | } |
---|
| 283 | |
---|
| 284 | /** |
---|
[6e93c836] | 285 | * @brief Returns true, if this red-black tree node is off-tree, and false |
---|
| 286 | * otherwise. |
---|
| 287 | * |
---|
| 288 | * @param[in] the_node The node to test. |
---|
[112396de] | 289 | * |
---|
[6e93c836] | 290 | * @retval true The node is not a part of a tree (off-tree). |
---|
| 291 | * @retval false Otherwise. |
---|
| 292 | * |
---|
| 293 | * @see _RBTree_Set_off_tree(). |
---|
[112396de] | 294 | */ |
---|
[6e93c836] | 295 | RTEMS_INLINE_ROUTINE bool _RBTree_Is_node_off_tree( |
---|
| 296 | const RBTree_Node *the_node |
---|
| 297 | ) |
---|
[93fb3cb0] | 298 | { |
---|
[6e93c836] | 299 | return the_node->parent == NULL; |
---|
[93fb3cb0] | 300 | } |
---|
[112396de] | 301 | |
---|
[93fb3cb0] | 302 | /** |
---|
[993f5ac] | 303 | * @brief Returns a pointer to root node of the red-black tree. |
---|
[93fb3cb0] | 304 | * |
---|
[993f5ac] | 305 | * The root node may change after insert or extract operations. |
---|
| 306 | * |
---|
| 307 | * @param[in] the_rbtree The red-black tree control. |
---|
| 308 | * |
---|
| 309 | * @retval NULL The tree is empty. |
---|
| 310 | * @retval root The root node. |
---|
| 311 | * |
---|
| 312 | * @see _RBTree_Is_root(). |
---|
[93fb3cb0] | 313 | */ |
---|
| 314 | RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Root( |
---|
| 315 | const RBTree_Control *the_rbtree |
---|
| 316 | ) |
---|
| 317 | { |
---|
| 318 | return the_rbtree->root; |
---|
| 319 | } |
---|
| 320 | |
---|
| 321 | /** |
---|
| 322 | * @brief Return pointer to RBTree's first node. |
---|
| 323 | * |
---|
| 324 | * This function returns a pointer to the first node on @a the_rbtree, |
---|
| 325 | * where @a dir specifies whether to return the minimum (0) or maximum (1). |
---|
| 326 | */ |
---|
| 327 | RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_First( |
---|
| 328 | const RBTree_Control *the_rbtree, |
---|
| 329 | RBTree_Direction dir |
---|
| 330 | ) |
---|
| 331 | { |
---|
| 332 | return the_rbtree->first[dir]; |
---|
| 333 | } |
---|
| 334 | |
---|
| 335 | /** |
---|
[993f5ac] | 336 | * @brief Returns a pointer to the parent of this node. |
---|
[93fb3cb0] | 337 | * |
---|
[993f5ac] | 338 | * The node must have a parent, thus it is invalid to use this function for the |
---|
| 339 | * root node or a node that is not part of a tree. To test for the root node |
---|
| 340 | * compare with _RBTree_Root() or use _RBTree_Is_root(). |
---|
| 341 | * |
---|
| 342 | * @param[in] the_node The node of interest. |
---|
| 343 | * |
---|
| 344 | * @retval parent The parent of this node. |
---|
| 345 | * @retval undefined The node is the root node or not part of a tree. |
---|
[93fb3cb0] | 346 | */ |
---|
| 347 | RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Parent( |
---|
| 348 | const RBTree_Node *the_node |
---|
| 349 | ) |
---|
| 350 | { |
---|
| 351 | return the_node->parent; |
---|
| 352 | } |
---|
| 353 | |
---|
| 354 | /** |
---|
| 355 | * @brief Return pointer to the left of this node. |
---|
| 356 | * |
---|
| 357 | * This function returns a pointer to the left node of this node. |
---|
| 358 | * |
---|
| 359 | * @param[in] the_node is the node to be operated upon. |
---|
| 360 | * |
---|
| 361 | * @return This method returns the left node on the rbtree. |
---|
| 362 | */ |
---|
| 363 | RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Left( |
---|
| 364 | const RBTree_Node *the_node |
---|
| 365 | ) |
---|
| 366 | { |
---|
| 367 | return the_node->child[RBT_LEFT]; |
---|
| 368 | } |
---|
| 369 | |
---|
| 370 | /** |
---|
| 371 | * @brief Return pointer to the right of this node. |
---|
| 372 | * |
---|
| 373 | * This function returns a pointer to the right node of this node. |
---|
| 374 | * |
---|
| 375 | * @param[in] the_node is the node to be operated upon. |
---|
| 376 | * |
---|
| 377 | * @return This method returns the right node on the rbtree. |
---|
| 378 | */ |
---|
| 379 | RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Right( |
---|
| 380 | const RBTree_Node *the_node |
---|
| 381 | ) |
---|
| 382 | { |
---|
| 383 | return the_node->child[RBT_RIGHT]; |
---|
| 384 | } |
---|
| 385 | |
---|
| 386 | /** |
---|
| 387 | * @brief Is the RBTree empty. |
---|
| 388 | * |
---|
| 389 | * This function returns true if there are no nodes on @a the_rbtree and |
---|
| 390 | * false otherwise. |
---|
| 391 | * |
---|
| 392 | * @param[in] the_rbtree is the rbtree to be operated upon. |
---|
| 393 | * |
---|
| 394 | * @retval true There are no nodes on @a the_rbtree. |
---|
| 395 | * @retval false There are nodes on @a the_rbtree. |
---|
| 396 | */ |
---|
| 397 | RTEMS_INLINE_ROUTINE bool _RBTree_Is_empty( |
---|
| 398 | const RBTree_Control *the_rbtree |
---|
| 399 | ) |
---|
| 400 | { |
---|
| 401 | return (the_rbtree->root == NULL); |
---|
| 402 | } |
---|
| 403 | |
---|
| 404 | /** |
---|
| 405 | * @brief Is this the first node on the RBTree. |
---|
| 406 | * |
---|
| 407 | * This function returns true if @a the_node is the first node on |
---|
| 408 | * @a the_rbtree and false otherwise. @a dir specifies whether first means |
---|
| 409 | * minimum (0) or maximum (1). |
---|
| 410 | * |
---|
| 411 | * @retval true @a the_node is the first node on @a the_rbtree. |
---|
| 412 | * @retval false @a the_node is not the first node on @a the_rbtree. |
---|
| 413 | * |
---|
| 414 | */ |
---|
| 415 | RTEMS_INLINE_ROUTINE bool _RBTree_Is_first( |
---|
| 416 | const RBTree_Control *the_rbtree, |
---|
| 417 | const RBTree_Node *the_node, |
---|
| 418 | RBTree_Direction dir |
---|
| 419 | ) |
---|
| 420 | { |
---|
| 421 | return (the_node == _RBTree_First(the_rbtree, dir)); |
---|
| 422 | } |
---|
| 423 | |
---|
| 424 | /** |
---|
[993f5ac] | 425 | * @brief Returns true if this node is the root node of a red-black tree, and |
---|
[93fb3cb0] | 426 | * false otherwise. |
---|
| 427 | * |
---|
[993f5ac] | 428 | * The root node may change after insert or extract operations. In case the |
---|
| 429 | * node is not a node of a tree, then this function yields unpredictable |
---|
| 430 | * results. |
---|
| 431 | * |
---|
| 432 | * @param[in] the_node The node of interest. |
---|
| 433 | * |
---|
| 434 | * @retval true The node is the root node. |
---|
| 435 | * @retval false Otherwise. |
---|
| 436 | * |
---|
| 437 | * @see _RBTree_Root(). |
---|
[93fb3cb0] | 438 | */ |
---|
| 439 | RTEMS_INLINE_ROUTINE bool _RBTree_Is_root( |
---|
[993f5ac] | 440 | const RBTree_Node *the_node |
---|
[93fb3cb0] | 441 | ) |
---|
| 442 | { |
---|
[993f5ac] | 443 | return _RBTree_Parent( _RBTree_Parent( the_node ) ) == NULL; |
---|
[93fb3cb0] | 444 | } |
---|
| 445 | |
---|
| 446 | /** |
---|
[b767683a] | 447 | * @brief Finds the red-black tree control given a node in the tree. |
---|
[93fb3cb0] | 448 | * |
---|
[b767683a] | 449 | * In case the node is not a node of a tree, then this function yields |
---|
| 450 | * unpredictable results. |
---|
| 451 | * |
---|
| 452 | * @param[in] the_node The node of interest. |
---|
| 453 | * |
---|
| 454 | * @return The red-black tree control of the node. |
---|
[93fb3cb0] | 455 | */ |
---|
[b767683a] | 456 | RTEMS_INLINE_ROUTINE RBTree_Control *_RBTree_Find_control( |
---|
| 457 | const RBTree_Node *the_node |
---|
| 458 | ) |
---|
[93fb3cb0] | 459 | { |
---|
[b767683a] | 460 | RBTree_Node *parent = the_node->parent; |
---|
| 461 | RBTree_Control *rbtree; |
---|
| 462 | |
---|
| 463 | do { |
---|
| 464 | rbtree = (RBTree_Control *) parent; |
---|
| 465 | parent = parent->parent; |
---|
| 466 | } while ( parent != NULL ); |
---|
| 467 | |
---|
| 468 | return rbtree; |
---|
[93fb3cb0] | 469 | } |
---|
| 470 | |
---|
| 471 | /** |
---|
| 472 | * @brief Initialize this RBTree as empty. |
---|
| 473 | * |
---|
| 474 | * This routine initializes @a the_rbtree to contain zero nodes. |
---|
| 475 | */ |
---|
| 476 | RTEMS_INLINE_ROUTINE void _RBTree_Initialize_empty( |
---|
[64939bc] | 477 | RBTree_Control *the_rbtree |
---|
| 478 | ) |
---|
[93fb3cb0] | 479 | { |
---|
| 480 | the_rbtree->permanent_null = NULL; |
---|
| 481 | the_rbtree->root = NULL; |
---|
[64939bc] | 482 | the_rbtree->first[RBT_LEFT] = NULL; |
---|
| 483 | the_rbtree->first[RBT_RIGHT] = NULL; |
---|
[93fb3cb0] | 484 | } |
---|
| 485 | |
---|
| 486 | /** |
---|
| 487 | * @brief Returns the predecessor of a node. |
---|
| 488 | * |
---|
| 489 | * @param[in] node is the node. |
---|
| 490 | * |
---|
| 491 | * @retval NULL The predecessor does not exist. Otherwise it returns |
---|
| 492 | * the predecessor node. |
---|
| 493 | */ |
---|
[4ea97d24] | 494 | RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Predecessor( |
---|
[93fb3cb0] | 495 | const RBTree_Node *node |
---|
| 496 | ) |
---|
| 497 | { |
---|
[4ea97d24] | 498 | return _RBTree_Next( node, RBT_LEFT ); |
---|
[93fb3cb0] | 499 | } |
---|
| 500 | |
---|
| 501 | /** |
---|
| 502 | * @brief Returns the successor of a node. |
---|
| 503 | * |
---|
| 504 | * @param[in] node is the node. |
---|
| 505 | * |
---|
| 506 | * @retval NULL The successor does not exist. Otherwise the successor node. |
---|
| 507 | */ |
---|
[4ea97d24] | 508 | RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Successor( |
---|
[93fb3cb0] | 509 | const RBTree_Node *node |
---|
| 510 | ) |
---|
| 511 | { |
---|
[4ea97d24] | 512 | return _RBTree_Next( node, RBT_RIGHT ); |
---|
[93fb3cb0] | 513 | } |
---|
| 514 | |
---|
| 515 | /** |
---|
[639117f] | 516 | * @brief Gets a node with an extremal key value from the red-black tree. |
---|
[93fb3cb0] | 517 | * |
---|
[d7a94693] | 518 | * This function extracts a node with the minimum or maximum key value from |
---|
| 519 | * tree and returns a pointer to that node if it exists. In case multiple |
---|
[639117f] | 520 | * nodes with a minimum key value exist, then they are extracted in FIFO order. |
---|
| 521 | * In case multiple nodes with a maximum key value exist, then they are |
---|
| 522 | * extracted in LIFO order. |
---|
[93fb3cb0] | 523 | * |
---|
[d7a94693] | 524 | * @param[in] the_rbtree The red-black tree control. |
---|
| 525 | * @param[in] dir Specifies whether to get a node with the minimum (RBT_LEFT) |
---|
| 526 | * or maximum (RBT_RIGHT) key value. |
---|
[93fb3cb0] | 527 | * |
---|
[d7a94693] | 528 | * @retval NULL The tree is empty. |
---|
[639117f] | 529 | * @retval extremal_node A node with a minimal or maximal key value on the |
---|
[d7a94693] | 530 | * tree. |
---|
[93fb3cb0] | 531 | */ |
---|
[4ea97d24] | 532 | RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Get( |
---|
[d7a94693] | 533 | RBTree_Control *the_rbtree, |
---|
| 534 | RBTree_Direction dir |
---|
| 535 | ) |
---|
[93fb3cb0] | 536 | { |
---|
[d7a94693] | 537 | RBTree_Node *the_node = the_rbtree->first[ dir ]; |
---|
| 538 | |
---|
| 539 | if ( the_node != NULL ) { |
---|
| 540 | _RBTree_Extract( the_rbtree, the_node ); |
---|
| 541 | } |
---|
| 542 | |
---|
[93fb3cb0] | 543 | return the_node; |
---|
| 544 | } |
---|
| 545 | |
---|
[bd9baa81] | 546 | /**@}*/ |
---|
| 547 | |
---|
[93fb3cb0] | 548 | #ifdef __cplusplus |
---|
| 549 | } |
---|
| 550 | #endif |
---|
| 551 | |
---|
[bd9baa81] | 552 | #endif |
---|
[53afcfd2] | 553 | /* end of include file */ |
---|