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     template <typename> class Avl_node;
  23     template <typename> class Avl_tree;
  24  }

  25  
  26  
  27  class Genode::Avl_node_base
  28  {
  29     protected:
  30  
  31        /**
  32         * Internal policy interface
  33         *
  34         * The implementation of this interface is provided by the AVL tree.
  35         */

  36        struct Policy
  37        {
  38           virtual ~Policy() { }
  39  
  40           /**
  41            * Compare two nodes
  42            *
  43            * \retval false if n2 is lower than n1
  44            * \retval true  if n2 is higher than or equal to n1
  45            *
  46            * This method must be provided by the derived class.
  47            * It determines the order of nodes inside the AVL tree.
  48            */

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

  50  
  51           /**
  52            * Node recomputation hook
  53            *
  54            * If a node gets rearranged, this method is called.
  55            * It can be used to update AVL-tree-position dependent
  56            * meta data.
  57            */

  58           virtual void recompute(Avl_node_base *) { }

  59        }
;

  60  
  61        Avl_node_base *_child[2];  /* left and right subtrees */
  62        Avl_node_base *_parent;    /* parent of subtree       */
  63        unsigned char  _depth;     /* depth of subtree        */

  64  
  65     public:
  66  
  67        typedef bool Side;
  68  
  69        enum { LEFT = false, RIGHT = true };

  70  
  71     private:
  72  
  73        /**
  74         * Determine depth of subtree
  75         */

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

  78  
  79        /**
  80         * Update depth of node
  81         */

  82        void _recompute_depth(Policy &policy);

  83  
  84        /**
  85         * Determine left-right bias of both subtrees
  86         */

  87        inline Side _bias() {
  88           return (_child_depth(RIGHT) > _child_depth(LEFT)); }

  89  
  90        /**
  91         * Insert subtree into specified side of the node
  92         */

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

  94  
  95        /**
  96         * Rotate subtree
  97         *
  98         * \param side   direction of rotate operation
  99         * \param node   subtree to rotate
 100         *
 101         * The local node_* variable names describe node locations for
 102         * the left (default) rotation. For example, node_r_l is the
 103         * left of the right of node.
 104         */

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

 106  
 107        /**
 108         * Rebalance subtree
 109         *
 110         * \param node   immediate child that needs balancing
 111         *
 112         * `this` is parent of the subtree to rebalance
 113         */

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

 115  
 116     public:
 117  
 118        /**
 119         * Constructor
 120         */

 121        Avl_node_base();

 122  
 123        /**
 124         * Insert new node into subtree
 125         */

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

 127  
 128        /**
 129         * Remove node from tree
 130         */

 131        void remove(Policy &policy);

 132  }
;

 133  
 134  
 135  /**
 136   * AVL node
 137   *
 138   * \param NT  type of the class derived from `Avl_node`
 139   *
 140   * Each object to be stored in the AVL tree must be derived from `Avl_node`.
 141   * The type of the derived class is to be specified as template argument to
 142   * enable `Avl_node` to call virtual methods specific for the derived class.
 143   *
 144   * The NT class must implement a method called `higher` that takes a pointer to
 145   * another NT object as argument and returns a bool value. The bool value is
 146   * true if the specified node is higher or equal in the tree order.
 147   */

 148  template <typename NT>
 149  struct Genode::Avl_node : Avl_node_base
 150  {
 151     /**
 152      * Return child of specified side, or nullptr if there is no child
 153      *
 154      * This method can be called by the NT objects to traverse the tree.
 155      */

 156     inline NT *child(Side i) const { return static_cast<NT *>(_child[i]); }

 157  
 158     /**
 159      * Default policy
 160      *
 161      * \noapi
 162      */

 163     void recompute() { }

 164  }
;

 165  
 166  
 167  /**
 168   * Root node of the AVL tree
 169   *
 170   * The real nodes are always attached at the left branch of this root node.
 171   */

 172  template <typename NT>
 173  class Genode::Avl_tree : Avl_node<NT>
 174  {
 175     private:
 176  
 177        /**
 178         * Auto-generated policy class specific for NT
 179         */

 180        class Policy : public Avl_node_base::Policy
 181        {
 182           bool higher(Avl_node_base *n1, Avl_node_base *n2) const
 183           {
 184              return static_cast<NT *>(n1)->higher(static_cast<NT *>(n2));
 185           }

 186  
 187           void recompute(Avl_node_base *node)
 188           {
 189              static_cast<NT *>(node)->recompute();
 190           }

 191  
 192        }
 _policy;

 193  
 194     public:
 195  
 196        /**
 197         * Insert node into AVL tree
 198         */

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

 200  
 201        /**
 202         * Remove node from AVL tree
 203         */

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

 205  
 206        /**
 207         * Request first node of the tree
 208         *
 209         * \return  first node, or nullptr if the tree is empty
 210         */

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

 212  }
;

 213  
 214  #endif /* _INCLUDE__UTIL__AVL_TREE_H_ */