salad: rework bps tree read view API
Currently, there's no notion of a BPS tree read view per se - one can create an iterator over a regular tree and then "freeze" it. This works just fine for snapshotting and joining replicas, but this spartan API doesn't let us implement user read views, because to do that we need to do lookups and create iterators over a frozen tree as many times as we want, not just once. So this patch introduces a concept of bps_tree_view, which contains a frozen image of a bps_tree and implements a subset of non-modifying bps_tree methods: - bps_tree_view_size - bps_tree_view_find - bps_tree_view_first - bps_tree_view_last - bps_tree_view_lower_bound - bps_tree_view_lower_bound_elem - bps_tree_view_upper_bound - bps_tree_view_upper_bound_elem - bps_tree_view_iterator_get_elem - bps_tree_view_iterator_prev - bps_tree_view_iterator_next - bps_tree_view_iterator_is_equal Note, bps_tree and bps_tree_view share bps_tree_iterator, because iterator methods (get_elem, next, prev, is_equal) take bps_tree or bps_tree_view. The bps_tree_iterator now contains only block index and offset. We could also implement the rest of non-modifying methods, but didn't do that, because they are not needed to implement user read views: - bps_tree_random - bps_tree_approximate_count - bps_tree_debug_check - bps_tree_print To create a bps_tree_view from a bps_tree, one is supposed to call bps_tree_view_create. If a bps_tree_view is no longer needed, it should be destroyed with bps_tree_view_destroy. Old methods used for creating frozen iterators were dropped: - bps_tree_iterator_freeze - bps_tree_iterator_destroy To avoid code duplication, we factored out the common part of bps_tree and bps_tree_view into a new structure, named bps_tree_common. Basically, the new structure contains all bps_tree members except matras, which is stored in bps_tree. The difference between bps_tree_view and bps_tree is that the latter stores matras_view instead of matras. The common part contains pointers to matras and matras_view, which are used by internal implementation to look up bps_tree blocks. All internal methods now take bps_tree_common instead of bps_tree. For all public methods that are implemented both for bps_tree and bps_tree_view, we have the common implementation defined in _impl suffixed private function, which is called by the corresponding public functions. To ensure that a modifying method isn't called on bps_tree_common object corresponding to a bps_tree_view because of a bug in the bps_tree implementation, we added !matras_is_read_view_created assertion to bps_tree_touch_block. Closes #7191 NO_DOC=refactoring NO_CHANGELOG=refactoring
Showing
- src/box/memtx_tree.cc 24 additions, 9 deletionssrc/box/memtx_tree.cc
- src/lib/salad/bps_tree.h 583 additions, 199 deletionssrc/lib/salad/bps_tree.h
- test/unit/CMakeLists.txt 2 additions, 0 deletionstest/unit/CMakeLists.txt
- test/unit/bps_tree.cc 8 additions, 8 deletionstest/unit/bps_tree.cc
- test/unit/bps_tree_iterator.cc 12 additions, 10 deletionstest/unit/bps_tree_iterator.cc
- test/unit/bps_tree_view.c 466 additions, 0 deletionstest/unit/bps_tree_view.c
- test/unit/bps_tree_view.result 76 additions, 0 deletionstest/unit/bps_tree_view.result
Loading
Please register or sign in to comment