From: Vladimir Davydov <vdavydov.dev@gmail.com> To: kostja@tarantool.org Cc: tarantool-patches@freelists.org Subject: [PATCH 07/12] vinyl: move vy_history to its own source file Date: Sun, 15 Apr 2018 22:55:20 +0300 [thread overview] Message-ID: <4aedbfc963dd58a7f450ddab1457b9f2a4053b58.1523820298.git.vdavydov.dev@gmail.com> (raw) In-Reply-To: <cover.1523820298.git.vdavydov.dev@gmail.com> In-Reply-To: <cover.1523820298.git.vdavydov.dev@gmail.com> So that it can be reused by vy_read_iterator. No functional changes, this patch just moves pieces of code. --- src/box/CMakeLists.txt | 1 + src/box/vy_history.c | 111 +++++++++++++++++++++++++++++++++++++ src/box/vy_history.h | 133 ++++++++++++++++++++++++++++++++++++++++++++ src/box/vy_point_lookup.c | 138 +--------------------------------------------- test/unit/CMakeLists.txt | 1 + 5 files changed, 247 insertions(+), 137 deletions(-) create mode 100644 src/box/vy_history.c create mode 100644 src/box/vy_history.h diff --git a/src/box/CMakeLists.txt b/src/box/CMakeLists.txt index ef7225d1..807ee566 100644 --- a/src/box/CMakeLists.txt +++ b/src/box/CMakeLists.txt @@ -84,6 +84,7 @@ add_library(box STATIC vy_cache.c vy_log.c vy_upsert.c + vy_history.c vy_read_set.c vy_scheduler.c request.c diff --git a/src/box/vy_history.c b/src/box/vy_history.c new file mode 100644 index 00000000..a11705a6 --- /dev/null +++ b/src/box/vy_history.c @@ -0,0 +1,111 @@ +/* + * Copyright 2010-2018, Tarantool AUTHORS, please see AUTHORS file. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "vy_history.h" + +#include <stdbool.h> +#include <stddef.h> +#include <small/region.h> +#include <small/rlist.h> + +#include "diag.h" +#include "fiber.h" +#include "tuple.h" +#include "iproto_constants.h" +#include "vy_stmt.h" +#include "vy_upsert.h" + +int +vy_history_append_stmt(struct vy_history *history, struct tuple *stmt) +{ + struct region *region = &fiber()->gc; + struct vy_history_node *node = region_alloc(region, sizeof(*node)); + if (node == NULL) { + diag_set(OutOfMemory, sizeof(*node), "region", + "struct vy_history_node"); + return -1; + } + node->is_refable = vy_stmt_is_refable(stmt); + if (node->is_refable) + tuple_ref(stmt); + node->stmt = stmt; + rlist_add_tail_entry(&history->stmts, node, link); + return 0; +} + +void +vy_history_cleanup(struct vy_history *history) +{ + struct vy_history_node *node; + rlist_foreach_entry(node, &history->stmts, link) { + if (node->is_refable) + tuple_unref(node->stmt); + } + rlist_create(&history->stmts); +} + +int +vy_history_apply(struct vy_history *history, const struct key_def *cmp_def, + struct tuple_format *format, int *upserts_applied, + struct tuple **ret) +{ + *ret = NULL; + *upserts_applied = 0; + if (rlist_empty(&history->stmts)) + return 0; + + struct tuple *curr_stmt = NULL; + struct vy_history_node *node = rlist_last_entry(&history->stmts, + struct vy_history_node, link); + if (vy_history_is_terminal(history)) { + if (vy_stmt_type(node->stmt) == IPROTO_DELETE) { + /* Ignore terminal delete */ + } else if (!node->is_refable) { + curr_stmt = vy_stmt_dup(node->stmt); + } else { + curr_stmt = node->stmt; + tuple_ref(curr_stmt); + } + node = rlist_prev_entry_safe(node, &history->stmts, link); + } + while (node != NULL) { + struct tuple *stmt = vy_apply_upsert(node->stmt, curr_stmt, + cmp_def, format, true); + ++*upserts_applied; + if (stmt == NULL) + return -1; + if (curr_stmt != NULL) + tuple_unref(curr_stmt); + curr_stmt = stmt; + node = rlist_prev_entry_safe(node, &history->stmts, link); + } + *ret = curr_stmt; + return 0; +} diff --git a/src/box/vy_history.h b/src/box/vy_history.h new file mode 100644 index 00000000..01f5364c --- /dev/null +++ b/src/box/vy_history.h @@ -0,0 +1,133 @@ +#ifndef INCLUDES_TARANTOOL_BOX_VY_HISTORY_H +#define INCLUDES_TARANTOOL_BOX_VY_HISTORY_H +/* + * Copyright 2010-2018, Tarantool AUTHORS, please see AUTHORS file. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <assert.h> +#include <stdbool.h> +#include <small/rlist.h> + +#include "iproto_constants.h" +#include "vy_stmt.h" + +#if defined(__cplusplus) +extern "C" { +#endif /* defined(__cplusplus) */ + +struct key_def; +struct tuple; +struct tuple_format; + +/** Key history. */ +struct vy_history { + /** + * List of statements sorted by LSN in descending order. + * Linked by vy_history_node::link. + */ + struct rlist stmts; +}; + +/** Key history node. */ +struct vy_history_node { + /** Link in a history list. */ + struct rlist link; + /** History statement. Referenced if @is_refable is set. */ + struct tuple *stmt; + /** + * Set if the statement stored in this node is refable, + * i.e. has a reference counter that can be incremented + * to pin the statement in memory. Refable statements are + * referenced by the history. It is a responsibility of + * the user of the history to track lifetime of unrefable + * statements. + * + * Note, we need to store this flag here, because by the + * time we clean up a history list, unrefable statements + * stored in it might have been deleted, thus making + * vy_stmt_is_refable() unusable. + */ + bool is_refable; +}; + +/** + * Initialize a history list. + */ +static inline void +vy_history_create(struct vy_history *history) +{ + rlist_create(&history->stmts); +} + +/** + * Return true if the history of a key contains terminal node in the end, + * i.e. REPLACE of DELETE statement. + */ +static inline bool +vy_history_is_terminal(struct vy_history *history) +{ + if (rlist_empty(&history->stmts)) + return false; + struct vy_history_node *node = rlist_last_entry(&history->stmts, + struct vy_history_node, link); + assert(vy_stmt_type(node->stmt) == IPROTO_REPLACE || + vy_stmt_type(node->stmt) == IPROTO_DELETE || + vy_stmt_type(node->stmt) == IPROTO_INSERT || + vy_stmt_type(node->stmt) == IPROTO_UPSERT); + return vy_stmt_type(node->stmt) != IPROTO_UPSERT; +} + +/** + * Append an (older) statement to a history list. + * Returns 0 on success, -1 on memory allocation error. + */ +int +vy_history_append_stmt(struct vy_history *history, struct tuple *stmt); + +/** + * Release all statements stored in the given history and + * reinitialize the history list. + */ +void +vy_history_cleanup(struct vy_history *history); + +/** + * Get a resultant statement from collected history. + */ +int +vy_history_apply(struct vy_history *history, const struct key_def *cmp_def, + struct tuple_format *format, int *upserts_applied, + struct tuple **ret); + +#if defined(__cplusplus) +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* INCLUDES_TARANTOOL_BOX_VY_HISTORY_H */ diff --git a/src/box/vy_point_lookup.c b/src/box/vy_point_lookup.c index 7c9995ed..6994ebfd 100644 --- a/src/box/vy_point_lookup.c +++ b/src/box/vy_point_lookup.c @@ -45,101 +45,7 @@ #include "vy_mem.h" #include "vy_run.h" #include "vy_cache.h" -#include "vy_upsert.h" - -/** Key history. */ -struct vy_history { - /** - * List of statements sorted by LSN in descending order. - * Linked by vy_history_node::link. - */ - struct rlist stmts; -}; - -/** Key history node. */ -struct vy_history_node { - /** Link in a history list. */ - struct rlist link; - /** History statement. Referenced if @is_refable is set. */ - struct tuple *stmt; - /** - * Set if the statement stored in this node is refable, - * i.e. has a reference counter that can be incremented - * to pin the statement in memory. Refable statements are - * referenced by the history. It is a responsibility of - * the user of the history to track lifetime of unrefable - * statements. - * - * Note, we need to store this flag here, because by the - * time we clean up a history list, unrefable statements - * stored in it might have been deleted, thus making - * vy_stmt_is_refable() unusable. - */ - bool is_refable; -}; - -/** - * Initialize a history list. - */ -static void -vy_history_create(struct vy_history *history) -{ - rlist_create(&history->stmts); -} - -/** - * Append an (older) statement to a history list. - * Returns 0 on success, -1 on memory allocation error. - */ -static int -vy_history_append_stmt(struct vy_history *history, struct tuple *stmt) -{ - struct region *region = &fiber()->gc; - struct vy_history_node *node = region_alloc(region, sizeof(*node)); - if (node == NULL) { - diag_set(OutOfMemory, sizeof(*node), "region", - "struct vy_history_node"); - return -1; - } - node->is_refable = vy_stmt_is_refable(stmt); - if (node->is_refable) - tuple_ref(stmt); - node->stmt = stmt; - rlist_add_tail_entry(&history->stmts, node, link); - return 0; -} - -/** - * Release all statements stored in the given history and - * reinitialize the history list. - */ -static void -vy_history_cleanup(struct vy_history *history) -{ - struct vy_history_node *node; - rlist_foreach_entry(node, &history->stmts, link) - if (node->is_refable) - tuple_unref(node->stmt); - rlist_create(&history->stmts); -} - -/** - * Return true if the history of a key contains terminal node in the end, - * i.e. REPLACE of DELETE statement. - */ -static bool -vy_history_is_terminal(struct vy_history *history) -{ - if (rlist_empty(&history->stmts)) - return false; - struct vy_history_node *node = rlist_last_entry(&history->stmts, - struct vy_history_node, link); - assert(vy_stmt_type(node->stmt) == IPROTO_REPLACE || - vy_stmt_type(node->stmt) == IPROTO_DELETE || - vy_stmt_type(node->stmt) == IPROTO_INSERT || - vy_stmt_type(node->stmt) == IPROTO_UPSERT); - return vy_stmt_type(node->stmt) != IPROTO_UPSERT; -} +#include "vy_history.h" /** * Scan TX write set for given key. @@ -327,48 +233,6 @@ vy_point_lookup_scan_slices(struct vy_lsm *lsm, const struct vy_read_view **rv, return rc; } -/** - * Get a resultant statement from collected history. - */ -static int -vy_history_apply(struct vy_history *history, const struct key_def *cmp_def, - struct tuple_format *format, int *upserts_applied, - struct tuple **ret) -{ - *ret = NULL; - *upserts_applied = 0; - if (rlist_empty(&history->stmts)) - return 0; - - struct tuple *curr_stmt = NULL; - struct vy_history_node *node = rlist_last_entry(&history->stmts, - struct vy_history_node, link); - if (vy_history_is_terminal(history)) { - if (vy_stmt_type(node->stmt) == IPROTO_DELETE) { - /* Ignore terminal delete */ - } else if (!node->is_refable) { - curr_stmt = vy_stmt_dup(node->stmt); - } else { - curr_stmt = node->stmt; - tuple_ref(curr_stmt); - } - node = rlist_prev_entry_safe(node, &history->stmts, link); - } - while (node != NULL) { - struct tuple *stmt = vy_apply_upsert(node->stmt, curr_stmt, - cmp_def, format, true); - ++*upserts_applied; - if (stmt == NULL) - return -1; - if (curr_stmt != NULL) - tuple_unref(curr_stmt); - curr_stmt = stmt; - node = rlist_prev_entry_safe(node, &history->stmts, link); - } - *ret = curr_stmt; - return 0; -} - int vy_point_lookup(struct vy_lsm *lsm, struct vy_tx *tx, const struct vy_read_view **rv, diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 7e1c95ed..db270de6 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -160,6 +160,7 @@ add_executable(vy_point_lookup.test ${PROJECT_SOURCE_DIR}/src/box/vy_tx.c ${PROJECT_SOURCE_DIR}/src/box/vy_read_set.c ${PROJECT_SOURCE_DIR}/src/box/vy_upsert.c + ${PROJECT_SOURCE_DIR}/src/box/vy_history.c ${PROJECT_SOURCE_DIR}/src/box/vy_lsm.c ${PROJECT_SOURCE_DIR}/src/box/vy_cache.c ${PROJECT_SOURCE_DIR}/src/box/index_def.c -- 2.11.0
next prev parent reply other threads:[~2018-04-15 19:55 UTC|newest] Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-04-15 19:55 [PATCH 00/12] vinyl: prepare read iterator for index rebuild Vladimir Davydov 2018-04-15 19:55 ` [PATCH 01/12] vinyl: rename vy_stmt_history to vy_history Vladimir Davydov 2018-04-15 19:55 ` [PATCH 02/12] vinyl: factor out vy_history_apply from vy_point_lookup_apply_history Vladimir Davydov 2018-05-14 18:19 ` [tarantool-patches] " Vladislav Shpilevoy 2018-04-15 19:55 ` [PATCH 03/12] vinyl: add vy_history_append_stmt helper Vladimir Davydov 2018-04-15 19:55 ` [PATCH 04/12] vinyl: zap iterator_src_type enum Vladimir Davydov 2018-04-15 19:55 ` [PATCH 05/12] vinyl: encapsulate key history with struct Vladimir Davydov 2018-04-15 19:55 ` [PATCH 06/12] vinyl: refine vy_history_cleanup Vladimir Davydov 2018-04-15 19:55 ` Vladimir Davydov [this message] 2018-04-15 19:55 ` [PATCH 08/12] vinyl: use mempool for vy_history_node allocations Vladimir Davydov 2018-04-15 19:55 ` [PATCH 09/12] vinyl: consolidate skip optimization checks in read iterator Vladimir Davydov 2018-05-14 18:25 ` [tarantool-patches] " Vladislav Shpilevoy 2018-05-15 15:00 ` Vladimir Davydov 2018-04-15 19:55 ` [PATCH 10/12] vinyl: refactor vy_read_iterator_next Vladimir Davydov 2018-04-15 19:55 ` [PATCH 11/12] vinyl: make read iterator always return newest tuple version Vladimir Davydov 2018-04-15 19:55 ` [PATCH 12/12] vinyl: zap vy_read_iterator::curr_stmt Vladimir Davydov 2018-05-04 18:05 ` [tarantool-patches] Re: [PATCH 00/12] vinyl: prepare read iterator for index rebuild Vladislav Shpilevoy
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=4aedbfc963dd58a7f450ddab1457b9f2a4053b58.1523820298.git.vdavydov.dev@gmail.com \ --to=vdavydov.dev@gmail.com \ --cc=kostja@tarantool.org \ --cc=tarantool-patches@freelists.org \ --subject='Re: [PATCH 07/12] vinyl: move vy_history to its own source file' \ /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