7 * (c) 2008-2009 Technische Universität Dresden
8 * This file is part of TUD:OS and distributed under the terms of the
9 * GNU General Public License 2.
10 * Please see the COPYING-GPL-2 file for details.
12 * As a special exception, you may use this file as part of a free software
13 * library without restriction. Specifically, if other files instantiate
14 * templates or use macros or inline functions from this file, or you compile
15 * this file and link it with other files to produce an executable, this
16 * file does not by itself cause the resulting executable to be covered by
17 * the GNU General Public License. This exception does not however
18 * invalidate any other reasons why the executable file might be covered by
19 * the GNU General Public License.
24 #include <l4/cxx/std_ops>
25 #include <l4/cxx/pair>
26 #include <l4/cxx/type_traits>
33 * \brief Generic iterator for the AVL-tree based set.
34 * \param Cmp the type of the comparison functor.
35 * \param Node the type of a node.
36 * \param Node_op the type used to determine the direction of the iterator.
38 template< typename Node, typename Node_op >
39 class __Avl_tree_iter_b
42 Node const *_n; ///< Current node
43 Node const *_r; ///< Root node of current subtree
45 /// Create an invalid iterator, used as end marker.
46 __Avl_tree_iter_b() : _n(0), _r(0) {}
49 * \brief Create an iterator for the given AVL tree.
50 * \param t the root node of the tree to iterate.
51 * \param cmp the comparison functor for tree elements.
53 __Avl_tree_iter_b(Node const *t)
57 __Avl_tree_iter_b(Node const *t, Node const *r)
61 /// traverse the subtree down to the leftmost/rightmost leave.
62 inline void _downmost();
64 /// Increment to the next element.
68 /// Check two iterators for equality.
69 bool operator == (__Avl_tree_iter_b const &o) const { return _n == o._n; }
70 /// Check two iterators for non equality.
71 bool operator != (__Avl_tree_iter_b const &o) const { return _n != o._n; }
77 * \brief Generic iterator for the AVL-tree based set.
78 * \param Node the type of a node.
79 * \param Node_type the type of the node to return stored in a node.
80 * \param Node_op the type used to determine the direction of the iterator.
82 template< typename Node, typename Node_type, typename Node_op >
83 class __Avl_tree_iter : public __Avl_tree_iter_b<Node, Node_op>
87 typedef __Avl_tree_iter_b<Node, Node_op> Base;
94 /// Create an invalid iterator (end marker)
98 * \brief Create an iterator for the given tree.
99 * \param t the root node of the tree to iterate.
100 * \param cmp the conmparison functor for tree elements.
102 __Avl_tree_iter(Node const *t) : Base(t) {}
103 __Avl_tree_iter(Node const *t, Node const *r) : Base(t, r) {}
105 // template<typename Key2>
106 __Avl_tree_iter(Base const &o) : Base(o) {}
109 * \brief Dereference the iterator and get the item out of the tree.
110 * \return A reference to the data stored in the AVL tree.
112 Node_type &operator * () const { return *const_cast<Node *>(_n); }
114 * \brief Member access to the item the iterator points to.
115 * \return A pointer to the item in the node.
117 Node_type *operator -> () const { return const_cast<Node *>(_n); }
119 * \brief Set the iterator to the next element (pre increment).
121 __Avl_tree_iter &operator ++ () { inc(); return *this; }
123 * \brief Set the iterator to the next element (post increment).
125 __Avl_tree_iter &operator ++ (int)
126 { __Avl_tree_iter tmp = *this; inc(); return tmp; }
133 template< typename Node, typename Get_key, typename Compare, bool Const_nodes >
134 friend class Avl_tree;
138 Avl_tree_node *right;
139 unsigned short flags;
141 Md() : left(0), right(0), flags(0), balance(0) {}
145 Avl_tree_node() : _md() {}
147 void operator = (Avl_tree_node const &)
152 Avl_tree_node(Avl_tree_node const &o);
154 /// Adjust balance value
155 inline void adj_balance(Avl_tree_node *b, Avl_tree_node *c, int v = -1);
156 /// Replace the child \a c with \a repl.
157 inline void replace_child(Avl_tree_node *c, Avl_tree_node *repl);
159 /// Right rotation of this node.
160 void r_rotate(Avl_tree_node *r)
161 { _md.left = r->_md.right; r->_md.right = this; }
163 /// Left rotation of this node.
164 void l_rotate(Avl_tree_node *r)
165 { _md.right = r->_md.left; r->_md.left = this; }
167 static void swap(Avl_tree_node *a, Avl_tree_node *b)
168 { Md tmp = a->_md; a->_md = b->_md; b->_md = tmp; }
172 template< typename Node, typename Get_key,
173 typename Compare = Lt_functor<typename Get_key::Key_type>,
174 bool Const_nodes = true >
187 /// Current height of the tree.
188 unsigned long _height;
189 /// Head node of the tree, the root is \a _head.right.
192 /// Ops for forward iterators
195 static Node *child1(Node const *n) { return N(n->_md.left); }
196 static Node *child2(Node const *n) { return N(n->_md.right); }
197 static bool cmp(Node const *l, Node const *r)
198 { return Compare()(Get_key::key_of(l), Get_key::key_of(r)); }
201 /// Ops for Reverse iterators
204 static Node *child1(Node const *n) { return N(n->_md.right); }
205 static Node *child2(Node const *n) { return N(n->_md.left); }
206 static bool cmp(Node const *l, Node const *r)
207 { return Compare()(Get_key::key_of(r), Get_key::key_of(l)); }
210 Avl_tree(Avl_tree const &o);
213 typedef typename Get_key::Key_type Key_type;
214 typedef typename Type_traits<Key_type>::Param_type Key_param_type;
216 typedef Rev Rev_iter_ops;
217 typedef Fwd Fwd_iter_ops;
218 /// Forward iterator for the set.
219 typedef __Avl_tree_iter<Node, Node, Fwd> Iterator;
220 typedef Iterator iterator;
221 /// Constant forward iterator for the set.
222 typedef __Avl_tree_iter<Node, Node const, Fwd> Const_iterator;
223 typedef Const_iterator const_iterator;
224 /// Backward iterator for the set.
225 typedef __Avl_tree_iter<Node, Node, Rev> Rev_iterator;
226 typedef Rev_iterator reverse_iterator;
227 /// Constant backward iterator for the set.
228 typedef __Avl_tree_iter<Node, Node const, Rev> Const_rev_iterator;
229 typedef Const_rev_iterator const_reverse_iterator;
231 Avl_tree() : _height(0) {}
232 cxx::Pair<Iterator, int> insert(Node *new_node);
235 * \brief Remove an item from the set.
236 * \param key The item to remove.
237 * \return 0 on success, -3 if the item does not exist, and
238 * -4 on internal error.
240 Node *remove(Key_param_type key);
241 Node *erase(Key_param_type key) { return remove(key); }
244 * \brief Lookup a node equal to \a key.
245 * \param key The value to search for.
246 * \return A smart pointer to the element found, if no element found the
249 Node *find_node(Key_param_type key) const;
251 /// Destroy, and free the set.
254 Avl_tree_node const *n;
255 while ((n = _head._md.right))
256 remove(Get_key::key_of(N(n)));
260 * \brief Get the constant forward iterator for the first element in the set.
261 * \return Constant forward iterator for the first element in the set.
263 Const_iterator begin() const { return Const_iterator(N(_head._md.right)); }
265 * \brief Get the end marker for the constant forward iterator.
266 * \return The end marker for the constant forward iterator.
268 Const_iterator end() const { return Const_iterator(); }
271 * \brief Get the mutable forward iterator for the first element of the set.
272 * \return The mutable forward iterator for the first element of the set.
274 Iterator begin() { return Iterator(N(_head._md.right)); }
276 * \brief Get the end marker for the mutable forward iterator.
277 * \return The end marker for mutable forward iterator.
279 Iterator end() { return Iterator(); }
282 * \brief Get the constant backward iterator for the last element in the set.
283 * \return The constant backward iterator for the last element in the set.
285 Const_rev_iterator rbegin() const { return Const_rev_iterator(N(_head._md.right)); }
287 * \brief Get the end marker for the constant backward iterator.
288 * \return The end marker for the constant backward iterator.
290 Const_rev_iterator rend() const { return Const_rev_iterator(); }
293 * \brief Get the mutable backward iterator for the last element of the set.
294 * \return The mutable backward iterator for the last element of the set.
296 Rev_iterator rbegin() { return Rev_iterator(N(_head._md.right)); }
298 * \brief Get the end marker for the mutable backward iterator.
299 * \return The end marker for mutable backward iterator.
301 Rev_iterator rend() { return Rev_iterator(); }
303 Const_iterator find(Key_param_type key) const;
306 static Node *N(Avl_tree_node *n) { return static_cast<Node*>(n); }
307 static Node const *N(Avl_tree_node const *n) { return static_cast<Node const *>(n); }
312 //----------------------------------------------------------------------------
313 /* IMPLEMENTATION: __Avl_tree_iter_b */
315 template< typename Node, typename Node_op>
317 void __Avl_tree_iter_b<Node, Node_op>::_downmost()
321 if (Node_op::child1(_n))
322 _n = Node_op::child1(_n);
328 template< typename Node, typename Node_op>
329 void __Avl_tree_iter_b<Node, Node_op>::inc()
336 _r = _n = Node_op::child2(_r);
341 if (Node_op::child2(_n))
343 _n = Node_op::child2(_n);
352 if (Node_op::cmp(_n, q))
355 q = Node_op::child1(q);
357 else if (_n == q || Node_op::child2(q) == _n)
363 q = Node_op::child2(q);
371 //----------------------------------------------------------------------------
372 /* Implementation of Avl_tree_node */
374 void Avl_tree_node::adj_balance(Avl_tree_node *b, Avl_tree_node *c, int v)
376 if (_md.balance == 0)
381 else if (_md.balance == v)
394 /* Replace left or right child dependent on comparison. */
396 void Avl_tree_node::replace_child(Avl_tree_node *c, Avl_tree_node *repl)
405 //----------------------------------------------------------------------------
406 /* Implementation of AVL Tree */
408 /* Insert new _Node. */
409 template< typename Node, typename Get_key, class Compare, bool Const_nodes>
410 cxx::Pair<typename Avl_tree<Node, Get_key, Compare, Const_nodes>::Iterator, int>
411 Avl_tree<Node, Get_key, Compare, Const_nodes>::insert(Node *new_node)
413 if (!_head._md.right)
416 _head._md.right = new_node;
422 Avl_tree_node *p = _head._md.right; /* search variable */
423 Avl_tree_node *q = 0; /* new node */
424 Avl_tree_node *r; /* search variable (balancing) */
425 Avl_tree_node *s = _head._md.right; /* node where rebalancing may occur */
426 Avl_tree_node *t = &_head; /* parent of s */
428 int a; /* which subtree of s has grown -1 left ... */
431 if (cmp(Get_key::key_of(new_node), Get_key::key_of(N(p))))
437 /* found insert position */
439 p->_md.left = new_node;
443 else if (cmp(Get_key::key_of(N(p)), Get_key::key_of(new_node)))
449 /* found insert position */
451 p->_md.right = new_node;
456 /* item already exists */
457 return cxx::pair(end(), -E_exist);
459 /* insert position not yet found, move on */
469 /* adj balanc factors */
470 if (s != &_head && cmp(Get_key::key_of(new_node), Get_key::key_of(N(s))))
478 r = p = s->_md.right;
481 /* adj balance factors down to the new node */
484 if (cmp(Get_key::key_of(new_node), Get_key::key_of(N(p))))
499 /* tree has grown higher */
502 return cxx::pair(Iterator(N(new_node), N(new_node)), 0);
505 if (s->_md.balance == -a)
507 /* node s got balanced (shorter subtree of s has grown) */
509 return cxx::pair(Iterator(N(new_node), N(new_node)), 0);
512 /* tree got out of balance */
513 if (r->_md.balance == a)
515 /* single rotation */
522 /* set new balance factors */
528 /* double rotation */
542 /* set new balance factors */
543 p->adj_balance(r, s, a);
546 /* set new subtree head */
547 if (s == t->_md.left)
553 return cxx::pair(Iterator(N(new_node), N(new_node)), 0);
556 /* find an element */
557 template< typename Node, typename Get_key, class Compare, bool Const_nodes>
559 Node *Avl_tree<Node, Get_key, Compare, Const_nodes>::find_node(Key_param_type key) const
561 Avl_tree_node *q = _head._md.right;
566 if (cmp(key, Get_key::key_of(N(q))))
568 else if (cmp(Get_key::key_of(N(q)), key))
576 /* find an element */
577 template< typename Node, typename Get_key, class Compare, bool Const_nodes>
579 typename Avl_tree<Node, Get_key, Compare, Const_nodes>::Const_iterator
580 Avl_tree<Node, Get_key, Compare, Const_nodes>::find(Key_param_type key) const
582 Avl_tree_node *q = _head._md.right;
583 Avl_tree_node *r = q;
588 if (cmp(key, Get_key::key_of(N(q))))
590 else if (cmp(Get_key::key_of(N(q)), key))
598 return Iterator(N(q), N(r));
604 /* remove an element */
605 template< typename Node, typename Get_key, class Compare, bool Const_nodes>
607 Node *Avl_tree<Node, Get_key, Compare, Const_nodes>::remove(Key_param_type key)
609 Avl_tree_node *q = _head._md.right; /* search variable */
610 Avl_tree_node *p = &_head; /* parent node of q */
611 Avl_tree_node *r; /* 'symetric predecessor' of q, subtree to rotate
612 * while rebalancing */
613 Avl_tree_node *s = &_head; /* last ('deepest') node on the search path to q
614 * with balance 0, at this place the rebalancing
615 * stops in any case */
616 Avl_tree_node *t = 0; /* parent node of p */
621 /***************************************************************************
622 * search node with item == k, on the way down also search for the last
623 * ('deepest') node with balance zero, this is the last node where
624 * rebalancing might be necessary.
625 ***************************************************************************/
628 if (!cmp(key, Get_key::key_of(N(q))) && !cmp(Get_key::key_of(N(q)), key))
637 if (cmp(key, Get_key::key_of(N(p))))
639 else if (cmp(Get_key::key_of(N(p)), key))
648 /***************************************************************************
650 ***************************************************************************/
651 if (q->_md.left && q->_md.right)
653 /* replace q with its 'symetric predecessor' (the node with the largest
654 * item in the left subtree of q, its the rightmost item in this subtree) */
658 Avl_tree_node *p2 = p;
665 if (r->_md.balance == 0)
673 /* found, replace q */
676 Avl_tree_node::swap(q,r);
677 p2->replace_child(q, r);
681 p->replace_child(r, q);
689 if (!(t->_md.left == p || t->_md.right == p))
690 enter_kdebug("dumb 1");
692 if (!(p->_md.left == q || p->_md.right == q))
693 enter_kdebug("dumb 2");
697 if (q == _head._md.right)
699 /* remove tree head */
700 if (!q->_md.left && !q->_md.right)
709 _head._md.right = q->_md.right;
711 _head._md.right = q->_md.left;
719 /* q is not the tree head */
720 int a; /* changes of the balance factor, -1 right subtree got
721 * shorter, +1 left subtree got shorter */
723 if (q == p->_md.right)
726 p->_md.right = q->_md.left;
727 else if (q->_md.right)
728 p->_md.right = q->_md.right;
732 /* right subtree of p got shorter */
738 p->_md.left = q->_md.left;
739 else if (q->_md.right)
740 p->_md.left = q->_md.right;
744 /* left subtree of p got shorter */
749 /***********************************************************************
751 * q is the removed node
752 * p points to the node which must be rebalanced,
753 * t points to the parent node of p
754 * s points to the last node with balance 0 on the way down to p
755 ***********************************************************************/
757 Avl_tree_node *o; /* subtree while rebalancing */
758 bool done = false; /* done with rebalancing */
764 /***************************************************************
765 * left subtree of p got shorter
766 ***************************************************************/
767 if (p->_md.balance == -1)
768 /* p got balanced => the whole tree with head p got shorter,
769 * must rebalance parent node of p (a.1.) */
771 else if (p->_md.balance == 0)
773 /* p got out of balance, but kept its overall height
780 /* left subtree of p was already shorter than right,
786 /* single rotation left and done (a.3.1) */
791 t->replace_child(p, r);
795 else if (r->_md.balance == +1)
797 /* single rotation left and rebalance parent node
803 t->replace_child(p, r);
809 /* double rotation right - left and rebalance parent
814 t->replace_child(p, o);
815 o->adj_balance(p, r);
823 /***************************************************************
824 * right subtree of p got shorter
825 ***************************************************************/
826 if (p->_md.balance == +1)
827 /* p got balanced, => the whole tree with head p got
828 * shorter, must rebalance parent node of p (b.1.) */
830 else if (p->_md.balance == 0)
832 /* p got out of balance, but kept its overall height
839 /* the right subtree of p already was shorter than the left,
840 * need to rotate to rebuild the AVL tree */
843 if (r->_md.balance == 0)
845 /* single rotation right and done (b.3.1) */
850 t->replace_child(p, r);
854 else if (r->_md.balance == -1)
856 /* single rotation right and rebalance parent
862 t->replace_child(p, r);
867 /* double rotation left - right and rebalance parent
872 t->replace_child(p, o);
873 o->adj_balance(r, p);
881 /* need to rebalance parent node, go one level up in the tree.
882 * Actually, we go down the tree until we find p and store its
883 * parent and the parent of the parent. We start at the last
884 * node with balance 0, because the rebalancing definitely
887 * t points to the node which must be rebalanced, p to the
888 * subtree of t which got shorter */
895 /* whole tree got shorter */
901 /* reached the last node which needs to be rebalanced */
903 if (p->_md.left == q)
904 /* left subtree got shorter */
906 else if (p->_md.right == q)
907 /* right subtree got shorter */
910 return (Node*)-E_inval;
922 while (p && (p != r))
925 if (cmp(Get_key::key_of(N(q)), Get_key::key_of(N(p))))
931 if (!p) enter_kdebug("dd");
933 if (p->_md.left == q)
934 /* left subtree got shorter */
936 else if (p->_md.right == q)
937 /* right subtree got shorter */
940 return (Node*)-E_inval;