7 * (c) 2008-2009 Alexander Warg <warg@os.inf.tu-dresden.de>,
8 * Carsten Weinhold <weinhold@os.inf.tu-dresden.de>
9 * economic rights: Technische Universität Dresden (Germany)
11 * This file is part of TUD:OS and distributed under the terms of the
12 * GNU General Public License 2.
13 * Please see the COPYING-GPL-2 file for details.
15 * As a special exception, you may use this file as part of a free software
16 * library without restriction. Specifically, if other files instantiate
17 * templates or use macros or inline functions from this file, or you compile
18 * this file and link it with other files to produce an executable, this
19 * file does not by itself cause the resulting executable to be covered by
20 * the GNU General Public License. This exception does not however
21 * invalidate any other reasons why the executable file might be covered by
22 * the GNU General Public License.
27 #include <l4/cxx/std_ops>
28 #include <l4/cxx/pair>
29 #include <l4/cxx/type_traits>
36 * \brief Generic iterator for the AVL-tree based set.
37 * \param Cmp the type of the comparison functor.
38 * \param Node the type of a node.
39 * \param Node_op the type used to determine the direction of the iterator.
41 template< typename Node, typename Node_op >
42 class __Avl_tree_iter_b
45 Node const *_n; ///< Current node
46 Node const *_r; ///< Root node of current subtree
48 /// Create an invalid iterator, used as end marker.
49 __Avl_tree_iter_b() : _n(0), _r(0) {}
52 * \brief Create an iterator for the given AVL tree.
53 * \param t the root node of the tree to iterate.
54 * \param cmp the comparison functor for tree elements.
56 __Avl_tree_iter_b(Node const *t)
60 __Avl_tree_iter_b(Node const *t, Node const *r)
64 /// traverse the subtree down to the leftmost/rightmost leave.
65 inline void _downmost();
67 /// Increment to the next element.
71 /// Check two iterators for equality.
72 bool operator == (__Avl_tree_iter_b const &o) const { return _n == o._n; }
73 /// Check two iterators for non equality.
74 bool operator != (__Avl_tree_iter_b const &o) const { return _n != o._n; }
80 * \brief Generic iterator for the AVL-tree based set.
81 * \param Node the type of a node.
82 * \param Node_type the type of the node to return stored in a node.
83 * \param Node_op the type used to determine the direction of the iterator.
85 template< typename Node, typename Node_type, typename Node_op >
86 class __Avl_tree_iter : public __Avl_tree_iter_b<Node, Node_op>
90 typedef __Avl_tree_iter_b<Node, Node_op> Base;
97 /// Create an invalid iterator (end marker)
101 * \brief Create an iterator for the given tree.
102 * \param t the root node of the tree to iterate.
103 * \param cmp the conmparison functor for tree elements.
105 __Avl_tree_iter(Node const *t) : Base(t) {}
106 __Avl_tree_iter(Node const *t, Node const *r) : Base(t, r) {}
108 // template<typename Key2>
109 __Avl_tree_iter(Base const &o) : Base(o) {}
112 * \brief Dereference the iterator and get the item out of the tree.
113 * \return A reference to the data stored in the AVL tree.
115 Node_type &operator * () const { return *const_cast<Node *>(_n); }
117 * \brief Member access to the item the iterator points to.
118 * \return A pointer to the item in the node.
120 Node_type *operator -> () const { return const_cast<Node *>(_n); }
122 * \brief Set the iterator to the next element (pre increment).
124 __Avl_tree_iter &operator ++ () { inc(); return *this; }
126 * \brief Set the iterator to the next element (post increment).
128 __Avl_tree_iter &operator ++ (int)
129 { __Avl_tree_iter tmp = *this; inc(); return tmp; }
136 template< typename Node, typename Get_key, typename Compare, bool Const_nodes >
137 friend class Avl_tree;
141 Avl_tree_node *right;
142 unsigned short flags;
144 Md() : left(0), right(0), flags(0), balance(0) {}
148 Avl_tree_node() : _md() {}
150 void operator = (Avl_tree_node const &)
155 Avl_tree_node(Avl_tree_node const &o);
157 /// Adjust balance value
158 inline void adj_balance(Avl_tree_node *b, Avl_tree_node *c, int v = -1);
159 /// Replace the child \a c with \a repl.
160 inline void replace_child(Avl_tree_node *c, Avl_tree_node *repl);
162 /// Right rotation of this node.
163 void r_rotate(Avl_tree_node *r)
164 { _md.left = r->_md.right; r->_md.right = this; }
166 /// Left rotation of this node.
167 void l_rotate(Avl_tree_node *r)
168 { _md.right = r->_md.left; r->_md.left = this; }
170 static void swap(Avl_tree_node *a, Avl_tree_node *b)
171 { Md tmp = a->_md; a->_md = b->_md; b->_md = tmp; }
175 template< typename Node, typename Get_key,
176 typename Compare = Lt_functor<typename Get_key::Key_type>,
177 bool Const_nodes = true >
190 /// Current height of the tree.
191 unsigned long _height;
192 /// Head node of the tree, the root is \a _head.right.
195 /// Ops for forward iterators
198 static Node *child1(Node const *n) { return N(n->_md.left); }
199 static Node *child2(Node const *n) { return N(n->_md.right); }
200 static bool cmp(Node const *l, Node const *r)
201 { return Compare()(Get_key::key_of(l), Get_key::key_of(r)); }
204 /// Ops for Reverse iterators
207 static Node *child1(Node const *n) { return N(n->_md.right); }
208 static Node *child2(Node const *n) { return N(n->_md.left); }
209 static bool cmp(Node const *l, Node const *r)
210 { return Compare()(Get_key::key_of(r), Get_key::key_of(l)); }
213 Avl_tree(Avl_tree const &o);
216 typedef typename Get_key::Key_type Key_type;
217 typedef typename Type_traits<Key_type>::Param_type Key_param_type;
219 typedef Rev Rev_iter_ops;
220 typedef Fwd Fwd_iter_ops;
221 /// Forward iterator for the set.
222 typedef __Avl_tree_iter<Node, Node, Fwd> Iterator;
223 typedef Iterator iterator;
224 /// Constant forward iterator for the set.
225 typedef __Avl_tree_iter<Node, Node const, Fwd> Const_iterator;
226 typedef Const_iterator const_iterator;
227 /// Backward iterator for the set.
228 typedef __Avl_tree_iter<Node, Node, Rev> Rev_iterator;
229 typedef Rev_iterator reverse_iterator;
230 /// Constant backward iterator for the set.
231 typedef __Avl_tree_iter<Node, Node const, Rev> Const_rev_iterator;
232 typedef Const_rev_iterator const_reverse_iterator;
234 Avl_tree() : _height(0) {}
235 cxx::Pair<Iterator, int> insert(Node *new_node);
238 * \brief Remove an item from the set.
239 * \param key The item to remove.
240 * \return 0 on success, -3 if the item does not exist, and
241 * -4 on internal error.
243 Node *remove(Key_param_type key);
244 Node *erase(Key_param_type key) { return remove(key); }
247 * \brief Lookup a node equal to \a key.
248 * \param key The value to search for.
249 * \return A smart pointer to the element found, if no element found the
252 Node *find_node(Key_param_type key) const;
254 /// Destroy, and free the set.
257 Avl_tree_node const *n;
258 while ((n = _head._md.right))
259 remove(Get_key::key_of(N(n)));
263 * \brief Get the constant forward iterator for the first element in the set.
264 * \return Constant forward iterator for the first element in the set.
266 Const_iterator begin() const { return Const_iterator(N(_head._md.right)); }
268 * \brief Get the end marker for the constant forward iterator.
269 * \return The end marker for the constant forward iterator.
271 Const_iterator end() const { return Const_iterator(); }
274 * \brief Get the mutable forward iterator for the first element of the set.
275 * \return The mutable forward iterator for the first element of the set.
277 Iterator begin() { return Iterator(N(_head._md.right)); }
279 * \brief Get the end marker for the mutable forward iterator.
280 * \return The end marker for mutable forward iterator.
282 Iterator end() { return Iterator(); }
285 * \brief Get the constant backward iterator for the last element in the set.
286 * \return The constant backward iterator for the last element in the set.
288 Const_rev_iterator rbegin() const { return Const_rev_iterator(N(_head._md.right)); }
290 * \brief Get the end marker for the constant backward iterator.
291 * \return The end marker for the constant backward iterator.
293 Const_rev_iterator rend() const { return Const_rev_iterator(); }
296 * \brief Get the mutable backward iterator for the last element of the set.
297 * \return The mutable backward iterator for the last element of the set.
299 Rev_iterator rbegin() { return Rev_iterator(N(_head._md.right)); }
301 * \brief Get the end marker for the mutable backward iterator.
302 * \return The end marker for mutable backward iterator.
304 Rev_iterator rend() { return Rev_iterator(); }
306 Const_iterator find(Key_param_type key) const;
309 static Node *N(Avl_tree_node *n) { return static_cast<Node*>(n); }
310 static Node const *N(Avl_tree_node const *n) { return static_cast<Node const *>(n); }
315 //----------------------------------------------------------------------------
316 /* IMPLEMENTATION: __Avl_tree_iter_b */
318 template< typename Node, typename Node_op>
320 void __Avl_tree_iter_b<Node, Node_op>::_downmost()
324 if (Node_op::child1(_n))
325 _n = Node_op::child1(_n);
331 template< typename Node, typename Node_op>
332 void __Avl_tree_iter_b<Node, Node_op>::inc()
339 _r = _n = Node_op::child2(_r);
344 if (Node_op::child2(_n))
346 _n = Node_op::child2(_n);
355 if (Node_op::cmp(_n, q))
358 q = Node_op::child1(q);
360 else if (_n == q || Node_op::child2(q) == _n)
366 q = Node_op::child2(q);
374 //----------------------------------------------------------------------------
375 /* Implementation of Avl_tree_node */
377 void Avl_tree_node::adj_balance(Avl_tree_node *b, Avl_tree_node *c, int v)
379 if (_md.balance == 0)
384 else if (_md.balance == v)
397 /* Replace left or right child dependent on comparison. */
399 void Avl_tree_node::replace_child(Avl_tree_node *c, Avl_tree_node *repl)
408 //----------------------------------------------------------------------------
409 /* Implementation of AVL Tree */
411 /* Insert new _Node. */
412 template< typename Node, typename Get_key, class Compare, bool Const_nodes>
413 cxx::Pair<typename Avl_tree<Node, Get_key, Compare, Const_nodes>::Iterator, int>
414 Avl_tree<Node, Get_key, Compare, Const_nodes>::insert(Node *new_node)
416 if (!_head._md.right)
419 _head._md.right = new_node;
425 Avl_tree_node *p = _head._md.right; /* search variable */
426 Avl_tree_node *q = 0; /* new node */
427 Avl_tree_node *r; /* search variable (balancing) */
428 Avl_tree_node *s = _head._md.right; /* node where rebalancing may occur */
429 Avl_tree_node *t = &_head; /* parent of s */
431 int a; /* which subtree of s has grown -1 left ... */
434 if (cmp(Get_key::key_of(new_node), Get_key::key_of(N(p))))
440 /* found insert position */
442 p->_md.left = new_node;
446 else if (cmp(Get_key::key_of(N(p)), Get_key::key_of(new_node)))
452 /* found insert position */
454 p->_md.right = new_node;
459 /* item already exists */
460 return cxx::pair(end(), -E_exist);
462 /* insert position not yet found, move on */
472 /* adj balanc factors */
473 if (s != &_head && cmp(Get_key::key_of(new_node), Get_key::key_of(N(s))))
481 r = p = s->_md.right;
484 /* adj balance factors down to the new node */
487 if (cmp(Get_key::key_of(new_node), Get_key::key_of(N(p))))
502 /* tree has grown higher */
505 return cxx::pair(Iterator(N(new_node), N(new_node)), 0);
508 if (s->_md.balance == -a)
510 /* node s got balanced (shorter subtree of s has grown) */
512 return cxx::pair(Iterator(N(new_node), N(new_node)), 0);
515 /* tree got out of balance */
516 if (r->_md.balance == a)
518 /* single rotation */
525 /* set new balance factors */
531 /* double rotation */
545 /* set new balance factors */
546 p->adj_balance(r, s, a);
549 /* set new subtree head */
550 if (s == t->_md.left)
556 return cxx::pair(Iterator(N(new_node), N(new_node)), 0);
559 /* find an element */
560 template< typename Node, typename Get_key, class Compare, bool Const_nodes>
562 Node *Avl_tree<Node, Get_key, Compare, Const_nodes>::find_node(Key_param_type key) const
564 Avl_tree_node *q = _head._md.right;
569 if (cmp(key, Get_key::key_of(N(q))))
571 else if (cmp(Get_key::key_of(N(q)), key))
579 /* find an element */
580 template< typename Node, typename Get_key, class Compare, bool Const_nodes>
582 typename Avl_tree<Node, Get_key, Compare, Const_nodes>::Const_iterator
583 Avl_tree<Node, Get_key, Compare, Const_nodes>::find(Key_param_type key) const
585 Avl_tree_node *q = _head._md.right;
586 Avl_tree_node *r = q;
591 if (cmp(key, Get_key::key_of(N(q))))
593 else if (cmp(Get_key::key_of(N(q)), key))
601 return Iterator(N(q), N(r));
607 /* remove an element */
608 template< typename Node, typename Get_key, class Compare, bool Const_nodes>
610 Node *Avl_tree<Node, Get_key, Compare, Const_nodes>::remove(Key_param_type key)
612 Avl_tree_node *q = _head._md.right; /* search variable */
613 Avl_tree_node *p = &_head; /* parent node of q */
614 Avl_tree_node *r; /* 'symetric predecessor' of q, subtree to rotate
615 * while rebalancing */
616 Avl_tree_node *s = &_head; /* last ('deepest') node on the search path to q
617 * with balance 0, at this place the rebalancing
618 * stops in any case */
619 Avl_tree_node *t = 0; /* parent node of p */
624 /***************************************************************************
625 * search node with item == k, on the way down also search for the last
626 * ('deepest') node with balance zero, this is the last node where
627 * rebalancing might be necessary.
628 ***************************************************************************/
631 if (!cmp(key, Get_key::key_of(N(q))) && !cmp(Get_key::key_of(N(q)), key))
640 if (cmp(key, Get_key::key_of(N(p))))
642 else if (cmp(Get_key::key_of(N(p)), key))
651 /***************************************************************************
653 ***************************************************************************/
654 if (q->_md.left && q->_md.right)
656 /* replace q with its 'symetric predecessor' (the node with the largest
657 * item in the left subtree of q, its the rightmost item in this subtree) */
661 Avl_tree_node *p2 = p;
668 if (r->_md.balance == 0)
676 /* found, replace q */
679 Avl_tree_node::swap(q,r);
680 p2->replace_child(q, r);
684 p->replace_child(r, q);
692 if (!(t->_md.left == p || t->_md.right == p))
693 enter_kdebug("dumb 1");
695 if (!(p->_md.left == q || p->_md.right == q))
696 enter_kdebug("dumb 2");
700 if (q == _head._md.right)
702 /* remove tree head */
703 if (!q->_md.left && !q->_md.right)
712 _head._md.right = q->_md.right;
714 _head._md.right = q->_md.left;
722 /* q is not the tree head */
723 int a; /* changes of the balance factor, -1 right subtree got
724 * shorter, +1 left subtree got shorter */
726 if (q == p->_md.right)
729 p->_md.right = q->_md.left;
730 else if (q->_md.right)
731 p->_md.right = q->_md.right;
735 /* right subtree of p got shorter */
741 p->_md.left = q->_md.left;
742 else if (q->_md.right)
743 p->_md.left = q->_md.right;
747 /* left subtree of p got shorter */
752 /***********************************************************************
754 * q is the removed node
755 * p points to the node which must be rebalanced,
756 * t points to the parent node of p
757 * s points to the last node with balance 0 on the way down to p
758 ***********************************************************************/
760 Avl_tree_node *o; /* subtree while rebalancing */
761 bool done = false; /* done with rebalancing */
767 /***************************************************************
768 * left subtree of p got shorter
769 ***************************************************************/
770 if (p->_md.balance == -1)
771 /* p got balanced => the whole tree with head p got shorter,
772 * must rebalance parent node of p (a.1.) */
774 else if (p->_md.balance == 0)
776 /* p got out of balance, but kept its overall height
783 /* left subtree of p was already shorter than right,
789 /* single rotation left and done (a.3.1) */
794 t->replace_child(p, r);
798 else if (r->_md.balance == +1)
800 /* single rotation left and rebalance parent node
806 t->replace_child(p, r);
812 /* double rotation right - left and rebalance parent
817 t->replace_child(p, o);
818 o->adj_balance(p, r);
826 /***************************************************************
827 * right subtree of p got shorter
828 ***************************************************************/
829 if (p->_md.balance == +1)
830 /* p got balanced, => the whole tree with head p got
831 * shorter, must rebalance parent node of p (b.1.) */
833 else if (p->_md.balance == 0)
835 /* p got out of balance, but kept its overall height
842 /* the right subtree of p already was shorter than the left,
843 * need to rotate to rebuild the AVL tree */
846 if (r->_md.balance == 0)
848 /* single rotation right and done (b.3.1) */
853 t->replace_child(p, r);
857 else if (r->_md.balance == -1)
859 /* single rotation right and rebalance parent
865 t->replace_child(p, r);
870 /* double rotation left - right and rebalance parent
875 t->replace_child(p, o);
876 o->adj_balance(r, p);
884 /* need to rebalance parent node, go one level up in the tree.
885 * Actually, we go down the tree until we find p and store its
886 * parent and the parent of the parent. We start at the last
887 * node with balance 0, because the rebalancing definitely
890 * t points to the node which must be rebalanced, p to the
891 * subtree of t which got shorter */
898 /* whole tree got shorter */
904 /* reached the last node which needs to be rebalanced */
906 if (p->_md.left == q)
907 /* left subtree got shorter */
909 else if (p->_md.right == q)
910 /* right subtree got shorter */
913 return (Node*)-E_inval;
925 while (p && (p != r))
928 if (cmp(Get_key::key_of(N(q)), Get_key::key_of(N(p))))
934 if (!p) enter_kdebug("dd");
936 if (p->_md.left == q)
937 /* left subtree got shorter */
939 else if (p->_md.right == q)
940 /* right subtree got shorter */
943 return (Node*)-E_inval;