-
Notifications
You must be signed in to change notification settings - Fork 403
Closed
Description
Consider the following snippet:
tarantool/src/box/memtx_tree.cc
Lines 673 to 726 in 2d97e4c
| 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.
Reactions are currently unavailable