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