diff --git a/src/box/vinyl.c b/src/box/vinyl.c index 182792da817eda3b3ffe0c518032a563c6c1625a..2976f781344bc2fa3d23853f8b88dc98daa0e0c2 100644 --- a/src/box/vinyl.c +++ b/src/box/vinyl.c @@ -8111,19 +8111,6 @@ vy_read_iterator_merge_get(struct vy_read_iterator *itr, struct vy_tuple **t) return rc; } -/** - * Conventional wrapper around vy_merge_iterator_next_lsn() to automatically - * re-create the merge iterator on vy_index/vy_range/vy_run changes. - */ -static int -vy_read_iterator_merge_next_lsn(struct vy_read_iterator *itr) -{ - int rc; - while ((rc = vy_merge_iterator_next_lsn(&itr->merge_iterator)) == -2) - vy_read_iterator_restore(itr); - return rc; -} - /** * Conventional wrapper around vy_merge_iterator_next_key() to automatically * re-create the merge iterator on vy_index/vy_range/vy_run changes. @@ -8196,6 +8183,7 @@ vy_read_iterator_next(struct vy_read_iterator *itr, struct vy_tuple **result) } while (true) { struct vy_tuple *t; +restart: rc = vy_read_iterator_merge_get(itr, &t); if (rc >= 0 && itr->merge_iterator.range_ended && itr->curr_range != NULL) { rc = vy_read_iterator_next_range(itr); @@ -8208,26 +8196,35 @@ vy_read_iterator_next(struct vy_read_iterator *itr, struct vy_tuple **result) if (rc > 0) return 0; /* no more data */ assert(rc == 0); - if (itr->curr_tuple != NULL) - vy_tuple_unref(itr->curr_tuple); - itr->curr_tuple = t; - vy_tuple_ref(itr->curr_tuple); - while (itr->curr_tuple->flags & SVUPSERT) { - rc = vy_read_iterator_merge_next_lsn(itr); + vy_tuple_ref(t); + while (t->flags & SVUPSERT) { + rc = vy_merge_iterator_next_lsn(&itr->merge_iterator); + if (rc == -2) { + vy_read_iterator_restore(itr); + vy_tuple_unref(t); + goto restart; + } + if (rc < 0) { + vy_tuple_unref(t); + return rc; + } struct vy_tuple *next = NULL; - if (rc == 0) { + if (rc == 0) rc = vy_read_iterator_merge_get(itr, &next); + if (rc < 0) { + vy_tuple_unref(t); + return rc; } - if (rc < 0) - return -1; struct vy_tuple *applied = - vy_apply_upsert(itr->curr_tuple, next, - itr->index, true); + vy_apply_upsert(t, next, itr->index, true); + vy_tuple_unref(t); if (applied == NULL) return -1; - vy_tuple_unref(itr->curr_tuple); - itr->curr_tuple = applied; + t = applied; } + if (itr->curr_tuple != NULL) + vy_tuple_unref(itr->curr_tuple); + itr->curr_tuple = t; if (rc != 0 || (itr->curr_tuple->flags & SVDELETE) == 0) break; rc = vy_read_iterator_merge_next_key(itr);