Skip to content
Snippets Groups Projects
Commit bfe83ac8 authored by Magomed Kostoev's avatar Magomed Kostoev Committed by Vladimir Davydov
Browse files

bps: add 2-way support for logarithmic offsets

The current tree does not allow to find offset of an element or create
an iterator to an element based on its offset. This patch is meant to
fix this by expanding the data structure with additional information
and introducing methods using it: subtree cardinalities.

A subtree cardinality is the amount of elements in it. For example,
cardinality of a leaf block is count of elements in it (effectively
it equals to leaf.header.size), cardinality of an inner block is the
sum of cardinalities of its chlidren.

The patch includes two chosable ways to store this information:
`BPS_INNER_CARD` and `BPS_INNER_CHILD_CARDS`.

The first implementation sores block cardinality in each inner block.
This implementation has minimal memory overhead (it just introduces
a new 64-bit field in `struct bps_inner`), but calculation of offsets
is not that fast, since in order to find an offset of a particular
child of an inner node we have to look into each of its children
prior to the looking one.

The second one sores an array of children cardinalities in inner
blocks. The memory overhead of this implementation is visible since
it significantly decreases the children capacity of inner blocks. The
max count in inner block is decreased from 42 to 25 for tree of 8-byte
elements with 512-byte blocks and from 25 to 18 for tree of 16-byte
elements with 512-byte blocks. Offset calcluations are faster though.

It's possible (though impractical) to enable both solutions, the tree
will use the best ways to perform offset-based tasks, but will have to
maintain both children cardinality array and inner own cardinalities.

Along with the theoretical support this patch introduces a bunch of
functions using it:
- `iterator_at(t, offset)`: gives an iterator to an element of a tree
  or tree view by its offset;
- `find_get_offset(t, key, offset_ptr)`: the same as `find` but also
  provides to the user the offset of the found element in the output
  parameter;
- `[lower|upper]_bound[_elem]_get_offset(t, key, exact, offset_ptr)`:
  the same as upper/lower bound functions but provide to the user the
  offset to the found position (end of the tree included).
- `insert_get_offset(t, new_elem, replaced, offset_ptr)`: the same as
  `insert`, but also provides the offset to the inserted element.
- `delete_get_offset(t, elem, offset_ptr)`: same as `delete`, but also
  returns offset to the deleted element prior to the deletion in the
  output parameter.

Another new function introduced is bps_tree_view_debug_check(t). This
function is similar to the bps_tree_debug_check(t), but is applicable
to tree views. It's used to adopt default tree view tests to the new
tree variations.

Each new implementation is tested by old tree tests (these now support
several tree variations selected with a C definition, the definitions
are specified in the test/unit/CMakeLists.txt).

New offset API-related test introduced (this one tests both of two
tree variations - BPS_INNER_CARD and BPS_INNER_CHILD_CARDS).

Part of #8204

NO_DOC=internal
NO_CHANGELOG=internal
parent 8ecf3cdc
No related branches found
No related tags found
No related merge requests found
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment