1// vi:set ft=cpp: -*- Mode: C++ -*-
2/**
3 * \file
4 * \brief AVL set
5 */
6/*
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)
10 *
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.
14 *
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.
23 */
24
25#pragma once
26
27#include <l4/cxx/std_alloc>
28#include <l4/cxx/std_ops>
29#include <l4/cxx/type_traits>
30#include <l4/cxx/avl_tree>
31
32namespace cxx {
33namespace Bits {
34/**
35 * \internal
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 Key the type of the item stored in a node.
40 * \param Node_op the type used to determine the direction of the iterator.
41 */
42template< typename Node, typename Key, typename Node_op >
43class Avl_set_iter : public __Bst_iter_b<Node, Node_op>
44{
45private:
46  /// Super-class type
47  typedef __Bst_iter_b<Node, Node_op> Base;
48
49  /// our non-const key type
50  typedef typename Type_traits<Key>::Non_const_type Non_const_key;
51
52  /// our non-const iterator type
53  typedef Avl_set_iter<Node, Non_const_key, Node_op> Non_const_iter;
54
55  using Base::_n;
56  using Base::_r;
57  using Base::inc;
58
59public:
60  /// Create an invalid iterator (end marker)
61  Avl_set_iter() = default;
62
63  /**
64   * Create an iterator for the given tree.
65   * \param t the root node of the tree to iterate.
66   */
67  Avl_set_iter(Node const *t) : Base(t) {}
68
69  /**
70   * Create an iterator from a BST iterator.
71   * \prarm o  The BST iterator that shall be copied.
72   */
73  Avl_set_iter(Base const &o) : Base(o) {}
74
75  /// Allow copy of non-const iterator to const iterator versions.
76  Avl_set_iter(Non_const_iter const &o)
77  : Base(o) {}
78
79  /// Allow assignment of non-const iterator to const iterator versions.
80  Avl_set_iter &operator = (Non_const_iter const &o)
81  { Base::operator = (o); return *this; }
82
83  /**
84   * \brief Dereference the iterator and get the item out of the tree.
85   * \return A reference to the data stored in the AVL tree.
86   */
87  Key &operator * () const { return const_cast<Node*>(_n)->item; }
88  /**
89   * \brief Member access to the item the iterator points to.
90   * \return A pointer to the item in the node.
91   */
92  Key *operator -> () const { return &const_cast<Node*>(_n)->item; }
93  /**
94   * \brief Set the iterator to the next element (pre increment).
95   */
96  Avl_set_iter &operator ++ () { inc(); return *this; }
97  /**
98   * \brief Set the iterator to the next element (post increment).
99   */
100  Avl_set_iter operator ++ (int)
101  { Avl_set_iter tmp = *this; inc(); return tmp; }
102
103};
104
105/// Internal, key-getter for Avl_set nodes.
106template<typename KEY_TYPE>
107struct Avl_set_get_key
108{
109  typedef KEY_TYPE Key_type;
110  template<typename NODE>
111  static Key_type const &key_of(NODE const *n)
112  { return n->item; }
113};
114
115
116/**
117 * Internal: AVL set with internally managed nodes.
118 *
119 * Use Avl_set, Avl_map, or Avl_tree in applications.
120 *
121 * \tparam ITEM_TYPE  The type of the items to be stored in the set.
122 * \tparam COMPARE    The relation to define the partial order, default is
123 *                    to use operator '<'.
124 * \tparam ALLOC      The allocator to use for the nodes of the AVL set.
125 * \tparam GET_KEY    Sort-key getter (must provide the `Key_type` and
126 *                    sort-key for an item (of `ITEM_TYPE`).
127 */
128template< typename ITEM_TYPE, class COMPARE,
129          template<typename A> class ALLOC,
130          typename GET_KEY>
131class Base_avl_set
132{
133public:
134  /**
135   * Return status constants.
136   *
137   * These constants are compatible with the L4 error codes, see
138   * #l4_error_code_t.
139   */
140  enum
141  {
142    E_noent =  2, ///< Item does not exist.
143    E_exist = 17, ///< Item exists already.
144    E_nomem = 12, ///< Memory allocation failed.
145    E_inval = 22  ///< Internal error.
146  };
147  /// Type for the items store in the set
148  typedef ITEM_TYPE Item_type;
149  /// Key-getter type to derive the sort key of an internal node.
150  typedef GET_KEY Get_key;
151  /// Type of the sort key used for the items
152  typedef typename GET_KEY::Key_type Key_type;
153  /// Type used for const items within the set
154  typedef typename Type_traits<Item_type>::Const_type Const_item_type;
155  /// Type for the comparison functor.
156  typedef COMPARE Item_compare;
157
158private:
159  /// Internal representation of a tree node.
160  class _Node : public Avl_tree_node
161  {
162  public:
163    /// The actual item stored in the node.
164    Item_type  item;
165
166    _Node() = default;
167
168    _Node(Item_type const &item) : Avl_tree_node(), item(item) {}
169  };
170
171public:
172  /**
173   * \brief A smart pointer to a tree item.
174   */
175  class Node
176  {
177  private:
178    struct No_type;
179    friend class Base_avl_set<ITEM_TYPE, COMPARE, ALLOC, GET_KEY>;
180    _Node const *_n;
181    explicit Node(_Node const *n) : _n(n) {}
182
183  public:
184    /// Default construction for NIL pointer.
185    Node() : _n(0) {}
186
187    /**
188     *  Dereference the pointer.
189     *
190     *  \pre Node is valid.
191     */
192    Item_type const &operator * () { return _n->item; }
193    /**
194     *  Dereferenced member access.
195     *
196     *  \pre Node is valid.
197     */
198    Item_type const *operator -> () { return &_n->item; }
199
200    /**
201     * \brief Validity check.
202     * \return false if the pointer is NIL, true if valid.
203     */
204    bool valid() const { return _n; }
205
206    /// Cast to a real item pointer.
207    operator Item_type const * () { if (_n) return &_n->item; else return 0; }
208  };
209
210  /// Type for the node allocator.
211  typedef ALLOC<_Node> Node_allocator;
212
213private:
214  typedef Avl_tree<_Node, GET_KEY, COMPARE> Tree;
215  Tree _tree;
216  /// The allocator for new nodes
217  Node_allocator _alloc;
218
219  Base_avl_set &operator = (Base_avl_set const &) = delete;
220
221  typedef typename Tree::Fwd_iter_ops Fwd;
222  typedef typename Tree::Rev_iter_ops Rev;
223
224public:
225  typedef typename Type_traits<Item_type>::Param_type Item_param_type;
226
227  /// Forward iterator for the set.
228  typedef Avl_set_iter<_Node, Item_type, Fwd> Iterator;
229  typedef Iterator iterator;
230  /// Constant forward iterator for the set.
231  typedef Avl_set_iter<_Node, Const_item_type, Fwd> Const_iterator;
232  typedef Const_iterator const_iterator;
233  /// Backward iterator for the set.
234  typedef Avl_set_iter<_Node, Item_type, Rev> Rev_iterator;
235  typedef Rev_iterator reverse_iterator;
236  /// Constant backward iterator for the set.
237  typedef Avl_set_iter<_Node, Const_item_type, Rev> Const_rev_iterator;
238  typedef Const_rev_iterator const_reverse_iterator;
239
240  /**
241   * \brief Create a AVL-tree based set.
242   * \param alloc Node allocator.
243   *
244   * Create an empty set (AVL-tree based).
245   */
246  explicit Base_avl_set(Node_allocator const &alloc = Node_allocator())
247  : _tree(), _alloc(alloc)
248  {}
249
250  ~Base_avl_set()
251  {
252    _tree.remove_all([this](_Node *n)
253                     {
254                       n->~_Node();
255                       _alloc.free(n);
256                     });
257  }
258
259  /**
260   * Create a copy of an AVL-tree based set.
261   *
262   * \param o  The set to copy.
263   *
264   * Creates a deep copy of the set with all its items.
265   */
266  inline Base_avl_set(Base_avl_set const &o);
267
268  /**
269   * Insert an item into the set.
270   *
271   * \param item  The item to insert.
272   *
273   * \return A pair of iterator (`first`) and return value (`second`).
274   *         `second` will be 0 if the element was inserted into the set
275   *         and `-#E_exist` if the element was already in the set and
276   *         the set was therefore not updated.
277   *         In both cases, `first` contains an iterator that points to
278   *         the element.
279   *         `second` may also be `-#E_nomem` when memory for the node
280   *         could not be allocated. `first` is then invalid.
281   *
282   * Insert a new item into the set, each item can only be once in
283   * the set.
284   */
285  cxx::Pair<Iterator, int> insert(Item_type const &item);
286
287  /**
288   * Remove an item from the set.
289   *
290   * \param item  The item to remove.
291   *
292   * \retval 0         Success
293   * \retval -E_noent  Item does not exist
294   * \retval -E_inval  Internal error
295   */
296  int remove(Key_type const &item)
297  {
298    _Node *n = _tree.remove(item);
299    if ((long)n == -E_inval)
300      return -E_inval;
301
302    if (n)
303      {
304        n->~_Node();
305	_alloc.free(n);
306	return 0;
307      }
308
309    return -E_noent;
310  }
311
312  /**
313   * Erase the item with the given key.
314   * \param item  The key of the item to remove.
315   */
316  int erase(Key_type const &item)
317  { return remove(item); }
318
319  /**
320   * Lookup a node equal to `item`.
321   *
322   * \param item  The value to search for.
323   *
324   * \return A smart pointer to the element found.
325   *         If no element was found the smart pointer will be invalid.
326   */
327  Node find_node(Key_type const &item) const
328  { return Node(_tree.find_node(item)); }
329
330  /**
331   * Find the first node greater or equal to `key`.
332   *
333   * \param key  Minimum key to look for.
334   *
335   * \return Smart pointer to the first node greater or equal to `key`.
336   *         Will be invalid if no such element was found.
337   */
338  Node lower_bound_node(Key_type const &key) const
339  { return Node(_tree.lower_bound_node(key)); }
340
341  Node lower_bound_node(Key_type &&key) const
342  { return Node(_tree.lower_bound_node(key)); }
343
344  /**
345   * \brief Get the constant forward iterator for the first element in the set.
346   * \return Constant forward iterator for the first element in the set.
347   */
348  Const_iterator begin() const { return _tree.begin(); }
349  /**
350   * \brief Get the end marker for the constant forward iterator.
351   * \return The end marker for the constant forward iterator.
352   */
353  Const_iterator end() const   { return _tree.end(); }
354
355  /**
356   * \brief Get the mutable forward iterator for the first element of the set.
357   * \return The mutable forward iterator for the first element of the set.
358   */
359  Iterator begin() { return _tree.begin(); }
360  /**
361   * \brief Get the end marker for the mutable forward iterator.
362   * \return The end marker for mutable forward iterator.
363   */
364  Iterator end()   { return _tree.end(); }
365
366  /**
367   * \brief Get the constant backward iterator for the last element in the set.
368   * \return The constant backward iterator for the last element in the set.
369   */
370  Const_rev_iterator rbegin() const { return _tree.rbegin(); }
371  /**
372   * \brief Get the end marker for the constant backward iterator.
373   * \return The end marker for the constant backward iterator.
374   */
375  Const_rev_iterator rend() const   { return _tree.rend(); }
376
377  /**
378   * \brief Get the mutable backward iterator for the last element of the set.
379   * \return The mutable backward iterator for the last element of the set.
380   */
381  Rev_iterator rbegin() { return _tree.rbegin(); }
382  /**
383   * \brief Get the end marker for the mutable backward iterator.
384   * \return The end marker for mutable backward iterator.
385   */
386  Rev_iterator rend()   { return _tree.rend(); }
387
388  Const_iterator find(Key_type const &item) const
389  { return _tree.find(item); }
390};
391
392
393//----------------------------------------------------------------------------
394/* Implementation of AVL Tree */
395
396/* Create a copy */
397template< typename Item, class Compare, template<typename A> class Alloc, typename KEY_TYPE>
398Base_avl_set<Item,Compare,Alloc,KEY_TYPE>::Base_avl_set(Base_avl_set const &o)
399  : _tree(), _alloc(o._alloc)
400{
401  for (Const_iterator i = o.begin(); i != o.end(); ++i)
402    insert(*i);
403}
404
405/* Insert new _Node. */
406template< typename Item, class Compare, template< typename A > class Alloc, typename KEY_TYPE>
407Pair<typename Base_avl_set<Item,Compare,Alloc,KEY_TYPE>::Iterator, int>
408Base_avl_set<Item,Compare,Alloc,KEY_TYPE>::insert(Item const &item)
409{
410  _Node *n = _alloc.alloc();
411  if (!n)
412    return cxx::pair(end(), -E_nomem);
413
414  new (n, Nothrow()) _Node(item);
415  Pair<_Node *, bool> err = _tree.insert(n);
416  if (!err.second)
417    {
418      n->~_Node();
419      _alloc.free(n);
420    }
421
422  return cxx::pair(Iterator(typename Tree::Iterator(err.first, err.first)), err.second ? 0 : -E_exist);
423}
424
425} // namespace Bits
426
427/**
428 * \brief AVL set for simple compareable items.
429 *
430 * The AVL set can store any kind of items where a partial order is defined.
431 * The default relation is defined by the '<' operator.
432 *
433 * \tparam ITEM_TYPE  The type of the items to be stored in the set.
434 * \tparam COMPARE    The relation to define the partial order, default is
435 *                    to use operator '<'.
436 * \tparam ALLOC      The allocator to use for the nodes of the AVL set.
437 */
438template< typename ITEM_TYPE, class COMPARE = Lt_functor<ITEM_TYPE>,
439          template<typename A> class ALLOC = New_allocator>
440class Avl_set :
441  public Bits::Base_avl_set<ITEM_TYPE, COMPARE, ALLOC,
442                            Bits::Avl_set_get_key<ITEM_TYPE> >
443{
444private:
445  typedef Bits::Base_avl_set<ITEM_TYPE, COMPARE, ALLOC,
446                             Bits::Avl_set_get_key<ITEM_TYPE> > Base;
447
448public:
449  typedef typename Base::Node_allocator Node_allocator;
450  Avl_set() = default;
451  Avl_set(Node_allocator const &alloc)
452  : Base(alloc)
453  {}
454};
455
456} // namespace cxx
457