Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:13

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  * 
0006  * @ingroup RTEMSAPIClassicRBTrees
0007  *
0008  * @brief This header file provides the Red-Black Trees API.
0009  */
0010 
0011 /*
0012  *  Copyright (c) 2010 Gedare Bloom.
0013  *
0014  * Redistribution and use in source and binary forms, with or without
0015  * modification, are permitted provided that the following conditions
0016  * are met:
0017  * 1. Redistributions of source code must retain the above copyright
0018  *    notice, this list of conditions and the following disclaimer.
0019  * 2. Redistributions in binary form must reproduce the above copyright
0020  *    notice, this list of conditions and the following disclaimer in the
0021  *    documentation and/or other materials provided with the distribution.
0022  *
0023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0024  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0026  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0027  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0028  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0029  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0033  * POSSIBILITY OF SUCH DAMAGE.
0034  */
0035 
0036 #ifndef _RTEMS_RBTREE_H
0037 #define _RTEMS_RBTREE_H
0038 
0039 #include <rtems/score/rbtree.h>
0040 
0041 #ifdef __cplusplus
0042 extern "C" {
0043 #endif
0044 
0045 /**
0046  * @defgroup RTEMSAPIRBTrees Red-Black Trees
0047  *
0048  * @ingroup RTEMSAPIClassic
0049  *
0050  * @brief The red-black tree container provides data structures and directives
0051  *   to manage user-defined data structures in red-black trees.
0052  *
0053  * The red-black tree container offers no internal protection against
0054  * concurrent access.  The user must ensure that at most one thread at once can
0055  * access a red-black tree instance.
0056  *
0057  * @{
0058  */
0059 
0060 /**
0061  * @typedef rtems_rbtree_node
0062  *
0063  * A node that can be manipulated in the rbtree.
0064  */
0065 typedef RBTree_Node rtems_rbtree_node;
0066 
0067 /**
0068  * @typedef rtems_rbtree_control
0069  *
0070  * The rbtree's control anchors the rbtree.
0071  */
0072 typedef RBTree_Control rtems_rbtree_control;
0073 
0074 /**
0075  * @brief Integer type for compare results.
0076  *
0077  * The type is large enough to represent pointers and 32-bit signed integers.
0078  *
0079  * @see rtems_rbtree_compare.
0080  */
0081 typedef long rtems_rbtree_compare_result;
0082 
0083 /**
0084  * @brief Compares two red-black tree nodes.
0085  *
0086  * @param[in] first The first node.
0087  * @param[in] second The second node.
0088  *
0089  * @retval positive The key value of the first node is greater than the one of
0090  *   the second node.
0091  * @retval 0 The key value of the first node is equal to the one of the second
0092  *   node.
0093  * @retval negative The key value of the first node is less than the one of the
0094  *   second node.
0095  */
0096 typedef rtems_rbtree_compare_result ( *rtems_rbtree_compare )(
0097   const RBTree_Node *first,
0098   const RBTree_Node *second
0099 );
0100 
0101 /**
0102  * @brief RBTree initializer for an empty rbtree with designator @a name.
0103  */
0104 #define RTEMS_RBTREE_INITIALIZER_EMPTY(name) \
0105   RBTREE_INITIALIZER_EMPTY(name)
0106 
0107 /**
0108  * @brief RBTree definition for an empty rbtree with designator @a name.
0109  */
0110 #define RTEMS_RBTREE_DEFINE_EMPTY(name) \
0111   RBTREE_DEFINE_EMPTY(name)
0112 
0113 /**
0114  * @brief Initialize a RBTree header.
0115  *
0116  * This routine initializes @a the_rbtree structure to manage the
0117  * contiguous array of @a number_nodes nodes which starts at
0118  * @a starting_address.  Each node is of @a node_size bytes.
0119  *
0120  * @param[in] the_rbtree is the pointer to rbtree header
0121  * @param[in] compare The node compare function.
0122  * @param[in] starting_address is the starting address of first node
0123  * @param[in] number_nodes is the number of nodes in rbtree
0124  * @param[in] node_size is the size of node in bytes
0125  * @param[in] is_unique If true, then reject nodes with a duplicate key, else
0126  *   otherwise.
0127  */
0128 void rtems_rbtree_initialize(
0129   rtems_rbtree_control *the_rbtree,
0130   rtems_rbtree_compare  compare,
0131   void                 *starting_address,
0132   size_t                number_nodes,
0133   size_t                node_size,
0134   bool                  is_unique
0135 );
0136 
0137 /**
0138  * @brief Initialize this RBTree as Empty
0139  *
0140  * This routine initializes @a the_rbtree to contain zero nodes.
0141  */
0142 static inline void rtems_rbtree_initialize_empty(
0143   rtems_rbtree_control *the_rbtree
0144 )
0145 {
0146   _RBTree_Initialize_empty( the_rbtree );
0147 }
0148 
0149 /**
0150  * @brief Set off RBtree.
0151  *
0152  * This function sets the next and previous fields of the @a node to NULL
0153  * indicating the @a node is not part of any rbtree.
0154  */
0155 static inline void rtems_rbtree_set_off_tree(
0156   rtems_rbtree_node *node
0157 )
0158 {
0159   _RBTree_Set_off_tree( node );
0160 }
0161 
0162 /**
0163  * @brief Is the Node off RBTree.
0164  *
0165  * This function returns true if the @a node is not on a rbtree. A @a node is
0166  * off rbtree if the next and previous fields are set to NULL.
0167  */
0168 static inline bool rtems_rbtree_is_node_off_tree(
0169   const rtems_rbtree_node *node
0170 )
0171 {
0172   return _RBTree_Is_node_off_tree( node );
0173 }
0174 
0175 /**
0176  * @brief Return pointer to RBTree root.
0177  *
0178  * This function returns a pointer to the root node of @a the_rbtree.
0179  */
0180 static inline rtems_rbtree_node *rtems_rbtree_root(
0181   const rtems_rbtree_control *the_rbtree
0182 )
0183 {
0184   return _RBTree_Root( the_rbtree );
0185 }
0186 
0187 /**
0188  * @copydoc _RBTree_Minimum()
0189  */
0190 static inline rtems_rbtree_node *rtems_rbtree_min(
0191   const rtems_rbtree_control *the_rbtree
0192 )
0193 {
0194   return _RBTree_Minimum( the_rbtree );
0195 }
0196 
0197 /**
0198  * @copydoc _RBTree_Maximum()
0199  */
0200 static inline rtems_rbtree_node *rtems_rbtree_max(
0201   const rtems_rbtree_control *the_rbtree
0202 )
0203 {
0204   return _RBTree_Maximum( the_rbtree );
0205 }
0206 
0207 /**
0208  * @brief Return pointer to the left child node from this node.
0209  *
0210  * This function returns a pointer to the left child node of @a the_node.
0211  */
0212 static inline rtems_rbtree_node *rtems_rbtree_left(
0213   const rtems_rbtree_node *the_node
0214 )
0215 {
0216   return _RBTree_Left( the_node );
0217 }
0218 
0219 /**
0220  * @brief Return pointer to the right child node from this node.
0221  *
0222  * This function returns a pointer to the right child node of @a the_node.
0223  */
0224 static inline rtems_rbtree_node *rtems_rbtree_right(
0225   const rtems_rbtree_node *the_node
0226 )
0227 {
0228   return _RBTree_Right( the_node );
0229 }
0230 
0231 /**
0232  * @copydoc _RBTree_Parent()
0233  */
0234 static inline rtems_rbtree_node *rtems_rbtree_parent(
0235   const rtems_rbtree_node *the_node
0236 )
0237 {
0238   return _RBTree_Parent( the_node );
0239 }
0240 
0241 /**
0242  * @brief Is the RBTree empty.
0243  *
0244  * This function returns true if there a no nodes on @a the_rbtree and
0245  * false otherwise.
0246  */
0247 static inline bool rtems_rbtree_is_empty(
0248   const rtems_rbtree_control *the_rbtree
0249 )
0250 {
0251   return _RBTree_Is_empty( the_rbtree );
0252 }
0253 
0254 /**
0255  * @brief Is this the minimum node on the RBTree.
0256  *
0257  * This function returns true if @a the_node is the min node on @a the_rbtree 
0258  * and false otherwise.
0259  */
0260 static inline bool rtems_rbtree_is_min(
0261   const rtems_rbtree_control *the_rbtree,
0262   const rtems_rbtree_node *the_node
0263 )
0264 {
0265   return rtems_rbtree_min( the_rbtree ) == the_node;
0266 }
0267 
0268 /**
0269  * @brief Is this the maximum node on the RBTree.
0270  *
0271  * This function returns true if @a the_node is the max node on @a the_rbtree 
0272  * and false otherwise.
0273  */
0274 static inline bool rtems_rbtree_is_max(
0275   const rtems_rbtree_control *the_rbtree,
0276   const rtems_rbtree_node *the_node
0277 )
0278 {
0279   return rtems_rbtree_max( the_rbtree ) == the_node;
0280 }
0281 
0282 /**
0283  * @copydoc _RBTree_Is_root()
0284  */
0285 static inline bool rtems_rbtree_is_root(
0286   const rtems_rbtree_node *the_node
0287 )
0288 {
0289   return _RBTree_Is_root( the_node );
0290 }
0291 
0292 static inline bool rtems_rbtree_is_equal(
0293   rtems_rbtree_compare_result compare_result
0294 )
0295 {
0296   return compare_result == 0;
0297 }
0298 
0299 static inline bool rtems_rbtree_is_greater(
0300   rtems_rbtree_compare_result compare_result
0301 )
0302 {
0303   return compare_result > 0;
0304 }
0305 
0306 static inline bool rtems_rbtree_is_lesser(
0307   rtems_rbtree_compare_result compare_result
0308 )
0309 {
0310   return compare_result < 0;
0311 }
0312 
0313 /**
0314  * @brief Tries to find a node for the specified key in the tree.
0315  *
0316  * @param[in] the_rbtree The red-black tree control.
0317  * @param[in] the_node A node specifying the key.
0318  * @param[in] compare The node compare function.
0319  * @param[in] is_unique If true, then return the first node with a key equal to
0320  *   the one of the node specified if it exits, else return the last node if it
0321  *   exists.
0322  *
0323  * @retval node A node corresponding to the key.  If the tree is not unique
0324  * and contains duplicate keys, the set of duplicate keys acts as FIFO.
0325  * @retval NULL No node exists in the tree for the key.
0326  */
0327 rtems_rbtree_node* rtems_rbtree_find(
0328   const rtems_rbtree_control *the_rbtree,
0329   const rtems_rbtree_node    *the_node,
0330   rtems_rbtree_compare              compare,
0331   bool                        is_unique
0332 );
0333 
0334 /**
0335  * @copydoc _RBTree_Predecessor()
0336  */
0337 static inline rtems_rbtree_node* rtems_rbtree_predecessor(
0338   const rtems_rbtree_node *node
0339 )
0340 {
0341   return _RBTree_Predecessor( node );
0342 }
0343 
0344 /**
0345  * @copydoc _RBTree_Successor()
0346  */
0347 static inline rtems_rbtree_node* rtems_rbtree_successor(
0348   const rtems_rbtree_node *node
0349 )
0350 {
0351   return _RBTree_Successor( node );
0352 }
0353 
0354 /**
0355  * @copydoc _RBTree_Extract()
0356  */
0357 static inline void rtems_rbtree_extract(
0358   rtems_rbtree_control *the_rbtree,
0359   rtems_rbtree_node *the_node
0360 )
0361 {
0362   _RBTree_Extract( the_rbtree, the_node );
0363 }
0364 
0365 /**
0366  * @brief Gets a node with the minimum key value from the red-black tree.
0367  *
0368  * This function extracts a node with the minimum key value from
0369  * tree and returns a pointer to that node if it exists.  In case multiple
0370  * nodes with a minimum key value exist, then they are extracted in FIFO order.
0371  *
0372  * @param[in] the_rbtree The red-black tree control.
0373  *
0374  * @retval NULL The tree is empty.
0375  * @retval node A node with the minimal key value on the tree.
0376  */
0377 static inline rtems_rbtree_node *rtems_rbtree_get_min(
0378   rtems_rbtree_control *the_rbtree
0379 )
0380 {
0381   rtems_rbtree_node *the_node = rtems_rbtree_min( the_rbtree );
0382 
0383   if ( the_node != NULL ) {
0384     rtems_rbtree_extract( the_rbtree, the_node );
0385   }
0386 
0387   return the_node;
0388 }
0389 
0390 /**
0391  * @brief Gets a node with the maximal key value from the red-black tree.
0392  *
0393  * This function extracts a node with the maximum key value from tree and
0394  * returns a pointer to that node if it exists.  In case multiple nodes with a
0395  * maximum key value exist, then they are extracted in LIFO order.
0396  *
0397  * @param[in] the_rbtree The red-black tree control.
0398  *
0399  * @retval NULL The tree is empty.
0400  * @retval node A node with the maximal key value on the tree.
0401  */
0402 static inline rtems_rbtree_node *rtems_rbtree_get_max(
0403   rtems_rbtree_control *the_rbtree
0404 )
0405 {
0406   rtems_rbtree_node *the_node = rtems_rbtree_max( the_rbtree );
0407 
0408   if ( the_node != NULL ) {
0409     rtems_rbtree_extract( the_rbtree, the_node );
0410   }
0411 
0412   return the_node;
0413 }
0414 
0415 /**
0416  * @brief Peek at the min node on a rbtree.
0417  *
0418  * This function returns a pointer to the min node from @a the_rbtree 
0419  * without changing the tree.  If @a the_rbtree is empty, 
0420  * then NULL is returned.
0421  */
0422 static inline rtems_rbtree_node *rtems_rbtree_peek_min(
0423   const rtems_rbtree_control *the_rbtree
0424 )
0425 {
0426   return rtems_rbtree_min( the_rbtree );
0427 }
0428 
0429 /**
0430  * @brief Peek at the max node on a rbtree.
0431  *
0432  * This function returns a pointer to the max node from @a the_rbtree 
0433  * without changing the tree.  If @a the_rbtree is empty, 
0434  * then NULL is returned.
0435  */
0436 static inline rtems_rbtree_node *rtems_rbtree_peek_max(
0437   const rtems_rbtree_control *the_rbtree
0438 )
0439 {
0440   return rtems_rbtree_max( the_rbtree );
0441 }
0442 
0443 /**
0444  * @brief Inserts the node into the red-black tree.
0445  *
0446  * In case the node is already a node of a tree, then this function yields
0447  * unpredictable results.
0448  *
0449  * @param[in] the_rbtree The red-black tree control.
0450  * @param[in] the_node The node to insert.
0451  * @param[in] compare The node compare function.
0452  * @param[in] is_unique If true, then reject nodes with a duplicate key, else
0453  *   insert nodes in FIFO order in case the key value is equal to existing nodes.
0454  *
0455  * @retval NULL Successfully inserted.
0456  * @retval existing_node This is a unique insert and there exists a node with
0457  *   an equal key in the tree already.
0458  */
0459 rtems_rbtree_node *rtems_rbtree_insert(
0460   RBTree_Control *the_rbtree,
0461   RBTree_Node    *the_node,
0462   rtems_rbtree_compare  compare,
0463   bool            is_unique
0464 );
0465 
0466 /** @} */
0467 
0468 #ifdef __cplusplus
0469 }
0470 #endif
0471 
0472 #endif
0473 /* end of include file */