summaryrefslogblamecommitdiffstats
path: root/cpukit/score/include/rtems/score/rbtree.h
blob: c01de799eaf1fa70ed7e5977a8f207ed659893d5 (plain) (tree)
1
2
3
4
5


                               

                                                                              








                                                                          
                                         




                             

                   





                                


                                                

                  







                                                                                








                                                                        
 






                                                                   
 



















                                                                              


                                                   
 
   





                                      
 
   








                                                                             










                                                                               
   
                                                  

                           


   










                                                                             
 













                                                                             
 


                                                                          

                                          
 


                                                                         

                                                        
 


                                                                             

                                               
 


                                                                         

                                                          
 
   
                                                                 
  

                                                    



                                                                               
  


                                                                           
   
                          
                                   


                                 

  
   
                                                   
  

                                                                          
  



                                                                             
                                                                                 
  


                                                                             
   
                            
                             


                           
  
 
   
                                                              
  
                                                                               
                                                    





                                                                            
   
                     


                             
 
   

                                                   





                                                      
                          




                          
                                                 
  
                                                                
  


                                                
   
                                                                       
 
                          


   



                                                                          
  



                                                            
   


                                                   
 
                                  
 

   
                                                               
  







                                                               






















                                                                           
                                                       
  







                                                                               




                                                 





















































                                                                        
                                                                             

                   









                                                                            

                                          
                             

 
                                                              


   
                                                                    
  





                                                                      
   


                                                          
 








                                            







                                                                

                            


                                      

                                      


   





























                                                         






                                                                     
                                                      


                         
                                        


   





                                                                            
                                                    


                         
                                         

 

       



                  
      
                         
/**
 *  @file  rtems/score/rbtree.h
 *
 *  @brief Constants and Structures Associated with the Red-Black Tree Handler
 *
 *  This include file contains all the constants and structures associated
 *  with the Red-Black Tree Handler.
 */

/*
 *  Copyright (c) 2010 Gedare Bloom.
 *
 *  The license and distribution terms for this file may be
 *  found in the file LICENSE in this distribution or at
 *  http://www.rtems.org/license/LICENSE.
 */

#ifndef _RTEMS_SCORE_RBTREE_H
#define _RTEMS_SCORE_RBTREE_H

#include <stddef.h>

#include <rtems/score/address.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 *  @defgroup ScoreRBTree Red-Black Tree Handler
 *
 *  @ingroup Score
 *
 *  The Red-Black Tree Handler is used to manage sets of entities.  This handler
 *  provides two data structures.  The rbtree Node data structure is included
 *  as the first part of every data structure that will be placed on
 *  a RBTree.  The second data structure is rbtree Control which is used
 *  to manage a set of rbtree Nodes.
 */
/**@{*/

/**
 *  @typedef RBTree_Node
 *
 *  This type definition promotes the name for the RBTree Node used by
 *  all RTEMS code.  It is a separate type definition because a forward
 *  reference is required to define it.  See @ref RBTree_Node_struct for
 *  detailed information.
 */
typedef struct RBTree_Node_struct RBTree_Node;

/**
 * This enum type defines the colors available for the RBTree Nodes
 */
typedef enum {
  RBT_BLACK,
  RBT_RED
} RBTree_Color;

/**
 *  @struct RBTree_Node_struct
 *
 *  This is used to manage each element (node) which is placed
 *  on a RBT.
 *
 *  @note Typically, a more complicated structure will use the
 *        rbtree package.  The more complicated structure will
 *        include a rbtree node as the first element in its
 *        control structure.  It will then call the rbtree package
 *        with a pointer to that node element.  The node pointer
 *        and the higher level structure start at the same address
 *        so the user can cast the pointers back and forth.
 *
 */
struct RBTree_Node_struct {
  /** This points to the node's parent */
  RBTree_Node *parent;
  /** child[0] points to the left child, child[1] points to the right child */
  RBTree_Node *child[2];
  /** The color of the node. Either red or black */
  RBTree_Color color;
};

