[PATCH] vinyl: don't move to next range if it doesn't match EQ search key
Vladimir Davydov
vdavydov.dev at gmail.com
Wed Feb 28 12:14:32 MSK 2018
When iterating over a vinyl index, we move to the next range if the
minimal (in terms of the search criteria) statement among all sources
is outside the current range - see vy_read_iterator_next_key() and
vy_read_iterator_range_is_done(). This is OK for GE/GT/LE/LT, but for
EQ/REQ we should also make sure that the next range actually intersects
with the search key - if it doesn't, there's no point in iterating to
it. We used to have that check, but commit 5e414a73e93 ("vinyl: read
iterator: do not reopen all sources when range is changed") accidentally
removed it. As a result, unlimited EQ/REQ requests for partial keys read
runs of all ranges and therefore take much longer. This patch brings
this check back.
---
https://github.com/tarantool/tarantool/tree/vy-fix-read-iterator-perf-degradation
src/box/vy_read_iterator.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/src/box/vy_read_iterator.c b/src/box/vy_read_iterator.c
index d08be9a0..1ba33ffe 100644
--- a/src/box/vy_read_iterator.c
+++ b/src/box/vy_read_iterator.c
@@ -131,6 +131,11 @@ vy_read_iterator_unpin_slices(struct vy_read_iterator *itr)
/**
* Return true if the current statement is outside the current
* range and hence we should move to the next range.
+ *
+ * If we are looking for a match (EQ, REQ) and the search key
+ * doesn't intersect with the current range's boundary, the next
+ * range can't contain statements matching the search criteria
+ * and hence there's no point in iterating to it.
*/
static bool
vy_read_iterator_range_is_done(struct vy_read_iterator *itr)
@@ -142,12 +147,16 @@ vy_read_iterator_range_is_done(struct vy_read_iterator *itr)
if (dir > 0 && range->end != NULL &&
(stmt == NULL || vy_tuple_compare_with_key(stmt,
- range->end, cmp_def) >= 0))
+ range->end, cmp_def) >= 0) &&
+ (itr->iterator_type != ITER_EQ ||
+ vy_stmt_compare_with_key(itr->key, range->end, cmp_def) >= 0))
return true;
if (dir < 0 && range->begin != NULL &&
(stmt == NULL || vy_tuple_compare_with_key(stmt,
- range->begin, cmp_def) < 0))
+ range->begin, cmp_def) < 0) &&
+ (itr->iterator_type != ITER_REQ ||
+ vy_stmt_compare_with_key(itr->key, range->begin, cmp_def) <= 0))
return true;
return false;
--
2.11.0
More information about the Tarantool-patches
mailing list