|
datastructures 0.1.0
|
Persitent AVL tree implementation. More...
#include <_persistent_avl.hpp>


Public Types | |
| using | version_type = persistent_avl_version_type |
| using | node_ptr = typename base::node_ptr |
| using | key_type = typename base::key_type |
| using | size_type = typename base::size_type |
Public Types inherited from datastructures::detail::avl_tree_base< TKey, TItem, TKeyComp, TAlloc, persistent_avl_node< TItem, TAlloc, persistent_avl_version_type > > | |
| using | key_type = TKey |
| using | item_type = TItem |
| using | comparator_type = TKeyComp |
| using | allocator_type = TAlloc |
| using | node_type = persistent_avl_node< TItem, TAlloc, persistent_avl_version_type > |
| using | node_alloc_type = avl_node_allocator_type< node_type, allocator_type > |
| The node allocator type. | |
| using | node_ptr = avl_node_ptr< node_type, allocator_type > |
| The node pointer type. | |
| using | node_alloc_traits = std::allocator_traits< node_alloc_type > |
| Node allocator traits. | |
| using | size_type = typename node_alloc_traits::size_type |
| The size type. | |
Public Member Functions | |
| persistent_avl_tree (const typename base::comparator_type &comparator, const typename base::allocator_type &allocator) | |
| Constructs new persistent AVL tree. | |
| persistent_avl_tree (const persistent_avl_tree &other) | |
| Copies another tree. | |
| persistent_avl_tree & | operator= (const persistent_avl_tree &other) |
| Copies another tree. | |
| persistent_avl_tree (persistent_avl_tree &&other) noexcept | |
| Moves another tree into this one. | |
| persistent_avl_tree & | operator= (persistent_avl_tree &&other) noexcept |
| Moves another tree into this one. | |
| ~persistent_avl_tree () noexcept | |
| Destroys the tree. | |
| node_ptr | get_root (version_type version) const noexcept |
| Returns the trees root in a given version. | |
| std::vector< node_ptr > | list_in_order (version_type version) const noexcept |
| Returns a vector of nodes sorted by keys. | |
| node_ptr | find (const key_type &key, version_type version) const noexcept |
Finds a node with the given key in the given version, if there isn't any returns a nullptr. | |
| void | clear_all () noexcept |
| Erases the whole tree across versions. | |
| template<std::invocable TCallback> | |
| std::pair< node_ptr, bool > | insert (const key_type &key, TCallback &&callback, version_type version, bool do_assign) |
| Inserts an item to the tree. | |
| std::pair< bool, version_type > | erase (const key_type &key, version_type version) noexcept |
| Erases the node with the given key or does nothing if the key does not exist. | |
| base::size_type | size (version_type version) const noexcept |
| Returns the current number of nodes in the given version. | |
| int | get_height (version_type version) const |
| Returns the height of the tree in the given version. | |
| version_type | get_current_version () const noexcept |
| Returns the current verison. | |
| version_type | get_preceding_version (version_type version) const |
| Returns the preceding version to the given version. | |
| template<std::invocable TCallback> | |
| std::pair< typename persistent_avl_tree< TKey, TItem, TKeyComp, TAlloc >::node_ptr, bool > | insert (const key_type &key, TCallback &&callback, version_type version, bool do_assign) |
Public Member Functions inherited from datastructures::detail::avl_tree_base< TKey, TItem, TKeyComp, TAlloc, persistent_avl_node< TItem, TAlloc, persistent_avl_version_type > > | |
| avl_tree_base (const comparator_type &comparator, const allocator_type &allocator) | |
| avl_tree_base (comparator_type &&comparator, allocator_type &&allocator) noexcept | |
| virtual | ~avl_tree_base ()=0 |
| node_alloc_type | get_allocator () const noexcept |
| Returns the associated allocator. | |
Persitent AVL tree implementation.
Implemented using the path copying method, thus every update operation adds O(log n) space.
It should keep a minimal interface, supports only insertion, deletion and find. Any more high-level shortcut functions should be implemented in wrappers.
Every function is implemented without recursion.
The only time the pointers are invalidated is when .clear_all() is called, deletions do not invalidate pointers, although after every update operation some pointers can point to an old version.
Each update operation creates a new version which is based on the given one. The whole version tree can be retrieved using the .get_preceding_version() method for every version from 0 up to the current one. Multiple "newest" versions can co-exist with each one forming a new branch. To get the newly created version right after some update operation use .get_current_version() after it.
The nodes do not store pointers to parents, because the invariant that each node has just one predecessor no longer holds, thus the implementation of iterators is not possible in the current state.
There are two types TKey and TItem, it is this way to make the class more general and so that it can represent both sets and maps. The key type is the raw type that is used to query and compare nodes, the item type is the internal type stored in nodes, and it can be indentical to the key type.
The node allocator is derived from the item allocator TAlloc.
| TKey | The key type. |
| TItem | The item type, usually same as the TKey or std::pair<TKey, TValue> for some TValue. |
| TKeyComp | TKeyComp must allow comparisons between all of: two keys; two items; one key and one item; one item and one key. The comparisons must be all noexcept. |
| TAlloc | The item allocator type. |
| using datastructures::detail::persistent_avl_tree< TKey, TItem, TKeyComp, TAlloc >::key_type = typename base::key_type |
| using datastructures::detail::persistent_avl_tree< TKey, TItem, TKeyComp, TAlloc >::node_ptr = typename base::node_ptr |
| using datastructures::detail::persistent_avl_tree< TKey, TItem, TKeyComp, TAlloc >::size_type = typename base::size_type |
| using datastructures::detail::persistent_avl_tree< TKey, TItem, TKeyComp, TAlloc >::version_type = persistent_avl_version_type |
| datastructures::detail::persistent_avl_tree< TKey, TItem, TKeyComp, TAlloc >::persistent_avl_tree | ( | const typename base::comparator_type & | comparator, |
| const typename base::allocator_type & | allocator | ||
| ) |
Constructs new persistent AVL tree.
The tree needs to get the comparator and allocator instance from its wrapper, because they can store essential context. And to minimize the interface this is the only constructor except for the copy/move ones.
| comparator | The comparator instance passed from the wrapper. |
| allocator | The allocator instance passed from the wrapper. |
| datastructures::detail::persistent_avl_tree< TKey, TItem, TKeyComp, TAlloc >::persistent_avl_tree | ( | const persistent_avl_tree< TKey, TItem, TKeyComp, TAlloc > & | other | ) |
Copies another tree.
|
noexcept |
Moves another tree into this one.
|
noexcept |
Destroys the tree.
Correctly deallocates all the nodes without allocating any new memory.
|
noexcept |
Erases the whole tree across versions.
Erases every node without allocating any more space and thus cannot throw an exception.
Clears also the roots vector and based_on vector.
|
noexcept |
Erases the node with the given key or does nothing if the key does not exist.
Creates a new version based on the given version.
Does not invalidate any pointers because the path will be just copied without the node.
now we are sure that we will delete a node
|
noexcept |
Finds a node with the given key in the given version, if there isn't any returns a nullptr.
For version which do not exist yet returns a nullptr.
| key | The key to look for. |
| version | The version to search in. |
|
inlinenoexcept |
Returns the current verison.
| int datastructures::detail::persistent_avl_tree< TKey, TItem, TKeyComp, TAlloc >::get_height | ( | version_type | version | ) | const |
Returns the height of the tree in the given version.
That means the number of edges.
For invalid versions returns -1.
|
inline |
Returns the preceding version to the given version.
|
inlinenoexcept |
Returns the trees root in a given version.
For version which do not exist yet returns a nullptr.
| std::pair< node_ptr, bool > datastructures::detail::persistent_avl_tree< TKey, TItem, TKeyComp, TAlloc >::insert | ( | const key_type & | key, |
| TCallback && | callback, | ||
| version_type | version, | ||
| bool | do_assign | ||
| ) |
Inserts an item to the tree.
Creates a new version based on the given version.
This function functions as an all-in-one solution to the standard emplace/insert/assign methods. It takes in the key and tries to find it. When the key is present and do_assign is true copies the path and the found node but with the newly given item, that is obtained as the result of calling the callback function. When the key does not exist inserts a new node with the new item using the same logic.
When the do_assign flag is false it does not increase the version nor does it copy anything.
do_assign is false and the key was already present; true if the item was newly inserted, meaning the key was not present.| T | The item type. |
| key | The key to insert |
| callback | The callback function to call when inserting new item, it must return either a rvalue or lvalue reference to the item to be inserted. |
| version | If the version is not in the tree the new version will be based on the initial version -1. |
| do_assign | Says what to do in the case the key is already in the tree. |
| std::pair< typename persistent_avl_tree< TKey, TItem, TKeyComp, TAlloc >::node_ptr, bool > datastructures::detail::persistent_avl_tree< TKey, TItem, TKeyComp, TAlloc >::insert | ( | const key_type & | key, |
| TCallback && | callback, | ||
| version_type | version, | ||
| bool | do_assign | ||
| ) |
|
noexcept |
Returns a vector of nodes sorted by keys.
The values are returned as const pointers since they are immutable.
For an empty tree or invalid version returns an empty vector.
| persistent_avl_tree< TKey, TItem, TKeyComp, TAlloc > & datastructures::detail::persistent_avl_tree< TKey, TItem, TKeyComp, TAlloc >::operator= | ( | const persistent_avl_tree< TKey, TItem, TKeyComp, TAlloc > & | other | ) |
Copies another tree.
|
noexcept |
Moves another tree into this one.
|
inlinenoexcept |
Returns the current number of nodes in the given version.
For invalid versions returns 0.