[PATCH 07/12] vinyl: move vy_history to its own source file
Vladimir Davydov
vdavydov.dev at gmail.com
Sun Apr 15 22:55:20 MSK 2018
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
More information about the Tarantool-patches
mailing list