/**
 *  This type indicates the direction.
 */
typedef enum {
  RBT_LEFT=0,
  RBT_RIGHT=1
} RBTree_Direction;

/**
 * @brief Integer type for compare results.
 *
 * The type is large enough to represent pointers and 32-bit signed integers.
 *
 * @see RBTree_Compare.
 */
typedef long RBTree_Compare_result;

/**
 * @brief Compares two red-black tree nodes.
 *
 * @param[in] first The first node.
 * @param[in] second The second node.
 *
 * @retval positive The key value of the first node is greater than the one of
 *   the second node.
 * @retval 0 The key value of the first node is equal to the one of the second
 *   node.
 * @retval negative The key value of the first node is less than the one of the
 *   second node.
 */
typedef RBTree_Compare_result ( *RBTree_Compare )(
  const RBTree_Node *first,
  const RBTree_Node *second
);

/**
 *  @struct RBTree_Control
 *
 * This is used to manage a RBT.  A rbtree consists of a tree of zero or more
 * nodes.
 *
 * @note This implementation does not require special checks for
 *   manipulating the root element of the RBT.
 *   To accomplish this the @a RBTree_Control structure can be overlaid
 *   with a @ref RBTree_Node structure to act as a "dummy root",
 *   which has a NULL parent and its left child is the root.
 */

/* the RBTree_Control is actually part of the RBTree structure as an
 * RBTree_Node. The mapping of fields from RBTree_Control to RBTree_Node are:
 *   permanent_null == parent
 *   root == left
 *   first[0] == right
 */
typedef struct {
  /** This points to a NULL. Useful for finding the root. */
  RBTree_Node *permanent_null;
  /** This points to the root node of the RBT. */
  RBTree_Node *root;
  /** This points to the min and max nodes of this RBT. */
  RBTree_Node *first[2];
} RBTree_Control;

/**
 *  @brief RBTree initializer for an empty rbtree with designator @a name.
 */
#define RBTREE_INITIALIZER_EMPTY( name ) \
  { NULL, NULL, { NULL, NULL } }

/**
 *  @brief RBTree definition for an empty rbtree with designator @a name.
 */
#define RBTREE_DEFINE_EMPTY( name ) \
  RBTree_Control name = RBTREE_INITIALIZER_EMPTY( name )

/**
 *  @brief RBTree_Node initializer for an empty node with designator @a name.
 */
#define RBTREE_NODE_INITIALIZER_EMPTY( name ) \
  { NULL, { NULL, NULL }, RBT_RED }

/**
 *  @brief RBTree definition for an empty rbtree with designator @a name.
 */
#define RBTREE_NODE_DEFINE_EMPTY( name ) \
  RBTree_Node name = RBTREE_NODE_INITIALIZER_EMPTY( name )

/**
 * @brief Tries to find a node for the specified key in the tree.
 *
 * @param[in] the_rbtree The red-black tree control.
 * @param[in] the_node A node specifying the key.
 * @param[in] compare The node compare function.
 * @param[in] is_unique If true, then return the first node with a key equal to
 *   the one of the node specified if it exits, else return the last node if it
 *   exists.
 *
 * @retval node A node corresponding to the key.  If the tree is not unique
 * and contains duplicate keys, the set of duplicate keys acts as FIFO.
 * @retval NULL No node exists in the tree for the key.
 */
RBTree_Node *_RBTree_Find(
  const RBTree_Control *the_rbtree,
  const RBTree_Node    *the_node,
  RBTree_Compare        compare,
  bool                  is_unique
);

/**
 * @brief Inserts the node into the red-black tree.
 *
 * In case the node is already a node of a tree, then this function yields
 * unpredictable results.
 *
 * @param[in] the_rbtree The red-black tree control.
 * @param[in] the_node The node to insert.
 * @param[in] compare The node compare function.
 * @param[in] is_unique If true, then reject nodes with a duplicate key, else
 *   insert nodes in FIFO order in case the key value is equal to existing nodes.
 *
 * @retval NULL Successfully inserted.
 * @retval existing_node This is a unique insert and there exists a node with
 *   an equal key in the tree already.
 */
