1  /*
   2   * \brief  AVL tree
   3   * \author Norman Feske
   4   * \date   2006-04-12
   5   */

   6  
   7  /*
   8   * Copyright (C) 2006-2013 Genode Labs GmbH
   9   *
  10   * This file is part of the Genode OS framework, which is distributed
  11   * under the terms of the GNU General Public License version 2.
  12   */

  13  
  14  #ifndef _INCLUDE__UTIL__AVL_TREE_H_
  15  #define _INCLUDE__UTIL__AVL_TREE_H_
  16  
  17  #include <util/misc_math.h>
  18  
  19  namespace Genode {
  20  
  21     class Avl_node_base
  22     {
  23        protected:
  24  
  25           /**
  26            * Internal policy interface
  27            *
  28            * The implementation of this interface is provided by the AVL tree.
  29            */

  30           struct Policy
  31           {
  32              virtual ~Policy() { }
  33  
  34              /**
  35               * Compare two nodes
  36               *
  37               * \retval false if n2 is lower than n1
  38               * \retval true  if n2 is higher than or equal to n1
  39               *
  40               * This function must be provided by the derived class.
  41               * It determines the order of nodes inside the avl tree.
  42               */

  43              virtual bool higher(Avl_node_base *n1, Avl_node_base *n2) const = 0;

  44  
  45              /**
  46               * Node recomputation hook
  47               *
  48               * If a node gets rearranged, this function is called.
  49               * It can be used to update avl-tree-position dependent
  50               * meta data.
  51               */

  52              virtual void recompute(Avl_node_base *) { }

  53           }
;

  54  
  55           Avl_node_base *_child[2];  /* left and right subtrees */
  56           Avl_node_base *_parent;    /* parent of subtree       */
  57           unsigned char  _depth;     /* depth of subtree        */

  58  
  59        public:
  60  
  61           typedef bool Side;
  62  
  63           enum { LEFT = false, RIGHT = true };

  64  
  65        private:
  66  
  67           /**
  68            * Determine depth of subtree
  69            */

  70           inline int _child_depth(Side i) {
  71              return _child[i] ? _child[i]->_depth : 0; }

  72  
  73           /**
  74            * Update depth of node
  75            */

  76           void _recompute_depth(Policy &policy);

  77  
  78           /**
  79            * Determine left-right bias of both subtrees
  80            */

  81           inline Side _bias() {
  82              return (_child_depth(RIGHT) > _child_depth(LEFT)); }

  83  
  84           /**
  85            * Insert subtree into specified side of the node
  86            */

  87           void _adopt(Avl_node_base *node, Side i, Policy &policy);

  88  
  89           /**
  90            * Rotate subtree
  91            *
  92            * \param side   direction of rotate operation
  93            * \param node   subtree to rotate
  94            *
  95            * The local node_* variable names describe node locations for
  96            * the left (default) rotation. For example, node_r_l is the
  97            * left of the right of node.
  98            */

  99           void _rotate_subtree(Avl_node_base *node, Side side, Policy &policy);

 100  
 101           /**
 102            * Rebalance subtree
 103            *
 104            * \param node   immediate child that needs balancing
 105            *
 106            * `this` is parent of the subtree to rebalance
 107            */

 108           void _rebalance_subtree(Avl_node_base *node, Policy &policy);

 109  
 110        public:
 111  
 112           /**
 113            * Constructor
 114            */

 115           Avl_node_base();

 116  
 117           /**
 118            * Insert new node into subtree
 119            */

 120           void insert(Avl_node_base *node, Policy &policy);

 121  
 122           /**
 123            * Remove node from tree
 124            */

 125           void remove(Policy &policy);

 126     }
;

 127  
 128  
 129     /**
 130      * AVL node
 131      *
 132      * \param NT  type of the class derived from `Avl_node`
 133      *
 134      * Each object to be stored in the avl tree must be derived from
 135      * `Avl_node`. The type of the derived class is to be specified as
 136      * template argument to enable `Avl_node` to call virtual functions
 137      * specific for the derived class.
 138      */

 139     template <typename NT>
 140     class Avl_node : public Avl_node_base
 141     {
 142        public:
 143  
 144           inline NT *child(Side i) const { return static_cast<NT *>(_child[i]); }
 145  
 146           /**
 147            * Default policy
 148            */

 149           void recompute() { }

 150     }
;

 151  
 152  
 153     /**
 154      * Root node of the AVL tree
 155      *
 156      * The real nodes are always attached at the left branch of
 157      * this root node.
 158      */

 159     template <typename NT>
 160     class Avl_tree : Avl_node<NT>
 161     {
 162        private:
 163  
 164           /**
 165            * Auto-generated policy class specific for NT
 166            */

 167           class Policy : public Avl_node_base::Policy
 168           {
 169              bool higher(Avl_node_base *n1, Avl_node_base *n2) const
 170              
{
 171                 return static_cast<NT *>(n1)->higher(static_cast<NT *>(n2));
 172              }

 173  
 174              void recompute(Avl_node_base *node)
 175              {
 176                 static_cast<NT *>(node)->recompute();
 177              }

 178  
 179           }
 _policy;

 180  
 181        public:
 182  
 183           /**
 184            * Insert node into AVL tree
 185            */

 186           void insert(Avl_node<NT> *node) { Avl_node_base::insert(node, _policy); }

 187  
 188           /**
 189            * Remove node from AVL tree
 190            */

 191           void remove(Avl_node<NT> *node) { node->remove(_policy); }

 192  
 193           /**
 194            * Request first node of the tree
 195            *
 196            * \return  first node
 197            * \retval  NULL if tree is empty
 198            */

 199           inline NT *first() const { return this->child(Avl_node<NT>::LEFT); }

 200     }
;

 201  }

 202  
 203  #endif /* _INCLUDE__UTIL__AVL_TREE_H_ */