[server 2/4] Move helpers for updating request from space.c to request.c

Vladimir Davydov vdavydov.dev at gmail.com
Tue Jan 23 19:28:56 MSK 2018


This patch moves helpers used to fix requests after certain DML
operations to a separate source file. Currently, there are only
two of them, but there are going to be more so it seems to be a
good idea to isolate them. No functional changes.

Suggested by @kostja
---
 src/box/CMakeLists.txt |   1 +
 src/box/request.c      | 153 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/box/request.h      |  69 ++++++++++++++++++++++
 src/box/space.c        | 124 +--------------------------------------
 4 files changed, 225 insertions(+), 122 deletions(-)
 create mode 100644 src/box/request.c
 create mode 100644 src/box/request.h

diff --git a/src/box/CMakeLists.txt b/src/box/CMakeLists.txt
index 19d3dbbc..f31ce178 100644
--- a/src/box/CMakeLists.txt
+++ b/src/box/CMakeLists.txt
@@ -81,6 +81,7 @@ add_library(box STATIC
     vy_upsert.c
     vy_read_set.c
     vy_scheduler.c
+    request.c
     space.c
     space_def.c
     sequence.c
diff --git a/src/box/request.c b/src/box/request.c
new file mode 100644
index 00000000..9118dcc7
--- /dev/null
+++ b/src/box/request.c
@@ -0,0 +1,153 @@
+/*
+ * 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 <COPYRIGHT HOLDER> ``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
+ * <COPYRIGHT HOLDER> 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 "request.h"
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <msgpuck.h>
+#include <small/region.h>
+
+#include "fiber.h"
+#include "space.h"
+#include "index.h"
+#include "sequence.h"
+#include "key_def.h"
+#include "tuple.h"
+#include "xrow.h"
+#include "iproto_constants.h"
+
+void
+request_rebind_to_primary_key(struct request *request, struct space *space,
+			      struct tuple *found_tuple)
+{
+	struct index *pk = space_index(space, 0);
+	assert(pk != NULL);
+	uint32_t key_len;
+	char *key = tuple_extract_key(found_tuple, pk->def->key_def, &key_len);
+	assert(key != NULL);
+	request->key = key;
+	request->key_end = key + key_len;
+	request->index_id = 0;
+	/* Clear the *body* to ensure it's rebuilt at commit. */
+	request->header = NULL;
+}
+
+int
+request_handle_sequence(struct request *request, struct space *space)
+{
+	struct sequence *seq = space->sequence;
+
+	assert(seq != NULL);
+	assert(request->type == IPROTO_INSERT ||
+	       request->type == IPROTO_REPLACE);
+
+	/*
+	 * An automatically generated sequence inherits
+	 * privileges of the space it is used with.
+	 */
+	if (!seq->is_generated &&
+	    access_check_sequence(seq) != 0)
+		return -1;
+
+	struct index *pk = space_index(space, 0);
+	if (unlikely(pk == NULL))
+		return 0;
+
+	/*
+	 * Look up the first field of the primary key.
+	 */
+	const char *data = request->tuple;
+	const char *data_end = request->tuple_end;
+	int len = mp_decode_array(&data);
+	int fieldno = pk->def->key_def->parts[0].fieldno;
+	if (unlikely(len < fieldno + 1))
+		return 0;
+
+	const char *key = data;
+	if (unlikely(fieldno > 0)) {
+		do {
+			mp_next(&key);
+		} while (--fieldno > 0);
+	}
+
+	int64_t value;
+	if (mp_typeof(*key) == MP_NIL) {
+		/*
+		 * If the first field of the primary key is nil,
+		 * this is an auto increment request and we need
+		 * to replace the nil with the next value generated
+		 * by the space sequence.
+		 */
+		if (unlikely(sequence_next(seq, &value) != 0))
+			return -1;
+
+		const char *key_end = key;
+		mp_decode_nil(&key_end);
+
+		size_t buf_size = (request->tuple_end - request->tuple) +
+						mp_sizeof_uint(UINT64_MAX);
+		char *tuple = region_alloc(&fiber()->gc, buf_size);
+		if (tuple == NULL)
+			return -1;
+		char *tuple_end = mp_encode_array(tuple, len);
+
+		if (unlikely(key != data)) {
+			memcpy(tuple_end, data, key - data);
+			tuple_end += key - data;
+		}
+
+		if (value >= 0)
+			tuple_end = mp_encode_uint(tuple_end, value);
+		else
+			tuple_end = mp_encode_int(tuple_end, value);
+
+		memcpy(tuple_end, key_end, data_end - key_end);
+		tuple_end += data_end - key_end;
+
+		assert(tuple_end <= tuple + buf_size);
+
+		request->tuple = tuple;
+		request->tuple_end = tuple_end;
+	} else {
+		/*
+		 * If the first field is not nil, update the space
+		 * sequence with its value, to make sure that an
+		 * auto increment request never tries to insert a
+		 * value that is already in the space. Note, this
+		 * code is also invoked on final recovery to restore
+		 * the sequence value from WAL.
+		 */
+		if (likely(mp_read_int64(&key, &value) == 0))
+			return sequence_update(seq, value);
+	}
+	return 0;
+}
diff --git a/src/box/request.h b/src/box/request.h
new file mode 100644
index 00000000..ff1d97e0
--- /dev/null
+++ b/src/box/request.h
@@ -0,0 +1,69 @@
+#ifndef TARANTOOL_BOX_REQUEST_H_INCLUDED
+#define TARANTOOL_BOX_REQUEST_H_INCLUDED
+/*
+ * 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 <COPYRIGHT HOLDER> ``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
+ * <COPYRIGHT HOLDER> 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.
+ */
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* defined(__cplusplus) */
+
+struct request;
+struct space;
+struct tuple;
+
+/**
+ * Convert a request accessing a secondary key to a primary
+ * key undo record, given it found a tuple.
+ * Flush iproto header of the request to be reconstructed in
+ * txn_add_redo().
+ *
+ * @param request - request to fix
+ * @param space - space corresponding to request
+ * @param found_tuple - tuple found by secondary key
+ */
+void
+request_rebind_to_primary_key(struct request *request, struct space *space,
+			      struct tuple *found_tuple);
+
+/**
+ * Handle INSERT/REPLACE in a space with a sequence attached.
+ *
+ * @param request - request to fix
+ * @param space - space corresponding to request
+ */
+int
+request_handle_sequence(struct request *request, struct space *space);
+
+#if defined(__cplusplus)
+} /* extern "C" */
+#endif /* defined(__cplusplus) */
+
+#endif /* TARANTOOL_BOX_REQUEST_H_INCLUDED */
diff --git a/src/box/space.c b/src/box/space.c
index aeebf10a..d3692094 100644
--- a/src/box/space.c
+++ b/src/box/space.c
@@ -31,14 +31,13 @@
 #include "space.h"
 #include <stdlib.h>
 #include <string.h>
-#include "tuple.h"
-#include "tuple_compare.h"
+#include "tuple_format.h"
 #include "trigger.h"
 #include "user.h"
 #include "session.h"
+#include "request.h"
 #include "xrow.h"
 #include "iproto_constants.h"
-#include "sequence.h"
 
 int
 access_check_space(struct space *space, user_access_t access)
@@ -309,125 +308,6 @@ space_def_check_compatibility(const struct space_def *old_def,
 	return 0;
 }
 
-/**
- * Convert a request accessing a secondary key to a primary key undo
- * record, given it found a tuple.
- * Flush iproto header of the request to be reconstructed in txn_add_redo().
- *
- * @param request - request to fix
- * @param space - space corresponding to request
- * @param found_tuple - tuple found by secondary key
- */
-static void
-request_rebind_to_primary_key(struct request *request, struct space *space,
-			      struct tuple *found_tuple)
-{
-	struct index *pk = space_index(space, 0);
-	assert(pk != NULL);
-	uint32_t key_len;
-	char *key = tuple_extract_key(found_tuple, pk->def->key_def, &key_len);
-	assert(key != NULL);
-	request->key = key;
-	request->key_end = key + key_len;
-	request->index_id = 0;
-	/* Clear the *body* to ensure it's rebuilt at commit. */
-	request->header = NULL;
-}
-
-/**
- * Handle INSERT/REPLACE in a space with a sequence attached.
- */
-static int
-request_handle_sequence(struct request *request, struct space *space)
-{
-	struct sequence *seq = space->sequence;
-
-	assert(seq != NULL);
-	assert(request->type == IPROTO_INSERT ||
-	       request->type == IPROTO_REPLACE);
-
-	/*
-	 * An automatically generated sequence inherits
-	 * privileges of the space it is used with.
-	 */
-	if (!seq->is_generated &&
-	    access_check_sequence(seq) != 0)
-		return -1;
-
-	struct index *pk = space_index(space, 0);
-	if (unlikely(pk == NULL))
-		return 0;
-
-	/*
-	 * Look up the first field of the primary key.
-	 */
-	const char *data = request->tuple;
-	const char *data_end = request->tuple_end;
-	int len = mp_decode_array(&data);
-	int fieldno = pk->def->key_def->parts[0].fieldno;
-	if (unlikely(len < fieldno + 1))
-		return 0;
-
-	const char *key = data;
-	if (unlikely(fieldno > 0)) {
-		do {
-			mp_next(&key);
-		} while (--fieldno > 0);
-	}
-
-	int64_t value;
-	if (mp_typeof(*key) == MP_NIL) {
-		/*
-		 * If the first field of the primary key is nil,
-		 * this is an auto increment request and we need
-		 * to replace the nil with the next value generated
-		 * by the space sequence.
-		 */
-		if (unlikely(sequence_next(seq, &value) != 0))
-			return -1;
-
-		const char *key_end = key;
-		mp_decode_nil(&key_end);
-
-		size_t buf_size = (request->tuple_end - request->tuple) +
-						mp_sizeof_uint(UINT64_MAX);
-		char *tuple = region_alloc(&fiber()->gc, buf_size);
-		if (tuple == NULL)
-			return -1;
-		char *tuple_end = mp_encode_array(tuple, len);
-
-		if (unlikely(key != data)) {
-			memcpy(tuple_end, data, key - data);
-			tuple_end += key - data;
-		}
-
-		if (value >= 0)
-			tuple_end = mp_encode_uint(tuple_end, value);
-		else
-			tuple_end = mp_encode_int(tuple_end, value);
-
-		memcpy(tuple_end, key_end, data_end - key_end);
-		tuple_end += data_end - key_end;
-
-		assert(tuple_end <= tuple + buf_size);
-
-		request->tuple = tuple;
-		request->tuple_end = tuple_end;
-	} else {
-		/*
-		 * If the first field is not nil, update the space
-		 * sequence with its value, to make sure that an
-		 * auto increment request never tries to insert a
-		 * value that is already in the space. Note, this
-		 * code is also invoked on final recovery to restore
-		 * the sequence value from WAL.
-		 */
-		if (likely(mp_read_int64(&key, &value) == 0))
-			return sequence_update(seq, value);
-	}
-	return 0;
-}
-
 int
 space_execute_dml(struct space *space, struct txn *txn,
 		  struct request *request, struct tuple **result)
-- 
2.11.0




More information about the Tarantool-patches mailing list