Skip to content

Reverse tree iterators gap tracking bug #7113

@CuriousGeorgiy

Description

@CuriousGeorgiy

Consider the following snippet:

if (iterator_type_is_reverse(type)) {
/*
* Because of limitations of tree search API we use use
* lower_bound for LT search and upper_bound for LE
* and REQ searches. Thus we found position to the
* right of the target one. Let's make a step to the
* left to reach target position.
* If we found an invalid iterator all the elements in
* the tree are less (less or equal) to the key, and
* iterator_next call will convert the iterator to the
* last position in the tree, that's what we need.
*/
memtx_tree_iterator_prev(tree, &it->tree_iterator);
}
if (!equals && (type == ITER_EQ || type == ITER_REQ)) {
/*
* Found nothing, iteration will be stopped now. That is the
* last chance to record that the transaction have read the key.
*/
if (key_is_full) {
memtx_tx_track_point(txn, space, idx, it->key_data.key);
return 0;
}
/* it->tree_iterator is positioned on successor of a key! */
struct memtx_tree_data<USE_HINT> *res =
memtx_tree_iterator_get_elem(tree, &it->tree_iterator);
struct tuple *successor = res == NULL ? NULL : res->tuple;
memtx_tx_track_gap(txn, space, idx, successor, type,
it->key_data.key, it->key_data.part_count);
return 0;
}
struct memtx_tree_data<USE_HINT> *res =
memtx_tree_iterator_get_elem(tree, &it->tree_iterator);
uint32_t mk_index = 0;
if (res != NULL) {
*ret = res->tuple;
tree_iterator_set_current(it, res);
tree_iterator_set_next_method(it);
bool is_multikey = iterator->index->def->key_def->is_multikey;
mk_index = is_multikey ? (uint32_t)res->hint : 0;
}
if ((!key_is_full || (type != ITER_EQ && type != ITER_REQ)) &&
memtx_tx_manager_use_mvcc_engine) {
/* it->tree_iterator is positioned on successor of a key! */
struct tuple *successor = res == NULL ? NULL : res->tuple;
/********MVCC TRANSACTION MANAGER STORY GARBAGE COLLECTION BOUND START*********/
memtx_tx_track_gap(in_txn(), space, idx, successor, type,
it->key_data.key, it->key_data.part_count);
/*********MVCC TRANSACTION MANAGER STORY GARBAGE COLLECTION BOUND END**********/
}

Apparently, it is buggy for reverse iterators: instead of tracking gaps for successors of keys, it tracks gaps for tuples shifted by one to the left of the successor.

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions