From: Vladimir Davydov <vdavydov.dev@gmail.com> To: tarantool-patches@freelists.org Subject: [PATCH 3/6] vinyl: cache iterator: consolidate curr_stmt updates Date: Tue, 26 Mar 2019 18:50:31 +0300 [thread overview] Message-ID: <c6347c599e8deb14957b3021e1e48650c4684ae8.1553613748.git.vdavydov.dev@gmail.com> (raw) In-Reply-To: <cover.1553613748.git.vdavydov.dev@gmail.com> In-Reply-To: <cover.1553613748.git.vdavydov.dev@gmail.com> Currently, vy_cache_iterator->curr_stmt is updated by top-level iterator functions - next, skip, restore - which results in code duplication and spreads core logic among multiple places. To reduce the amount of code and make it generally easier to follow, this patch moves the updates to low level functions - step, seek. It also makes the seek method return the stop flag, which makes it similar to step, thus making the code more consistent. --- src/box/vy_cache.c | 87 ++++++++++++++++++++++-------------------------------- 1 file changed, 36 insertions(+), 51 deletions(-) diff --git a/src/box/vy_cache.c b/src/box/vy_cache.c index b27e04a5..825bfd3b 100644 --- a/src/box/vy_cache.c +++ b/src/box/vy_cache.c @@ -581,20 +581,22 @@ vy_cache_iterator_is_end_stop(struct vy_cache_iterator *itr, * Make one tree's iterator step from the current position. * Direction of the step depends on the iterator type. * @param itr Iterator to make step. - * @param[out] ret Result tuple. * - * @retval Must a merge_iterator stop on @a ret? - * The function is implicitly used by merge_iterator_next_key and - * return value is used to determine if the merge_iterator can - * return @a ret to a read_iterator immediately, without lookups - * in mems and runs. It is possible, when @a ret is a part of + * @retval Must a read iterator stop on the cached statement? + * The function is implicitly used by vy_read_iterator_next and + * return value is used to determine if the read iterator can + * return the cached statement without lookups in mems and runs. + * It is possible when the cached statement is a part of a * continuous cached tuples chain. In such a case mems or runs can * not contain more suitable tuples. */ static inline bool -vy_cache_iterator_step(struct vy_cache_iterator *itr, struct tuple **ret) +vy_cache_iterator_step(struct vy_cache_iterator *itr) { - *ret = NULL; + if (itr->curr_stmt != NULL) { + tuple_unref(itr->curr_stmt); + itr->curr_stmt = NULL; + } struct vy_cache_tree *tree = &itr->cache->cache_tree; struct vy_cache_entry *prev_entry = *vy_cache_tree_iterator_get_elem(tree, &itr->curr_pos); @@ -611,7 +613,8 @@ vy_cache_iterator_step(struct vy_cache_iterator *itr, struct tuple **ret) vy_stmt_compare(itr->key, entry->stmt, itr->cache->cmp_def)) { return vy_cache_iterator_is_end_stop(itr, prev_entry); } - *ret = entry->stmt; + itr->curr_stmt = entry->stmt; + tuple_ref(itr->curr_stmt); return vy_cache_iterator_is_stop(itr, entry); } @@ -629,7 +632,7 @@ vy_cache_iterator_skip_to_read_view(struct vy_cache_iterator *itr, bool *stop) * but there could be older tuples in runs. */ *stop = false; - vy_cache_iterator_step(itr, &itr->curr_stmt); + vy_cache_iterator_step(itr); } } @@ -637,15 +640,21 @@ vy_cache_iterator_skip_to_read_view(struct vy_cache_iterator *itr, bool *stop) * Position the iterator to the first cache entry satisfying * the iterator search criteria and following the given key * (pass NULL to start iteration). + * + * Like vy_cache_iterator_step(), this functions returns true + * if the cached statement is a part of a continuous tuple chain + * and hence the caller doesn't need to scan mems and runs. */ -static void +static bool vy_cache_iterator_seek(struct vy_cache_iterator *itr, - const struct tuple *last_key, - struct vy_cache_entry **ret) + const struct tuple *last_key) { struct vy_cache_tree *tree = &itr->cache->cache_tree; - *ret = NULL; + if (itr->curr_stmt != NULL) { + tuple_unref(itr->curr_stmt); + itr->curr_stmt = NULL; + } itr->cache->stat.lookup++; const struct tuple *key = itr->key; @@ -673,7 +682,7 @@ vy_cache_iterator_seek(struct vy_cache_iterator *itr, if (iterator_type == ITER_LT || iterator_type == ITER_LE) vy_cache_tree_iterator_prev(tree, &itr->curr_pos); if (vy_cache_tree_iterator_is_invalid(&itr->curr_pos)) - return; + return false; struct vy_cache_entry *entry; entry = *vy_cache_tree_iterator_get_elem(tree, &itr->curr_pos); @@ -682,39 +691,33 @@ vy_cache_iterator_seek(struct vy_cache_iterator *itr, ((last_key == NULL && !exact) || (last_key != NULL && vy_stmt_compare(itr->key, entry->stmt, itr->cache->cmp_def) != 0))) - return; + return false; - *ret = entry; + itr->curr_stmt = entry->stmt; + tuple_ref(itr->curr_stmt); + return vy_cache_iterator_is_stop(itr, entry); } NODISCARD int vy_cache_iterator_next(struct vy_cache_iterator *itr, struct vy_history *history, bool *stop) { - *stop = false; vy_history_cleanup(history); if (!itr->search_started) { assert(itr->curr_stmt == NULL); itr->search_started = true; itr->version = itr->cache->version; - struct vy_cache_entry *entry; - vy_cache_iterator_seek(itr, NULL, &entry); - if (entry == NULL) - return 0; - itr->curr_stmt = entry->stmt; - *stop = vy_cache_iterator_is_stop(itr, entry); + *stop = vy_cache_iterator_seek(itr, NULL); } else { assert(itr->version == itr->cache->version); if (itr->curr_stmt == NULL) return 0; - tuple_unref(itr->curr_stmt); - *stop = vy_cache_iterator_step(itr, &itr->curr_stmt); + *stop = vy_cache_iterator_step(itr); } vy_cache_iterator_skip_to_read_view(itr, stop); if (itr->curr_stmt != NULL) { - tuple_ref(itr->curr_stmt); vy_stmt_counter_acct_tuple(&itr->cache->stat.get, itr->curr_stmt); return vy_history_append_stmt(history, itr->curr_stmt); @@ -740,25 +743,14 @@ vy_cache_iterator_skip(struct vy_cache_iterator *itr, itr->cache->cmp_def) > 0)) return 0; - *stop = false; vy_history_cleanup(history); itr->search_started = true; itr->version = itr->cache->version; - if (itr->curr_stmt != NULL) - tuple_unref(itr->curr_stmt); - itr->curr_stmt = NULL; - - struct vy_cache_entry *entry; - vy_cache_iterator_seek(itr, last_stmt, &entry); - if (entry != NULL) { - *stop = vy_cache_iterator_is_stop(itr, entry); - itr->curr_stmt = entry->stmt; - } - + *stop = vy_cache_iterator_seek(itr, last_stmt); vy_cache_iterator_skip_to_read_view(itr, stop); + if (itr->curr_stmt != NULL) { - tuple_ref(itr->curr_stmt); vy_stmt_counter_acct_tuple(&itr->cache->stat.get, itr->curr_stmt); return vy_history_append_stmt(history, itr->curr_stmt); @@ -776,9 +768,6 @@ vy_cache_iterator_restore(struct vy_cache_iterator *itr, itr->version = itr->cache->version; struct tuple *prev_stmt = itr->curr_stmt; - if (prev_stmt != NULL) - tuple_unref(prev_stmt); - if ((prev_stmt == NULL && itr->iterator_type == ITER_EQ) || (prev_stmt != NULL && prev_stmt != vy_cache_iterator_curr_stmt(itr))) { @@ -787,13 +776,7 @@ vy_cache_iterator_restore(struct vy_cache_iterator *itr, * In either case the best we can do is restart the * search. */ - struct vy_cache_entry *entry; - vy_cache_iterator_seek(itr, last_stmt, &entry); - itr->curr_stmt = NULL; - if (entry != NULL) { - *stop = vy_cache_iterator_is_stop(itr, entry); - itr->curr_stmt = entry->stmt; - } + *stop = vy_cache_iterator_seek(itr, last_stmt); vy_cache_iterator_skip_to_read_view(itr, stop); } else { /* @@ -830,7 +813,10 @@ vy_cache_iterator_restore(struct vy_cache_iterator *itr, break; if (vy_stmt_lsn(entry->stmt) <= (**itr->read_view).vlsn) { itr->curr_pos = pos; + if (itr->curr_stmt != NULL) + tuple_unref(itr->curr_stmt); itr->curr_stmt = entry->stmt; + tuple_ref(itr->curr_stmt); *stop = vy_cache_iterator_is_stop(itr, entry); } if (cmp == 0) @@ -840,7 +826,6 @@ vy_cache_iterator_restore(struct vy_cache_iterator *itr, vy_history_cleanup(history); if (itr->curr_stmt != NULL) { - tuple_ref(itr->curr_stmt); vy_stmt_counter_acct_tuple(&itr->cache->stat.get, itr->curr_stmt); if (vy_history_append_stmt(history, itr->curr_stmt) != 0) -- 2.11.0
next prev parent reply other threads:[~2019-03-26 15:50 UTC|newest] Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-03-26 15:50 [PATCH 0/6] vinyl: iterator cleanup Vladimir Davydov 2019-03-26 15:50 ` [PATCH 1/6] vinyl: txw iterator: fold eq check in seek method Vladimir Davydov 2019-03-28 14:25 ` [tarantool-patches] " Konstantin Osipov 2019-03-26 15:50 ` [PATCH 2/6] vinyl: cache " Vladimir Davydov 2019-03-28 14:27 ` [tarantool-patches] " Konstantin Osipov 2019-03-26 15:50 ` Vladimir Davydov [this message] 2019-03-28 14:29 ` [tarantool-patches] Re: [PATCH 3/6] vinyl: cache iterator: consolidate curr_stmt updates Konstantin Osipov 2019-03-28 14:47 ` Vladimir Davydov 2019-03-26 15:50 ` [PATCH 4/6] vinyl: run iterator: zap search_ended flag Vladimir Davydov 2019-03-28 14:35 ` [tarantool-patches] " Konstantin Osipov 2019-03-28 14:50 ` Vladimir Davydov 2019-03-26 15:50 ` [PATCH 5/6] vinyl: run iterator: refactor seek method Vladimir Davydov 2019-03-28 14:39 ` [tarantool-patches] " Konstantin Osipov 2019-03-28 14:58 ` Vladimir Davydov 2019-03-26 15:50 ` [PATCH 6/6] vinyl: simplify read iterator restoration behavior Vladimir Davydov 2019-03-28 14:47 ` [tarantool-patches] " Konstantin Osipov 2019-03-28 16:28 ` [PATCH 0/6] vinyl: iterator cleanup Vladimir Davydov
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=c6347c599e8deb14957b3021e1e48650c4684ae8.1553613748.git.vdavydov.dev@gmail.com \ --to=vdavydov.dev@gmail.com \ --cc=tarantool-patches@freelists.org \ --subject='Re: [PATCH 3/6] vinyl: cache iterator: consolidate curr_stmt updates' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox