[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