RBTree_Node *_RBTree_Insert(
  RBTree_Control *the_rbtree,
  RBTree_Node    *the_node,
  RBTree_Compare  compare,
  bool            is_unique
);

/**
 * @brief Extracts (removes) the node from the red-black tree.
 *
 * This function does not set the node off-tree.  In case this is desired, then
 * call _RBTree_Set_off_tree() after the extraction.
 *
 * In case the node to extract is not a node of the tree, then this function
 * yields unpredictable results.
 *
 * @param[in] the_rbtree The red-black tree control.
 * @param[in] the_node The node to extract.
 */
void _RBTree_Extract(
  RBTree_Control *the_rbtree,
  RBTree_Node *the_node
);

/**
 * @brief Returns the in-order next node of a node.
 *
 * @param[in] node The node.
 * @param[in] dir The direction.
 *
 * @retval NULL The in-order next node does not exist.
 * @retval otherwise The next node.
 */
RBTree_Node *_RBTree_Next(
  const RBTree_Node *node,
  RBTree_Direction dir
);

/**
 * @brief Sets a red-black tree node as off-tree.
 *
 * Do not use this function on nodes which are a part of a tree.
 *
 * @param[in] the_node The node to set off-tree.
 *
 * @see _RBTree_Is_node_off_tree().
 */
RTEMS_INLINE_ROUTINE void _RBTree_Set_off_tree( RBTree_Node *the_node )
{
  the_node->parent = NULL;
}

/**
 * @brief Returns true, if this red-black tree node is off-tree, and false
 * otherwise.
 *
 * @param[in] the_node The node to test.
 *
 * @retval true The node is not a part of a tree (off-tree).
 * @retval false Otherwise.
 *
 * @see _RBTree_Set_off_tree().
 */
RTEMS_INLINE_ROUTINE bool _RBTree_Is_node_off_tree(
  const RBTree_Node *the_node
)
{
  return the_node->parent == NULL;
}

/**
 * @brief Returns a pointer to root node of the red-black tree.
 *
 * The root node may change after insert or extract operations.
 *
 * @param[in] the_rbtree The red-black tree control.
 *
 * @retval NULL The tree is empty.
 * @retval root The root node.
 *
 * @see _RBTree_Is_root().
 */
RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Root(
  const RBTree_Control *the_rbtree
)
{
  return the_rbtree->root;
}

/**
 * @brief Return pointer to RBTree's first node.
 *
 * This function returns a pointer to the first node on @a the_rbtree,
 * where @a dir specifies whether to return the minimum (0) or maximum (1).
 */
RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_First(
  const RBTree_Control *the_rbtree,
  RBTree_Direction dir
)
{
  return the_rbtree->first[dir];
}

/**
 * @brief Returns a pointer to the parent of this node.
 *
 * The node must have a parent, thus it is invalid to use this function for the
 * root node or a node that is not part of a tree.  To test for the root node
 * compare with _RBTree_Root() or use _RBTree_Is_root().
 *
 * @param[in] the_node The node of interest.
 *
 * @retval parent The parent of this node.
 * @retval undefined The node is the root node or not part of a tree.
 */
RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Parent(
  const RBTree_Node *the_node
)
{
  return the_node->parent;
}

/**
 * @brief Return pointer to the left of this node.
 *
 * This function returns a pointer to the left node of this node.
 *
 * @param[in] the_node is the node to be operated upon.
 *
 * @return This method returns the left node on the rbtree.
 */
RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Left(
  const RBTree_Node *the_node
)
{
  return the_node->child[RBT_LEFT];
}

/**
 * @brief Return pointer to the right of this node.
 *
 * This function returns a pointer to the right node of this node.
 *
 * @param[in] the_node is the node to be operated upon.
 *
 * @return This method returns the right node on the rbtree.
 */
RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Right(
  const RBTree_Node *the_node
)
{
  return the_node->child[RBT_RIGHT];
}

/**
 * @brief Is the RBTree empty.
 *
 * This function returns true if there are no nodes on @a the_rbtree and
 * false otherwise.
 *
 * @param[in] the_rbtree is the rbtree to be operated upon.
 *
 * @retval true There are no nodes on @a the_rbtree.
 * @retval false There are nodes on @a the_rbtree.
 */
RTEMS_INLINE_ROUTINE bool _RBTree_Is_empty(
  const RBTree_Control *the_rbtree
)
{
  return (the_rbtree->root == NULL);
}

/**
 * @brief Returns true if this node is the root node of a red-black tree, and
 * false otherwise.
 *
 * The root node may change after insert or extract operations.  In case the
 * node is not a node of a tree, then this function yields unpredictable
 * results.
 *
 * @param[in] the_node The node of interest.
 *
 * @retval true The node is the root node.
 * @retval false Otherwise.
 *
 * @see _RBTree_Root().
 */
RTEMS_INLINE_ROUTINE bool _RBTree_Is_root(
  const RBTree_Node *the_node
)
{
  return _RBTree_Parent( _RBTree_Parent( the_node ) ) == NULL;
}

/**
 * @brief Finds the red-black tree control given a node in the tree.
 *
 * In case the node is not a node of a tree, then this function yields
 * unpredictable results.
 *
 * @param[in] the_node The node of interest.
 *
 * @return The red-black tree control of the node.
 */
RTEMS_INLINE_ROUTINE RBTree_Control *_RBTree_Find_control(
  const RBTree_Node *the_node
)
{
  RBTree_Node    *parent = the_node->parent;
  RBTree_Control *rbtree;

  do {
    rbtree = (RBTree_Control *) parent;
    parent = parent->parent;
  } while ( parent != NULL );

  return rbtree;
}

/**
 * @brief Initialize this RBTree as empty.
 *
 * This routine initializes @a the_rbtree to contain zero nodes.
 */
RTEMS_INLINE_ROUTINE void _RBTree_Initialize_empty(
  RBTree_Control *the_rbtree
)
{
  the_rbtree->permanent_null   = NULL;
  the_rbtree->root             = NULL;
  the_rbtree->first[RBT_LEFT]  = NULL;
  the_rbtree->first[RBT_RIGHT] = NULL;
}

/**
 * @brief Returns the minimum node of the red-black tree.
 *
 * @param[in] the_rbtree The red-black tree control.
 *
 * @retval NULL The red-black tree is empty.
 * @retval node The minimum node.
 */
RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Minimum(
  const RBTree_Control *the_rbtree
)
{
  return _RBTree_First( the_rbtree, RBT_LEFT );
}

/**
 * @brief Returns the maximum node of the red-black tree.
 *
 * @param[in] the_rbtree The red-black tree control.
 *
 * @retval NULL The red-black tree is empty.
 * @retval node The maximum node.
 */
RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Maximum(
  const RBTree_Control *the_rbtree
)
{
  return _RBTree_First( the_rbtree, RBT_RIGHT );
}

/**
 * @brief Returns the predecessor of a node.
 *
 * @param[in] node is the node.
 *
 * @retval NULL The predecessor does not exist.  Otherwise it returns
 *         the predecessor node.
 */
RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Predecessor(
  const RBTree_Node *node
)
{
  return _RBTree_Next( node, RBT_LEFT );
}

/**
 * @brief Returns the successor of a node.
 *
 * @param[in] node is the node.
 *
 * @retval NULL The successor does not exist.  Otherwise the successor node.
 */
RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Successor(
  const RBTree_Node *node
)
{
  return _RBTree_Next( node, RBT_RIGHT );
}

/**@}*/

#ifdef __cplusplus
}
#endif

#endif
/* end of include file */