24 #ifndef PPL_CO_Tree_inlines_hh
25 #define PPL_CO_Tree_inlines_hh 1
103 std::cout <<
"(empty tree)" << std::endl;
118 if (itr.
index() == key) {
153 if (itr.
index() == key) {
158 if (result.
index() < key) {
162 PPL_ASSERT(result ==
end() || result.
index() > key);
166 PPL_ASSERT((result ==
end()) == (last.index() < key));
174 PPL_ASSERT(itr !=
end());
247 PPL_ASSERT(first !=
end());
248 PPL_ASSERT(last !=
end());
257 PPL_ASSERT(first !=
end());
258 PPL_ASSERT(last !=
end());
285 PPL_ASSERT(itr !=
end());
286 PPL_ASSERT(i <= itr.
index());
310 PPL_ASSERT(ratio <= 100);
314 return 100*numer < ratio*denom;
320 PPL_ASSERT(ratio <= 100);
324 return 100*numer > ratio*denom;
354 std::memcpy(&to, &from,
sizeof(
data_type));
360 : current_index(0), current_data(0) {
361 #if PPL_CO_TREE_EXTRA_DEBUG
369 : current_index(&(tree1.
indexes[1])), current_data(&(tree1.
data[1])) {
370 #if PPL_CO_TREE_EXTRA_DEBUG
373 if (!tree1.
empty()) {
385 : current_index(&(tree1.
indexes[i])), current_data(&(tree1.
data[i])) {
386 #if PPL_CO_TREE_EXTRA_DEBUG
412 #if PPL_CO_TREE_EXTRA_DEBUG
413 swap(tree, itr.tree);
416 PPL_ASSERT(itr.
OK());
423 #if PPL_CO_TREE_EXTRA_DEBUG
434 #if PPL_CO_TREE_EXTRA_DEBUG
443 PPL_ASSERT(current_index != 0);
444 PPL_ASSERT(current_data != 0);
445 #if PPL_CO_TREE_EXTRA_DEBUG
446 PPL_ASSERT(current_index != &(tree->indexes[tree->reserved_size + 1]));
460 PPL_ASSERT(current_index != 0);
461 PPL_ASSERT(current_data != 0);
486 inline Coefficient_traits::const_reference
488 PPL_ASSERT(current_index != 0);
489 PPL_ASSERT(current_data != 0);
491 #if PPL_CO_TREE_EXTRA_DEBUG
492 PPL_ASSERT(current_index != &(tree->indexes[tree->reserved_size + 1]));
494 return *current_data;
499 PPL_ASSERT(current_index != 0);
500 PPL_ASSERT(current_data != 0);
502 #if PPL_CO_TREE_EXTRA_DEBUG
503 PPL_ASSERT(current_index != &(tree->indexes[tree->reserved_size + 1]));
505 return *current_index;
518 return !(*
this == x);
524 : current_index(0), current_data(0) {
525 #if PPL_CO_TREE_EXTRA_DEBUG
533 : current_index(&(tree1.
indexes[1])), current_data(&(tree1.
data[1])) {
534 #if PPL_CO_TREE_EXTRA_DEBUG
537 if (!tree1.
empty()) {
548 : current_index(&(tree1.
indexes[i])), current_data(&(tree1.
data[i])) {
549 #if PPL_CO_TREE_EXTRA_DEBUG
575 #if PPL_CO_TREE_EXTRA_DEBUG
576 swap(tree, itr.tree);
579 PPL_ASSERT(itr.
OK());
586 #if PPL_CO_TREE_EXTRA_DEBUG
597 #if PPL_CO_TREE_EXTRA_DEBUG
606 PPL_ASSERT(current_index != 0);
607 PPL_ASSERT(current_data != 0);
608 #if PPL_CO_TREE_EXTRA_DEBUG
609 PPL_ASSERT(current_index != &(tree->indexes[tree->reserved_size + 1]));
624 PPL_ASSERT(current_index != 0);
625 PPL_ASSERT(current_data != 0);
653 PPL_ASSERT(current_index != 0);
654 PPL_ASSERT(current_data != 0);
656 #if PPL_CO_TREE_EXTRA_DEBUG
657 PPL_ASSERT(current_index != &(tree->indexes[tree->reserved_size + 1]));
659 return *current_data;
662 inline Coefficient_traits::const_reference
664 PPL_ASSERT(current_index != 0);
665 PPL_ASSERT(current_data != 0);
667 #if PPL_CO_TREE_EXTRA_DEBUG
668 PPL_ASSERT(current_index != &(tree->indexes[tree->reserved_size + 1]));
670 return *current_data;
675 PPL_ASSERT(current_index != 0);
676 PPL_ASSERT(current_data != 0);
678 #if PPL_CO_TREE_EXTRA_DEBUG
679 PPL_ASSERT(current_index != &(tree->indexes[tree->reserved_size + 1]));
681 return *current_index;
694 return !(*
this == x);
726 PPL_ASSERT(&tree == &(itr.
tree));
734 PPL_ASSERT(itr != tree.end());
747 return !(*
this == itr);
752 i = tree.reserved_size / 2 + 1;
759 PPL_ASSERT(offset != 0);
760 PPL_ASSERT(offset != 1);
768 PPL_ASSERT(offset != 0);
769 PPL_ASSERT(offset != 1);
777 PPL_ASSERT(!is_root());
778 PPL_ASSERT(offset != 0);
794 const std::ptrdiff_t distance = p - tree.indexes;
795 PPL_ASSERT(distance >= 0);
810 const std::ptrdiff_t distance = p - tree.indexes;
811 PPL_ASSERT(distance >= 0);
820 PPL_ASSERT(offset <= (tree.reserved_size / 2 + 1));
821 return offset == (tree.reserved_size / 2 + 1);
829 return (i & (2*offset)) != 0;
842 inline Coefficient_traits::const_reference
849 return tree.indexes[i];
854 return tree.indexes[i];
889 #endif // !defined(PPL_CO_Tree_inlines_hh)
dimension_type index() const
Returns the index of the element pointed to by *this.
bool is_root() const
Returns true if the pointed node is the root node.
void dump_tree() const
Dumps the tree to stdout, for debugging purposes.
bool operator!=(const iterator &x) const
Compares *this with x .
data_type & operator*()
Returns the key and value of the current node.
void m_swap(iterator &itr)
Swaps itr with *this.
Coefficient data_type
The type of the data elements associated with keys.
void init(dimension_type n)
Initializes a tree with reserved size at least n .
size_t dimension_type
An unsigned integral type for representing space dimensions.
bool OK() const
Checks the internal invariants.
static void dump_subtree(tree_iterator itr)
Dumps the subtree rooted at itr to stdout, for debugging purposes.
static unsigned integer_log2(dimension_type n)
Returns the floor of the base-2 logarithm of n .
static bool is_greater_than_ratio(dimension_type numer, dimension_type denom, dimension_type ratio)
Compares the fractions numer/denom with ratio/100.
void destroy()
Deallocates the tree's dynamic arrays.
bool OK() const
Checks the internal invariant.
dimension_type get_offset() const
Returns 2^h, with h the height of the current node in the tree, counting from 0.
void swap(CO_Tree::iterator &x, CO_Tree::iterator &y)
dimension_type dfs_index() const
Returns the index of the current node in the DFS layout of the complete tree.
void get_parent()
Makes the iterator point to the parent of the current node.
iterator begin()
Returns an iterator that points at the first element.
data_type * data
The vector that contains the data of the keys in the tree.
bool operator==(const iterator &x) const
Compares *this with x .
bool is_right_child() const
Returns true if the pointed node has a parent and is its right child.
const dimension_type * current_index
A pointer to the corresponding element of the tree's indexes[] array.
bool is_leaf() const
Returns true if the pointed node is a leaf of the complete tree.
An iterator on the tree elements, ordered by key.
dimension_type * indexes
The vector that contains the keys in the tree.
static dimension_type max_size()
Returns the size() of the largest possible CO_Tree.
const_iterator & operator++()
Navigates to the next element.
const data_type * current_data
A pointer to the corresponding element of the tree's data[] array.
void m_swap(const_iterator &itr)
Swaps itr with *this.
unsigned height_t
This is used for node heights and depths in the tree.
std::allocator< data_type > data_allocator
The allocator used to allocate/deallocate data.
dimension_type size() const
Returns the number of elements stored in the tree.
void m_swap(CO_Tree &x)
Swaps x with *this.
iterator & operator=(const iterator &itr)
Assigns itr to *this .
const iterator & end()
Returns an iterator that points after the last element.
const_iterator & operator--()
Navigates to the previous element.
const_iterator()
Constructs an invalid const_iterator.
iterator bisect_in(iterator first, iterator last, dimension_type key)
Searches an element with key key in [first, last] using bisection.
void get_left_child()
Makes the iterator point to the left child of the current node.
CO_Tree & operator=(const CO_Tree &y)
The assignment operator.
bool empty() const
Returns true if the tree has no elements.
iterator insert(dimension_type key)
Inserts an element in the tree.
dimension_type reserved_size
The number of nodes in the complete tree.
const_iterator cbegin() const
Returns a const_iterator that points at the first element.
bool operator==(const const_iterator &x) const
Compares *this with x .
data_type & operator*()
Returns the current element.
tree_iterator & operator=(const tree_iterator &itr)
The assignment operator.
iterator cached_end
The iterator returned by end().
A cache-oblivious binary search tree of pairs.
~CO_Tree()
The destructor.
bool operator==(const tree_iterator &itr) const
Compares *this with itr.
dimension_type offset
This is 2^h, with h the height of the current node in the tree, counting from 0.
iterator bisect(dimension_type key)
Searches an element with key key using bisection.
const_iterator cached_const_end
The iterator returned by the const version of end().
void follow_left_children_with_value()
Follows left children with a value, until it arrives at a leaf or at a node with no value...
tree_iterator(CO_Tree &tree)
Constructs a tree_iterator pointing at the root node of the specified tree.
bool OK() const
Checks the internal invariants, in debug mode only.
const const_iterator & cend() const
Returns a const_iterator that points after the last element.
dimension_type dfs_index(const_iterator itr) const
static bool is_less_than_ratio(dimension_type numer, dimension_type denom, dimension_type ratio)
Compares the fractions numer/denom with ratio/100.
bool OK() const
Checks the internal invariants, in debug mode only.
iterator & operator++()
Navigates to the next element in the tree.
CO_Tree & tree
The tree containing the element pointed to by this iterator.
bool operator!=(const const_iterator &x) const
Compares *this with x .
dimension_type & index()
Returns a reference to the index of the element pointed to by *this.
bool operator!=(const tree_iterator &itr) const
Compares *this with itr.
tree_iterator insert_precise(dimension_type key, data_type_const_reference data, tree_iterator itr)
Inserts an element in the tree.
Coefficient_traits::const_reference data_type_const_reference
Coefficient_traits::const_reference Coefficient_zero()
Returns a const reference to a Coefficient with value 0.
The entire library is confined to this namespace.
A const iterator on the tree elements, ordered by key.
iterator()
Constructs an invalid iterator.
height_t depth() const
Returns the depth of the current node in the complete tree.
void rebuild_bigger_tree()
Increases the tree's reserved size.
data_type_const_reference operator*() const
Returns the current element.
void clear()
Removes all elements from the tree.
void swap(CO_Tree &x, CO_Tree &y)
Swaps x with y.
static void move_data_element(data_type &to, data_type &from)
Moves the value of from in to .
void get_root()
Makes the iterator point to the root of tree.
void refresh_cached_iterators()
Re-initializes the cached iterators.
dimension_type size_
The number of values stored in the tree.
void insert_in_empty_tree(dimension_type key, data_type_const_reference data)
Inserts an element in the tree.
bool structure_OK() const
Checks the internal invariants, but not the densities.
void follow_right_children_with_value()
Follows right children with a value, until it arrives at a leaf or at a node with no value...
const_iterator & operator=(const const_iterator &itr)
Assigns itr to *this .
iterator erase(dimension_type key)
Erases the element with key key from the tree.
const dimension_type * current_index
A pointer to the corresponding element of the tree's indexes[] array.
iterator bisect_near(iterator hint, dimension_type key)
Searches an element with key key near hint.
dimension_type index() const
Returns the index of the element pointed to by *this.
void move_data_from(CO_Tree &tree)
Moves all data in the tree tree into *this.
height_t max_depth
The depth of the leaves in the complete tree.
void fast_shift(dimension_type i, iterator itr)
dimension_type least_significant_one_mask(dimension_type i)
static const dimension_type unused_index
An index used as a marker for unused nodes in the tree.
iterator & operator--()
Navigates to the previous element in the tree.
void rebuild_smaller_tree()
Decreases the tree's reserved size.
void get_right_child()
Makes the iterator point to the right child of the current node.
void copy_data_from(const CO_Tree &tree)
Copies all data in the tree tree into *this.
dimension_type i
The index of the current node in the DFS layout of the complete tree.
CO_Tree()
Constructs an empty tree.
data_type * current_data
A pointer to the corresponding element of the tree's data[] array.
void go_down_searching_key(dimension_type key)
Searches for an element with key key in the subtree rooted at *this.