1 /* CO_Tree class declaration. 2 Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it> 3 Copyright (C) 2010-2016 BUGSENG srl (http://bugseng.com) 4 5 This file is part of the Parma Polyhedra Library (PPL). 6 7 The PPL is free software; you can redistribute it and/or modify it 8 under the terms of the GNU General Public License as published by the 9 Free Software Foundation; either version 3 of the License, or (at your 10 option) any later version. 11 12 The PPL is distributed in the hope that it will be useful, but WITHOUT 13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software Foundation, 19 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA. 20 21 For the most up-to-date information see the Parma Polyhedra Library 22 site: http://bugseng.com/products/ppl/ . */ 23 24 #ifndef PPL_CO_Tree_defs_hh 25 #define PPL_CO_Tree_defs_hh 1 26 27 #include "CO_Tree_types.hh" 28 29 #include "Coefficient_defs.hh" 30 #include <memory> 31 #include <cstddef> 32 33 #ifndef PPL_CO_TREE_EXTRA_DEBUG 34 #ifdef PPL_ABI_BREAKING_EXTRA_DEBUG 35 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 36 /*! 37 \brief 38 Enables extra debugging information for class CO_Tree. 39 40 \ingroup PPL_CXX_interface 41 When <CODE>PPL_CO_TREE_EXTRA_DEBUG</CODE> evaluates to <CODE>true</CODE>, 42 each CO_Tree iterator and const_iterator carries a pointer to the associated 43 tree; this enables extra consistency checks to be performed. 44 */ 45 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 46 #define PPL_CO_TREE_EXTRA_DEBUG 1 47 #else // !defined(PPL_ABI_BREAKING_EXTRA_DEBUG) 48 #define PPL_CO_TREE_EXTRA_DEBUG 0 49 #endif // !defined(PPL_ABI_BREAKING_EXTRA_DEBUG) 50 #endif // !defined(PPL_CO_TREE_EXTRA_DEBUG) 51 52 53 namespace Parma_Polyhedra_Library { 54 55 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 56 //! A cache-oblivious binary search tree of pairs. 57 /*! \ingroup PPL_CXX_interface 58 This class implements a binary search tree with keys of dimension_type type 59 and data of Coefficient type, laid out in a dynamically-sized array. 60 61 The array-based layout saves calls to new/delete (to insert \f$n\f$ elements 62 only \f$O(\log n)\f$ allocations are performed) and, more importantly, is 63 much more cache-friendly than a standard (pointer-based) tree, because the 64 elements are stored sequentially in memory (leaving some holes to allow 65 fast insertion of new elements). 66 The downside of this representation is that all iterators are invalidated 67 when an element is added or removed, because the array could have been 68 enlarged or shrunk. This is partially addressed by providing references to 69 internal end iterators that are updated when needed. 70 71 B-trees are cache-friendly too, but the cache size is fixed (usually at 72 compile-time). This raises two problems: firstly the cache size must be 73 known in advance and those data structures do not perform well with other 74 cache sizes and, secondly, even if the cache size is known, the 75 optimizations target only one level of cache. This kind of data structures 76 are called cache aware. This implementation, instead, is cache oblivious: 77 it performs well with every cache size, and thus exploits all of the 78 available caches. 79 80 Assuming \p n is the number of elements in the tree and \p B is the number 81 of (dimension_type, Coefficient) pairs that fit in a cache line, the 82 time and cache misses complexities are the following: 83 84 - Insertions/Queries/Deletions: \f$O(\log^2 n)\f$ time, 85 \f$O(\log \frac{n}{B}))\f$ cache misses. 86 - Tree traversal from begin() to end(), using an %iterator: \f$O(n)\f$ time, 87 \f$O(\frac{n}{B})\f$ cache misses. 88 - Queries with a hint: \f$O(\log k)\f$ time and \f$O(\log \frac{k}{B})\f$ 89 cache misses, where k is the distance between the given %iterator and the 90 searched element (or the position where it would have been). 91 92 The binary search tree is embedded in a (slightly bigger) complete tree, 93 that is enlarged and shrunk when needed. The complete tree is laid out 94 in an in-order DFS layout in two arrays: one for the keys and one for the 95 associated data. 96 The indexes and values are stored in different arrays to reduce 97 cache-misses during key queries. 98 99 The tree can store up to \f$(-(dimension_type)1)/100\f$ elements. 100 This limit allows faster density computations, but can be removed if needed. 101 */ 102 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 103 class CO_Tree { 104 105 public: 106 class const_iterator; 107 class iterator; 108 109 private: 110 //! This is used for node heights and depths in the tree. 111 typedef unsigned height_t; 112 113 PPL_COMPILE_TIME_CHECK(C_Integer<height_t>::max 114 >= sizeof_to_bits(sizeof(dimension_type)), 115 "height_t is too small to store depths."); 116 117 class tree_iterator; 118 119 // This must be declared here, because it is a friend of const_iterator. 120 //! Returns the index of the current element in the DFS layout of the 121 //! complete tree. 122 /*! 123 \return the index of the current element in the DFS layout of the complete 124 tree. 125 126 \param itr the iterator that points to the desired element. 127 */ 128 dimension_type dfs_index(const_iterator itr) const; 129 130 // This must be declared here, because it is a friend of iterator. 131 //! Returns the index of the current element in the DFS layout of the 132 //! complete tree. 133 /*! 134 \return the index of the current element in the DFS layout of the complete 135 tree. 136 137 \param itr the iterator that points to the desired element. 138 */ 139 dimension_type dfs_index(iterator itr) const; 140 141 public: 142 143 //! The type of the data elements associated with keys. 144 /*! 145 If this is changed, occurrences of Coefficient_zero() in the CO_Tree 146 implementation have to be replaced with constants of the correct type. 147 */ 148 typedef Coefficient data_type; 149 typedef Coefficient_traits::const_reference data_type_const_reference; 150 151 //! A const %iterator on the tree elements, ordered by key. 152 /*! 153 Iterator increment and decrement operations are \f$O(1)\f$ time. 154 These iterators are invalidated by operations that add or remove elements 155 from the tree. 156 */ 157 class const_iterator { 158 private: 159 public: 160 161 typedef std::bidirectional_iterator_tag iterator_category; 162 typedef const data_type value_type; 163 typedef std::ptrdiff_t difference_type; 164 typedef value_type* pointer; 165 typedef data_type_const_reference reference; 166 167 //! Constructs an invalid const_iterator. 168 /*! 169 This constructor takes \f$O(1)\f$ time. 170 */ 171 explicit const_iterator(); 172 173 //! Constructs an %iterator pointing to the first element of the tree. 174 /*! 175 \param tree 176 The tree that the new %iterator will point to. 177 178 This constructor takes \f$O(1)\f$ time. 179 */ 180 explicit const_iterator(const CO_Tree& tree); 181 182 //! Constructs a const_iterator pointing to the i-th node of the tree. 183 /*! 184 \param tree 185 The tree that the new %iterator will point to. 186 187 \param i 188 The index of the element in \p tree to which the %iterator will point 189 to. 190 191 The i-th node must be a node with a value or end(). 192 193 This constructor takes \f$O(1)\f$ time. 194 */ 195 const_iterator(const CO_Tree& tree, dimension_type i); 196 197 //! The copy constructor. 198 /*! 199 \param itr 200 The %iterator that will be copied. 201 202 This constructor takes \f$O(1)\f$ time. 203 */ 204 const_iterator(const const_iterator& itr); 205 206 //! Converts an iterator into a const_iterator. 207 /*! 208 \param itr 209 The iterator that will be converted into a const_iterator. 210 211 This constructor takes \f$O(1)\f$ time. 212 */ 213 const_iterator(const iterator& itr); 214 215 //! Swaps itr with *this. 216 /*! 217 \param itr 218 The %iterator that will be swapped with *this. 219 220 This method takes \f$O(1)\f$ time. 221 */ 222 void m_swap(const_iterator& itr); 223 224 //! Assigns \p itr to *this . 225 /*! 226 \param itr 227 The %iterator that will be assigned into *this. 228 229 This method takes \f$O(1)\f$ time. 230 */ 231 const_iterator& operator=(const const_iterator& itr); 232 233 //! Assigns \p itr to *this . 234 /*! 235 \param itr 236 The %iterator that will be assigned into *this. 237 238 This method takes \f$O(1)\f$ time. 239 */ 240 const_iterator& operator=(const iterator& itr); 241 242 //! Navigates to the next element. 243 /*! 244 This method takes \f$O(1)\f$ time. 245 */ 246 const_iterator& operator++(); 247 248 //! Navigates to the previous element. 249 /*! 250 This method takes \f$O(1)\f$ time. 251 */ 252 const_iterator& operator--(); 253 254 //! Navigates to the next element. 255 /*! 256 This method takes \f$O(1)\f$ time. 257 */ 258 const_iterator operator++(int); 259 260 //! Navigates to the previous element. 261 /*! 262 This method takes \f$O(1)\f$ time. 263 */ 264 const_iterator operator--(int); 265 266 //! Returns the current element. 267 data_type_const_reference operator*() const; 268 269 //! Returns the index of the element pointed to by \c *this. 270 /*! 271 \returns the index of the element pointed to by \c *this. 272 */ 273 dimension_type index() const; 274 275 //! Compares \p *this with x . 276 /*! 277 \param x 278 The %iterator that will be compared with *this. 279 */ 280 bool operator==(const const_iterator& x) const; 281 282 //! Compares \p *this with x . 283 /*! 284 \param x 285 The %iterator that will be compared with *this. 286 */ 287 bool operator!=(const const_iterator& x) const; 288 289 private: 290 //! Checks the internal invariants, in debug mode only. 291 bool OK() const; 292 293 //! A pointer to the corresponding element of the tree's indexes[] array. 294 const dimension_type* current_index; 295 296 //! A pointer to the corresponding element of the tree's data[] array. 297 const data_type* current_data; 298 299 #if PPL_CO_TREE_EXTRA_DEBUG 300 //! A pointer to the corresponding tree, used for debug purposes only. 301 const CO_Tree* tree; 302 #endif 303 304 friend dimension_type CO_Tree::dfs_index(const_iterator itr) const; 305 }; 306 307 //! An %iterator on the tree elements, ordered by key. 308 /*! 309 Iterator increment and decrement operations are \f$O(1)\f$ time. 310 These iterators are invalidated by operations that add or remove elements 311 from the tree. 312 */ 313 class iterator { 314 public: 315 316 typedef std::bidirectional_iterator_tag iterator_category; 317 typedef data_type value_type; 318 typedef std::ptrdiff_t difference_type; 319 typedef value_type* pointer; 320 typedef value_type& reference; 321 322 //! Constructs an invalid iterator. 323 /*! 324 This constructor takes \f$O(1)\f$ time. 325 */ 326 iterator(); 327 328 //! Constructs an %iterator pointing to first element of the tree. 329 /*! 330 \param tree 331 The tree to which the new %iterator will point to. 332 333 This constructor takes \f$O(1)\f$ time. 334 */ 335 explicit iterator(CO_Tree& tree); 336 337 //! Constructs an %iterator pointing to the i-th node. 338 /*! 339 \param tree 340 The tree to which the new %iterator will point to. 341 342 \param i 343 The index of the element in \p tree to which the new %iterator will 344 point to. 345 346 The i-th node must be a node with a value or end(). 347 348 This constructor takes \f$O(1)\f$ time. 349 */ 350 iterator(CO_Tree& tree, dimension_type i); 351 352 //! The constructor from a tree_iterator. 353 /*! 354 \param itr 355 The tree_iterator that will be converted into an iterator. 356 357 This is meant for use by CO_Tree only. 358 This is not private to avoid the friend declaration. 359 360 This constructor takes \f$O(1)\f$ time. 361 */ 362 explicit iterator(const tree_iterator& itr); 363 364 //! The copy constructor. 365 /*! 366 \param itr 367 The %iterator that will be copied. 368 369 This constructor takes \f$O(1)\f$ time. 370 */ 371 iterator(const iterator& itr); 372 373 //! Swaps itr with *this. 374 /*! 375 \param itr 376 The %iterator that will be swapped with *this. 377 378 This method takes \f$O(1)\f$ time. 379 */ 380 void m_swap(iterator& itr); 381 382 //! Assigns \p itr to *this . 383 /*! 384 \param itr 385 The %iterator that will be assigned into *this. 386 387 This method takes \f$O(1)\f$ time. 388 */ 389 iterator& operator=(const iterator& itr); 390 391 //! Assigns \p itr to *this . 392 /*! 393 \param itr 394 The %iterator that will be assigned into *this. 395 396 This method takes \f$O(1)\f$ time. 397 */ 398 iterator& operator=(const tree_iterator& itr); 399 400 //! Navigates to the next element in the tree. 401 /*! 402 This method takes \f$O(1)\f$ time. 403 */ 404 iterator& operator++(); 405 406 //! Navigates to the previous element in the tree. 407 /*! 408 This method takes \f$O(1)\f$ time. 409 */ 410 iterator& operator--(); 411 412 //! Navigates to the next element in the tree. 413 /*! 414 This method takes \f$O(1)\f$ time. 415 */ 416 iterator operator++(int); 417 418 //! Navigates to the previous element in the tree. 419 /*! 420 This method takes \f$O(1)\f$ time. 421 */ 422 iterator operator--(int); 423 424 //! Returns the current element. 425 data_type& operator*(); 426 427 //! Returns the current element. 428 data_type_const_reference operator*() const; 429 430 //! Returns the index of the element pointed to by \c *this. 431 /*! 432 \returns the index of the element pointed to by \c *this. 433 */ 434 dimension_type index() const; 435 436 //! Compares \p *this with x . 437 /*! 438 \param x 439 The %iterator that will be compared with *this. 440 */ 441 bool operator==(const iterator& x) const; 442 443 //! Compares \p *this with x . 444 /*! 445 \param x 446 The %iterator that will be compared with *this. 447 */ 448 bool operator!=(const iterator& x) const; 449 450 private: 451 //! Checks the internal invariants, in debug mode only. 452 bool OK() const; 453 454 //! A pointer to the corresponding element of the tree's indexes[] array. 455 const dimension_type* current_index; 456 457 //! A pointer to the corresponding element of the tree's data[] array. 458 data_type* current_data; 459 460 #if PPL_CO_TREE_EXTRA_DEBUG 461 //! A pointer to the corresponding tree, used for debug purposes only. 462 CO_Tree* tree; 463 #endif 464 465 friend const_iterator& const_iterator::operator=(const iterator&); 466 friend dimension_type CO_Tree::dfs_index(iterator itr) const; 467 }; 468 469 //! Constructs an empty tree. 470 /*! 471 This constructor takes \f$O(1)\f$ time. 472 */ 473 CO_Tree(); 474 475 //! The copy constructor. 476 /*! 477 \param y 478 The tree that will be copied. 479 480 This constructor takes \f$O(n)\f$ time. 481 */ 482 CO_Tree(const CO_Tree& y); 483 484 //! A constructor from a sequence of \p n elements. 485 /*! 486 \param i 487 An iterator that points to the first element of the sequence. 488 489 \param n 490 The number of elements in the [i, i_end) sequence. 491 492 i must be an input iterator on a sequence of data_type elements, 493 sorted by index. 494 Objects of Iterator type must have an index() method that returns the 495 index with which the element pointed to by the iterator must be inserted. 496 497 This constructor takes \f$O(n)\f$ time, so it is more efficient than 498 the construction of an empty tree followed by n insertions, that would 499 take \f$O(n*\log^2 n)\f$ time. 500 */ 501 template <typename Iterator> 502 CO_Tree(Iterator i, dimension_type n); 503 504 //! The assignment operator. 505 /*! 506 \param y 507 The tree that will be assigned to *this. 508 509 This method takes \f$O(n)\f$ time. 510 */ 511 CO_Tree& operator=(const CO_Tree& y); 512 513 //! Removes all elements from the tree. 514 /*! 515 This method takes \f$O(n)\f$ time. 516 */ 517 void clear(); 518 519 //! The destructor. 520 /*! 521 This destructor takes \f$O(n)\f$ time. 522 */ 523 ~CO_Tree(); 524 525 //! Returns \p true if the tree has no elements. 526 /*! 527 This method takes \f$O(1)\f$ time. 528 */ 529 bool empty() const; 530 531 //! Returns the number of elements stored in the tree. 532 /*! 533 This method takes \f$O(1)\f$ time. 534 */ 535 dimension_type size() const; 536 537 //! Returns the size() of the largest possible CO_Tree. 538 static dimension_type max_size(); 539 540 //! Dumps the tree to stdout, for debugging purposes. 541 void dump_tree() const; 542 543 //! Returns the size in bytes of the memory managed by \p *this. 544 /*! 545 This method takes \f$O(n)\f$ time. 546 */ 547 dimension_type external_memory_in_bytes() const; 548 549 //! Inserts an element in the tree. 550 /*! 551 \returns 552 An %iterator that points to the inserted pair. 553 554 \param key 555 The key that will be inserted into the tree, associated with the default 556 data. 557 558 If such a pair already exists, an %iterator pointing to that pair is 559 returned. 560 561 This operation invalidates existing iterators. 562 563 This method takes \f$O(\log n)\f$ time if the element already exists, and 564 \f$O(\log^2 n)\f$ amortized time otherwise. 565 */ 566 iterator insert(dimension_type key); 567 568 //! Inserts an element in the tree. 569 /*! 570 \returns 571 An %iterator that points to the inserted element. 572 573 \param key 574 The key that will be inserted into the tree.. 575 576 \param data 577 The data that will be inserted into the tree. 578 579 If an element with the specified key already exists, its associated data 580 is set to \p data and an %iterator pointing to that pair is returned. 581 582 This operation invalidates existing iterators. 583 584 This method takes \f$O(\log n)\f$ time if the element already exists, and 585 \f$O(\log^2 n)\f$ amortized time otherwise.amortized 586 */ 587 iterator insert(dimension_type key, data_type_const_reference data); 588 589 //! Inserts an element in the tree. 590 /*! 591 \return 592 An %iterator that points to the inserted element. 593 594 \param itr 595 The %iterator used as hint 596 597 \param key 598 The key that will be inserted into the tree, associated with the default 599 data. 600 601 This will be faster if \p itr points near to the place where the new 602 element will be inserted (or where is already stored). 603 However, the value of \p itr does not affect the result of this 604 method, as long it is a valid %iterator for this tree. \p itr may even be 605 end(). 606 607 If an element with the specified key already exists, an %iterator pointing 608 to that pair is returned. 609 610 This operation invalidates existing iterators. 611 612 This method takes \f$O(\log n)\f$ time if the element already exists, and 613 \f$O(\log^2 n)\f$ amortized time otherwise. 614 */ 615 iterator insert(iterator itr, dimension_type key); 616 617 //! Inserts an element in the tree. 618 /*! 619 \return 620 An iterator that points to the inserted element. 621 622 \param itr 623 The iterator used as hint 624 625 \param key 626 The key that will be inserted into the tree. 627 628 \param data 629 The data that will be inserted into the tree. 630 631 This will be faster if \p itr points near to the place where the new 632 element will be inserted (or where is already stored). 633 However, the value of \p itr does not affect the result of this 634 method, as long it is a valid iterator for this tree. \p itr may even be 635 end(). 636 637 If an element with the specified key already exists, its associated data 638 is set to \p data and an iterator pointing to that pair is returned. 639 640 This operation invalidates existing iterators. 641 642 This method takes \f$O(\log n)\f$ time if the element already exists, 643 and \f$O(\log^2 n)\f$ amortized time otherwise. 644 */ 645 iterator insert(iterator itr, dimension_type key, 646 data_type_const_reference data); 647 648 //! Erases the element with key \p key from the tree. 649 /*! 650 This operation invalidates existing iterators. 651 652 \returns an iterator to the next element (or end() if there are no 653 elements with key greater than \p key ). 654 655 \param key 656 The key of the element that will be erased from the tree. 657 658 This method takes \f$O(\log n)\f$ time if the element already exists, 659 and \f$O(\log^2 n)\f$ amortized time otherwise. 660 */ 661 iterator erase(dimension_type key); 662 663 //! Erases the element pointed to by \p itr from the tree. 664 /*! 665 This operation invalidates existing iterators. 666 667 \returns an iterator to the next element (or end() if there are no 668 elements with key greater than \p key ). 669 670 \param itr 671 An iterator pointing to the element that will be erased from the tree. 672 673 This method takes \f$O(\log n)\f$ time if the element already exists, and 674 \f$O(\log^2 n)\f$ amortized time otherwise. 675 */ 676 iterator erase(iterator itr); 677 678 /*! 679 \brief Removes the element with key \p key (if it exists) and decrements 680 by 1 all elements' keys that were greater than \p key. 681 682 \param key 683 The key of the element that will be erased from the tree. 684 685 This operation invalidates existing iterators. 686 687 This method takes \f$O(k+\log^2 n)\f$ expected time, where k is the number 688 of elements with keys greater than \p key. 689 */ 690 void erase_element_and_shift_left(dimension_type key); 691 692 //! Adds \p n to all keys greater than or equal to \p key. 693 /*! 694 \param key 695 The key of the first element whose key will be increased. 696 697 \param n 698 Specifies how much the keys will be increased. 699 700 This method takes \f$O(k+\log n)\f$ expected time, where k is the number 701 of elements with keys greater than or equal to \p key. 702 */ 703 void increase_keys_from(dimension_type key, dimension_type n); 704 705 //! Sets to \p i the key of *itr. Assumes that i<=itr.index() and that there 706 //! are no elements with keys in [i,itr.index()). 707 /*! 708 All existing iterators remain valid. 709 710 This method takes \f$O(1)\f$ time. 711 */ 712 void fast_shift(dimension_type i, iterator itr); 713 714 //! Swaps x with *this. 715 /*! 716 \param x 717 The tree that will be swapped with *this. 718 719 This operation invalidates existing iterators. 720 721 This method takes \f$O(1)\f$ time. 722 */ 723 void m_swap(CO_Tree& x); 724 725 //! Returns an iterator that points at the first element. 726 /*! 727 This method takes \f$O(1)\f$ time. 728 */ 729 iterator begin(); 730 731 //! Returns an iterator that points after the last element. 732 /*! 733 This method always returns a reference to the same internal %iterator, 734 that is updated at each operation that modifies the structure. 735 Client code can keep a const reference to that %iterator instead of 736 keep updating a local %iterator. 737 738 This method takes \f$O(1)\f$ time. 739 */ 740 const iterator& end(); 741 742 //! Equivalent to cbegin(). 743 const_iterator begin() const; 744 745 //! Equivalent to cend(). 746 const const_iterator& end() const; 747 748 //! Returns a const_iterator that points at the first element. 749 /*! 750 This method takes \f$O(1)\f$ time. 751 */ 752 const_iterator cbegin() const; 753 754 //! Returns a const_iterator that points after the last element. 755 /*! 756 This method always returns a reference to the same internal %iterator, 757 that is updated at each operation that modifies the structure. 758 Client code can keep a const reference to that %iterator instead of 759 keep updating a local %iterator. 760 761 This method takes \f$O(1)\f$ time. 762 */ 763 const const_iterator& cend() const; 764 765 //! Searches an element with key \p key using bisection. 766 /*! 767 \param key 768 The key that will be searched for. 769 770 If the element is found, an %iterator pointing to that element is 771 returned; otherwise, the returned %iterator refers to the immediately 772 preceding or succeeding value. 773 If the tree is empty, end() is returned. 774 775 This method takes \f$O(\log n)\f$ time. 776 */ 777 iterator bisect(dimension_type key); 778 779 //! Searches an element with key \p key using bisection. 780 /*! 781 \param key 782 The key that will be searched for. 783 784 If the element is found, an %iterator pointing to that element is 785 returned; otherwise, the returned %iterator refers to the immediately 786 preceding or succeeding value. 787 If the tree is empty, end() is returned. 788 789 This method takes \f$O(\log n)\f$ time. 790 */ 791 const_iterator bisect(dimension_type key) const; 792 793 //! Searches an element with key \p key in [first, last] using bisection. 794 /*! 795 \param first 796 An %iterator pointing to the first element in the range. 797 It must not be end(). 798 799 \param last 800 An %iterator pointing to the last element in the range. 801 Note that this is included in the search. 802 It must not be end(). 803 804 \param key 805 The key that will be searched for. 806 807 \return 808 If the specified key is found, an %iterator pointing to that element is 809 returned; otherwise, the returned %iterator refers to the immediately 810 preceding or succeeding value. 811 If the tree is empty, end() is returned. 812 813 This method takes \f$O(\log(last - first + 1))\f$ time. 814 */ 815 iterator bisect_in(iterator first, iterator last, dimension_type key); 816 817 //! Searches an element with key \p key in [first, last] using bisection. 818 /*! 819 \param first 820 An %iterator pointing to the first element in the range. 821 It must not be end(). 822 823 \param last 824 An %iterator pointing to the last element in the range. 825 Note that this is included in the search. 826 It must not be end(). 827 828 \param key 829 The key that will be searched for. 830 831 \return 832 If the specified key is found, an %iterator pointing to that element is 833 returned; otherwise, the returned %iterator refers to the immediately 834 preceding or succeeding value. 835 If the tree is empty, end() is returned. 836 837 This method takes \f$O(\log(last - first + 1))\f$ time. 838 */ 839 const_iterator bisect_in(const_iterator first, const_iterator last, 840 dimension_type key) const; 841 842 //! Searches an element with key \p key near \p hint. 843 /*! 844 \param hint 845 An %iterator used as a hint. 846 847 \param key 848 The key that will be searched for. 849 850 If the element is found, the returned %iterator points to that element; 851 otherwise, it points to the immediately preceding or succeeding value. 852 If the tree is empty, end() is returned. 853 854 The value of \p itr does not affect the result of this method, as long it 855 is a valid %iterator for this tree. \p itr may even be end(). 856 857 This method takes \f$O(\log n)\f$ time. If the distance between the 858 returned position and \p hint is \f$O(1)\f$ it takes \f$O(1)\f$ time. 859 */ 860 iterator bisect_near(iterator hint, dimension_type key); 861 862 //! Searches an element with key \p key near \p hint. 863 /*! 864 \param hint 865 An %iterator used as a hint. 866 867 \param key 868 The key that will be searched for. 869 870 If the element is found, the returned %iterator points to that element; 871 otherwise, it points to the immediately preceding or succeeding value. 872 If the tree is empty, end() is returned. 873 874 The value of \p itr does not affect the result of this method, as long it 875 is a valid %iterator for this tree. \p itr may even be end(). 876 877 This method takes \f$O(\log n)\f$ time. If the distance between the 878 returned position and \p hint is \f$O(1)\f$ it takes \f$O(1)\f$ time. 879 */ 880 const_iterator bisect_near(const_iterator hint, dimension_type key) const; 881 882 private: 883 884 //! Searches an element with key \p key in [first, last] using bisection. 885 /*! 886 \param first 887 The index of the first element in the range. 888 It must be the index of an element with a value. 889 890 \param last 891 The index of the last element in the range. 892 It must be the index of an element with a value. 893 Note that this is included in the search. 894 895 \param key 896 The key that will be searched for. 897 898 \return 899 If the element is found, the index of that element is returned; otherwise, 900 the returned index refers to the immediately preceding or succeeding 901 value. 902 903 This method takes \f$O(\log n)\f$ time. 904 */ 905 dimension_type bisect_in(dimension_type first, dimension_type last, 906 dimension_type key) const; 907 908 //! Searches an element with key \p key near \p hint. 909 /*! 910 \param hint 911 An index used as a hint. 912 It must be the index of an element with a value. 913 914 \param key 915 The key that will be searched for. 916 917 \return 918 If the element is found, the index of that element is returned; otherwise, 919 the returned index refers to the immediately preceding or succeeding 920 value. 921 922 This uses a binary progression and then a bisection, so this method is 923 \f$O(\log n)\f$, and it is \f$O(1)\f$ if the distance between the returned 924 position and \p hint is \f$O(1)\f$. 925 926 This method takes \f$O(\log n)\f$ time. If the distance between the 927 returned position and \p hint is \f$O(1)\f$ it takes \f$O(1)\f$ time. 928 */ 929 dimension_type bisect_near(dimension_type hint, dimension_type key) const; 930 931 //! Inserts an element in the tree. 932 /*! 933 If there is already an element with key \p key in the tree, its 934 associated data is set to \p data. 935 936 This operation invalidates existing iterators. 937 938 \return 939 An %iterator that points to the inserted element. 940 941 \param key 942 The key that will be inserted into the tree. 943 944 \param data 945 The data that will be associated with \p key. 946 947 \param itr 948 It must point to the element in the tree with key \p key or, if no such 949 element exists, it must point to the node that would be his parent. 950 951 This method takes \f$O(1)\f$ time if the element already exists, and 952 \f$O(\log^2 n)\f$ amortized time otherwise. 953 */ 954 tree_iterator insert_precise(dimension_type key, 955 data_type_const_reference data, 956 tree_iterator itr); 957 958 //! Helper for \c insert_precise. 959 /*! 960 This helper method takes the same arguments as \c insert_precise, 961 but besides assuming that \p itr is a correct hint, it also assumes 962 that \p key and \p data are not in the tree; namely, a proper 963 insertion has to be done and the insertion can not invalidate \p data. 964 */ 965 tree_iterator insert_precise_aux(dimension_type key, 966 data_type_const_reference data, 967 tree_iterator itr); 968 969 //! Inserts an element in the tree. 970 /*! 971 972 \param key 973 The key that will be inserted into the tree. 974 975 \param data 976 The data that will be associated with \p key. 977 978 The tree must be empty. 979 980 This operation invalidates existing iterators. 981 982 This method takes \f$O(1)\f$ time. 983 */ 984 void insert_in_empty_tree(dimension_type key, 985 data_type_const_reference data); 986 987 //! Erases from the tree the element pointed to by \p itr . 988 /*! 989 This operation invalidates existing iterators. 990 991 \returns 992 An %iterator to the next element (or end() if there are no elements with 993 key greater than \p key ). 994 995 \param itr 996 An %iterator pointing to the element that will be erased. 997 998 This method takes \f$O(\log^2 n)\f$ amortized time. 999 */ 1000 iterator erase(tree_iterator itr); 1001 1002 //! Initializes a tree with reserved size at least \p n . 1003 /*! 1004 \param n 1005 A lower bound on the tree's desired reserved size. 1006 1007 This method takes \f$O(n)\f$ time. 1008 */ 1009 void init(dimension_type n); 1010 1011 //! Deallocates the tree's dynamic arrays. 1012 /*! 1013 After this call, the tree fields are uninitialized, so init() must be 1014 called again before using the tree. 1015 1016 This method takes \f$O(n)\f$ time. 1017 */ 1018 void destroy(); 1019 1020 //! Checks the internal invariants, but not the densities. 1021 bool structure_OK() const; 1022 1023 //! Checks the internal invariants. 1024 bool OK() const; 1025 1026 //! Returns the floor of the base-2 logarithm of \p n . 1027 /*! 1028 \param n 1029 It must be greater than zero. 1030 1031 This method takes \f$O(\log n)\f$ time. 1032 */ 1033 static unsigned integer_log2(dimension_type n); 1034 1035 //! Compares the fractions numer/denom with ratio/100. 1036 /*! 1037 \returns Returns true if the fraction numer/denom is less 1038 than the fraction ratio/100. 1039 1040 \param ratio 1041 It must be less than or equal to 100. 1042 1043 \param numer 1044 The numerator of the fraction. 1045 1046 \param denom 1047 The denominator of the fraction. 1048 1049 This method takes \f$O(1)\f$ time. 1050 */ 1051 static bool is_less_than_ratio(dimension_type numer, dimension_type denom, 1052 dimension_type ratio); 1053 1054 //! Compares the fractions numer/denom with ratio/100. 1055 /*! 1056 \returns 1057 Returns true if the fraction numer/denom is greater than the fraction 1058 ratio/100. 1059 1060 \param ratio 1061 It must be less than or equal to 100. 1062 1063 \param numer 1064 The numerator of the fraction. 1065 1066 \param denom 1067 The denominator of the fraction. 1068 1069 This method takes \f$O(1)\f$ time. 1070 */ 1071 static bool is_greater_than_ratio(dimension_type numer, dimension_type denom, 1072 dimension_type ratio); 1073 1074 //! Dumps the subtree rooted at \p itr to stdout, for debugging purposes. 1075 /*! 1076 \param itr 1077 A tree_iterator pointing to the root of the desired subtree. 1078 */ 1079 static void dump_subtree(tree_iterator itr); 1080 1081 //! Increases the tree's reserved size. 1082 /*! 1083 This is called when the density is about to exceed the maximum density 1084 (specified by max_density_percent). 1085 1086 This method takes \f$O(n)\f$ time. 1087 */ 1088 void rebuild_bigger_tree(); 1089 1090 //! Decreases the tree's reserved size. 1091 /*! 1092 This is called when the density is about to become less than the minimum 1093 allowed density (specified by min_density_percent). 1094 1095 \p reserved_size must be greater than 3 (otherwise the tree can just be 1096 cleared). 1097 1098 This method takes \f$O(n)\f$ time. 1099 */ 1100 void rebuild_smaller_tree(); 1101 1102 //! Re-initializes the cached iterators. 1103 /*! 1104 This method must be called when the indexes[] and data[] vector are 1105 reallocated. 1106 1107 This method takes \f$O(1)\f$ time. 1108 */ 1109 void refresh_cached_iterators(); 1110 1111 //! Rebalances the tree. 1112 /*! 1113 For insertions, it adds the pair (key, value) in the process. 1114 1115 This operation invalidates existing iterators that point to nodes in the 1116 rebalanced subtree. 1117 1118 \returns an %iterator pointing to the root of the subtree that was 1119 rebalanced. 1120 1121 \param itr 1122 It points to the node where the new element has to be inserted or where an 1123 element has just been deleted. 1124 1125 \param key 1126 The index that will be inserted in the tree (for insertions only). 1127 1128 \param value 1129 The value that will be inserted in the tree (for insertions only). 1130 1131 This method takes \f$O(\log^2 n)\f$ amortized time. 1132 */ 1133 tree_iterator rebalance(tree_iterator itr, dimension_type key, 1134 data_type_const_reference value); 1135 1136 //! Moves all elements of a subtree to the rightmost end. 1137 /*! 1138 \returns 1139 The index of the rightmost unused node in the subtree after the process. 1140 1141 \param last_in_subtree 1142 It is the index of the last element in the subtree. 1143 1144 \param subtree_size 1145 It is the number of valid elements in the subtree. 1146 It must be greater than zero. 1147 1148 \param key 1149 The key that may be added to the tree if add_element is \c true. 1150 1151 \param value 1152 The value that may be added to the tree if add_element is \c true. 1153 1154 \param add_element 1155 If it is true, it tries to add an element with key \p key and value 1156 \p value in the process (but it may not). 1157 1158 This method takes \f$O(k)\f$ time, where k is \p subtree_size. 1159 */ 1160 dimension_type compact_elements_in_the_rightmost_end( 1161 dimension_type last_in_subtree, dimension_type subtree_size, 1162 dimension_type key, data_type_const_reference value, 1163 bool add_element); 1164 1165 //! Redistributes the elements in the subtree rooted at \p root_index. 1166 /*! 1167 The subtree's elements must be compacted to the rightmost end. 1168 1169 \param root_index 1170 The index of the subtree's root node. 1171 1172 \param subtree_size 1173 It is the number of used elements in the subtree. 1174 It must be greater than zero. 1175 1176 \param last_used 1177 It points to the leftmost element with a value in the subtree. 1178 1179 \param add_element 1180 If it is true, this method adds an element with the specified key and 1181 value in the process. 1182 1183 \param key 1184 The key that will be added to the tree if \p add_element is \c true. 1185 1186 \param value 1187 The data that will be added to the tree if \p add_element is \c true. 1188 1189 This method takes \f$O(k)\f$ time, where k is \p subtree_size. 1190 */ 1191 void redistribute_elements_in_subtree(dimension_type root_index, 1192 dimension_type subtree_size, 1193 dimension_type last_used, 1194 dimension_type key, 1195 data_type_const_reference value, 1196 bool add_element); 1197 1198 //! Moves all data in the tree \p tree into *this. 1199 /*! 1200 \param tree 1201 The tree from which the element will be moved into *this. 1202 1203 *this must be empty and big enough to contain all of tree's data without 1204 exceeding max_density. 1205 1206 This method takes \f$O(n)\f$ time. 1207 */ 1208 void move_data_from(CO_Tree& tree); 1209 1210 //! Copies all data in the tree \p tree into *this. 1211 /*! 1212 \param tree 1213 The tree from which the element will be copied into *this. 1214 1215 *this must be empty and must have the same reserved size of \p tree. 1216 this->OK() may return false before this method is called, but 1217 this->structure_OK() must return true. 1218 1219 This method takes \f$O(n)\f$ time. 1220 */ 1221 void copy_data_from(const CO_Tree& tree); 1222 1223 //! Counts the number of used elements in the subtree rooted at itr. 1224 /*! 1225 \param itr 1226 An %iterator pointing to the root of the desired subtree. 1227 1228 This method takes \f$O(k)\f$ time, where k is the number of elements in 1229 the subtree. 1230 */ 1231 static dimension_type count_used_in_subtree(tree_iterator itr); 1232 1233 //! Moves the value of \p from in \p to . 1234 /*! 1235 \param from 1236 It must be a valid value. 1237 1238 \param to 1239 It must be a non-constructed chunk of memory. 1240 1241 After the move, \p from becomes a non-constructed chunk of memory and 1242 \p to gets the value previously stored by \p from. 1243 1244 The implementation of this method assumes that data_type values do not 1245 keep pointers to themselves nor to their fields. 1246 1247 This method takes \f$O(1)\f$ time. 1248 */ 1249 static void move_data_element(data_type& to, data_type& from); 1250 1251 //! The maximum density of used nodes. 1252 /*! 1253 This must be greater than or equal to 50 and lower than 100. 1254 */ 1255 static const dimension_type max_density_percent = 91; 1256 1257 //! The minimum density of used nodes. 1258 /*! 1259 Must be strictly lower than the half of max_density_percent. 1260 */ 1261 static const dimension_type min_density_percent = 38; 1262 1263 //! The minimum density at the leaves' depth. 1264 /*! 1265 Must be greater than zero and strictly lower than min_density_percent. 1266 1267 Increasing the value is safe but leads to time inefficiencies 1268 (measured against ppl_lpsol on 24 August 2010), because it forces trees to 1269 be more balanced, increasing the cost of rebalancing. 1270 */ 1271 static const dimension_type min_leaf_density_percent = 1; 1272 1273 //! An index used as a marker for unused nodes in the tree. 1274 /*! 1275 This must not be used as a key. 1276 */ 1277 static const dimension_type unused_index = C_Integer<dimension_type>::max; 1278 1279 //! The %iterator returned by end(). 1280 /*! 1281 It is updated when needed, to keep it valid. 1282 */ 1283 iterator cached_end; 1284 1285 //! The %iterator returned by the const version of end(). 1286 /*! 1287 It is updated when needed, to keep it valid. 1288 */ 1289 const_iterator cached_const_end; 1290 1291 //! The depth of the leaves in the complete tree. 1292 height_t max_depth; 1293 1294 //! The vector that contains the keys in the tree. 1295 /*! 1296 If an element of this vector is \p unused_index , it means that that 1297 element and the corresponding element of data[] are not used. 1298 1299 Its size is reserved_size + 2, because the first and the last elements 1300 are used as markers for iterators. 1301 */ 1302 dimension_type* indexes; 1303 1304 //! The allocator used to allocate/deallocate data. 1305 std::allocator<data_type> data_allocator; 1306 1307 //! The vector that contains the data of the keys in the tree. 1308 /*! 1309 If index[i] is \p unused_index, data[i] is unused. 1310 Otherwise, data[i] contains the data associated to the indexes[i] key. 1311 1312 Its size is reserved_size + 1, because the first element is not used (to 1313 allow using the same index in both indexes[] and data[] instead of 1314 adding 1 to access data[]). 1315 */ 1316 data_type* data; 1317 1318 //! The number of nodes in the complete tree. 1319 /*! 1320 It is one less than a power of 2. 1321 If this is 0, data and indexes are set to NULL. 1322 */ 1323 dimension_type reserved_size; 1324 1325 //! The number of values stored in the tree. 1326 dimension_type size_; 1327 }; 1328 1329 class CO_Tree::tree_iterator { 1330 1331 public: 1332 1333 /*! 1334 \brief Constructs a tree_iterator pointing at the root node of the 1335 specified tree 1336 1337 \param tree 1338 The tree to which the new %iterator will point to. 1339 It must not be empty. 1340 */ 1341 explicit tree_iterator(CO_Tree& tree); 1342 1343 //! Constructs a tree_iterator pointing at the specified node of the tree. 1344 /*! 1345 \param tree 1346 The tree to which the new %iterator will point to. 1347 It must not be empty. 1348 1349 \param i 1350 The index of the element in \p tree to which the new %iterator will point 1351 to. 1352 */ 1353 tree_iterator(CO_Tree& tree, dimension_type i); 1354 1355 //! Constructs a tree_iterator from an iterator. 1356 /*! 1357 \param itr 1358 The iterator that will be converted into a tree_iterator. 1359 It must not be end(). 1360 1361 \param tree 1362 The tree to which the new %iterator will point to. 1363 It must not be empty. 1364 */ 1365 tree_iterator(const iterator& itr, CO_Tree& tree); 1366 1367 //! The assignment operator. 1368 /*! 1369 \param itr 1370 The %iterator that will be assigned into *this. 1371 */ 1372 tree_iterator& operator=(const tree_iterator& itr); 1373 1374 //! The assignment operator from an iterator. 1375 /*! 1376 \param itr 1377 The iterator that will be assigned into *this. 1378 */ 1379 tree_iterator& operator=(const iterator& itr); 1380 1381 //! Compares *this with \p itr. 1382 /*! 1383 \param itr 1384 The %iterator that will compared with *this. 1385 */ 1386 bool operator==(const tree_iterator& itr) const; 1387 1388 //! Compares *this with \p itr. 1389 /*! 1390 \param itr 1391 The %iterator that will compared with *this. 1392 */ 1393 bool operator!=(const tree_iterator& itr) const; 1394 1395 //! Makes the %iterator point to the root of \p tree. 1396 /*! 1397 The values of all fields (beside tree) are overwritten. 1398 1399 This method takes \f$O(1)\f$ time. 1400 */ 1401 void get_root(); 1402 1403 //! Makes the %iterator point to the left child of the current node. 1404 /*! 1405 This method takes \f$O(1)\f$ time. 1406 */ 1407 void get_left_child(); 1408 1409 //! Makes the %iterator point to the right child of the current node. 1410 /*! 1411 This method takes \f$O(1)\f$ time. 1412 */ 1413 void get_right_child(); 1414 1415 //! Makes the %iterator point to the parent of the current node. 1416 /*! 1417 This method takes \f$O(1)\f$ time. 1418 */ 1419 void get_parent(); 1420 1421 /*! 1422 \brief Searches for an element with key \p key in the subtree rooted at 1423 \p *this. 1424 1425 \param key 1426 The searched for key. 1427 1428 After this method, *this points to the found node (if it exists) or to 1429 the node that would be his parent (otherwise). 1430 1431 This method takes \f$O(\log n)\f$ time. 1432 */ 1433 void go_down_searching_key(dimension_type key); 1434 1435 /*! 1436 \brief Follows left children with a value, until it arrives at a leaf or at 1437 a node with no value. 1438 1439 This method takes \f$O(1)\f$ time. 1440 */ 1441 void follow_left_children_with_value(); 1442 1443 /*! 1444 \brief Follows right children with a value, until it arrives at a leaf or at 1445 a node with no value. 1446 1447 This method takes \f$O(1)\f$ time. 1448 */ 1449 void follow_right_children_with_value(); 1450 1451 //! Returns true if the pointed node is the root node. 1452 /*! 1453 This method takes \f$O(1)\f$ time. 1454 */ 1455 bool is_root() const; 1456 1457 //! Returns true if the pointed node has a parent and is its right child. 1458 /*! 1459 This method takes \f$O(1)\f$ time. 1460 */ 1461 bool is_right_child() const; 1462 1463 //! Returns true if the pointed node is a leaf of the complete tree. 1464 /*! 1465 This method takes \f$O(1)\f$ time. 1466 */ 1467 bool is_leaf() const; 1468 1469 //! Returns the key and value of the current node. 1470 data_type& operator*(); 1471 1472 //! Returns the key and value of the current node. 1473 Coefficient_traits::const_reference operator*() const; 1474 1475 //! Returns a reference to the index of the element pointed to by \c *this. 1476 /*! 1477 \returns a reference to the index of the element pointed to by \c *this. 1478 */ 1479 dimension_type& index(); 1480 1481 //! Returns the index of the element pointed to by \c *this. 1482 /*! 1483 \returns the index of the element pointed to by \c *this. 1484 */ 1485 dimension_type index() const; 1486 1487 //! Returns the index of the node pointed to by \c *this. 1488 /*! 1489 \returns the key of the node pointed to by \c *this, or unused_index if 1490 the current node does not contain a valid element. 1491 */ 1492 dimension_type key() const; 1493 1494 //! The tree containing the element pointed to by this %iterator. 1495 CO_Tree& tree; 1496 1497 /*! 1498 \brief Returns the index of the current node in the DFS layout of the 1499 complete tree. 1500 */ 1501 dimension_type dfs_index() const; 1502 1503 /*! 1504 \brief Returns 2^h, with h the height of the current node in the tree, 1505 counting from 0. 1506 1507 Thus leaves have offset 1. 1508 This is faster than depth(), so it is useful to compare node depths. 1509 1510 This method takes \f$O(1)\f$ time. 1511 */ 1512 dimension_type get_offset() const; 1513 1514 //! Returns the depth of the current node in the complete tree. 1515 /*! 1516 This method takes \f$O(\log n)\f$ time. 1517 */ 1518 height_t depth() const; 1519 1520 private: 1521 //! Checks the internal invariant. 1522 bool OK() const; 1523 1524 //! The index of the current node in the DFS layout of the complete tree. 1525 dimension_type i; 1526 1527 /*! 1528 \brief This is 2^h, with h the height of the current node in the tree, 1529 counting from 0. 1530 1531 Thus leaves have offset 1. 1532 This is equal to (i & -i), and is only stored to increase performance. 1533 */ 1534 dimension_type offset; 1535 }; 1536 1537 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 1538 //! Swaps \p x with \p y. 1539 /*! \relates CO_Tree */ 1540 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 1541 void swap(CO_Tree& x, CO_Tree& y); 1542 1543 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 1544 //! Swaps \p x with \p y. 1545 /*! \relates CO_Tree::const_iterator */ 1546 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 1547 void swap(CO_Tree::const_iterator& x, CO_Tree::const_iterator& y); 1548 1549 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 1550 //! Swaps \p x with \p y. 1551 /*! \relates CO_Tree::iterator */ 1552 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 1553 void swap(CO_Tree::iterator& x, CO_Tree::iterator& y); 1554 1555 } // namespace Parma_Polyhedra_Library 1556 1557 #include "CO_Tree_inlines.hh" 1558 #include "CO_Tree_templates.hh" 1559 1560 #endif // !defined(PPL_CO_Tree_defs_hh) 1561