[patches] [PATCH 1/3] tuple: move tuple_extract_key functions to a separate .cc file

Vladislav Shpilevoy v.shpilevoy at tarantool.org
Sat Feb 10 00:54:42 MSK 2018


Needed for #2048

Signed-off-by: Vladislav Shpilevoy <v.shpilevoy at tarantool.org>
---
 src/CMakeLists.txt           |   1 +
 src/box/CMakeLists.txt       |   1 +
 src/box/index.cc             |   1 +
 src/box/key_def.cc           |   1 +
 src/box/memtx_space.c        |   1 +
 src/box/request.c            |   1 +
 src/box/space.c              |   1 +
 src/box/tuple.c              | 194 ------------------------------------------
 src/box/tuple.h              |  59 -------------
 src/box/tuple_extract_key.cc | 196 +++++++++++++++++++++++++++++++++++++++++++
 src/box/tuple_extract_key.h  | 108 ++++++++++++++++++++++++
 src/box/vinyl.c              |   1 +
 src/box/vy_run.c             |   2 +-
 src/box/vy_stmt.c            |   1 +
 14 files changed, 314 insertions(+), 254 deletions(-)
 create mode 100644 src/box/tuple_extract_key.cc
 create mode 100644 src/box/tuple_extract_key.h

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e5acef738..b947a67c0 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -185,6 +185,7 @@ set(api_headers
     ${CMAKE_SOURCE_DIR}/src/box/tuple.h
     ${CMAKE_SOURCE_DIR}/src/box/tuple_format.h
     ${CMAKE_SOURCE_DIR}/src/box/tuple_compare.h
+    ${CMAKE_SOURCE_DIR}/src/box/tuple_extract_key.h
     ${CMAKE_SOURCE_DIR}/src/box/schema_def.h
     ${CMAKE_SOURCE_DIR}/src/box/box.h
     ${CMAKE_SOURCE_DIR}/src/box/index.h
diff --git a/src/box/CMakeLists.txt b/src/box/CMakeLists.txt
index bdbbbb075..c7ca34b89 100644
--- a/src/box/CMakeLists.txt
+++ b/src/box/CMakeLists.txt
@@ -35,6 +35,7 @@ add_library(tuple STATIC
     tuple_format.c
     tuple_update.c
     tuple_compare.cc
+    tuple_extract_key.cc
     tuple_hash.cc
     tuple_dictionary.c
     key_def.cc
diff --git a/src/box/index.cc b/src/box/index.cc
index 69fc76116..5e3128556 100644
--- a/src/box/index.cc
+++ b/src/box/index.cc
@@ -38,6 +38,7 @@
 #include "txn.h"
 #include "rmean.h"
 #include "info.h"
+#include "tuple_extract_key.h"
 
 /* {{{ Utilities. **********************************************/
 
diff --git a/src/box/key_def.cc b/src/box/key_def.cc
index f7f6c753a..7f00b82df 100644
--- a/src/box/key_def.cc
+++ b/src/box/key_def.cc
@@ -30,6 +30,7 @@
  */
 #include "key_def.h"
 #include "tuple_compare.h"
+#include "tuple_extract_key.h"
 #include "tuple_hash.h"
 #include "column_mask.h"
 #include "schema_def.h"
diff --git a/src/box/memtx_space.c b/src/box/memtx_space.c
index 92b7a468c..32f7e61f9 100644
--- a/src/box/memtx_space.c
+++ b/src/box/memtx_space.c
@@ -33,6 +33,7 @@
 #include "iproto_constants.h"
 #include "txn.h"
 #include "tuple_compare.h"
+#include "tuple_extract_key.h"
 #include "tuple_update.h"
 #include "xrow.h"
 #include "memtx_hash.h"
diff --git a/src/box/request.c b/src/box/request.c
index 646da4262..6518770ba 100644
--- a/src/box/request.c
+++ b/src/box/request.c
@@ -42,6 +42,7 @@
 #include "sequence.h"
 #include "key_def.h"
 #include "tuple.h"
+#include "tuple_extract_key.h"
 #include "xrow.h"
 #include "iproto_constants.h"
 
diff --git a/src/box/space.c b/src/box/space.c
index 11fd2c17d..7b84cc9f1 100644
--- a/src/box/space.c
+++ b/src/box/space.c
@@ -33,6 +33,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include "tuple_format.h"
+#include "tuple_extract_key.h"
 #include "trigger.h"
 #include "user.h"
 #include "session.h"
diff --git a/src/box/tuple.c b/src/box/tuple.c
index 40a091c13..d4760f3b1 100644
--- a/src/box/tuple.c
+++ b/src/box/tuple.c
@@ -184,200 +184,6 @@ tuple_next(struct tuple_iterator *it)
 	return NULL;
 }
 
-/**
- * Optimized version of tuple_extract_key_raw() for sequential key defs
- * @copydoc tuple_extract_key_raw()
- */
-static char *
-tuple_extract_key_sequential_raw(const char *data, const char *data_end,
-				 const struct key_def *key_def,
-				 uint32_t *key_size)
-{
-	assert(key_def_is_sequential(key_def));
-	const char *field_start = data;
-	uint32_t bsize = mp_sizeof_array(key_def->part_count);
-
-	mp_decode_array(&field_start);
-	const char *field_end = field_start;
-
-	for (uint32_t i = 0; i < key_def->part_count; i++)
-		mp_next(&field_end);
-	bsize += field_end - field_start;
-
-	assert(!data_end || (field_end - field_start <= data_end - data));
-	(void) data_end;
-
-	char *key = (char *) region_alloc(&fiber()->gc, bsize);
-	if (key == NULL) {
-		diag_set(OutOfMemory, bsize, "region",
-			"tuple_extract_key_raw_sequential");
-		return NULL;
-	}
-	char *key_buf = mp_encode_array(key, key_def->part_count);
-	memcpy(key_buf, field_start, field_end - field_start);
-
-	if (key_size != NULL)
-		*key_size = bsize;
-	return key;
-}
-
-/**
- * Optimized version of tuple_extract_key() for sequential key defs
- * @copydoc tuple_extract_key()
- */
-static inline char *
-tuple_extract_key_sequential(const struct tuple *tuple,
-			     const struct key_def *key_def,
-			     uint32_t *key_size)
-{
-	assert(key_def_is_sequential(key_def));
-	const char *data = tuple_data(tuple);
-	return tuple_extract_key_sequential_raw(data, NULL, key_def, key_size);
-}
-
-/**
- * General-purpose implementation of tuple_extract_key()
- * @copydoc tuple_extract_key()
- */
-static char *
-tuple_extract_key_slowpath(const struct tuple *tuple,
-			   const struct key_def *key_def, uint32_t *key_size)
-{
-	const char *data = tuple_data(tuple);
-	uint32_t part_count = key_def->part_count;
-	uint32_t bsize = mp_sizeof_array(part_count);
-	const struct tuple_format *format = tuple_format(tuple);
-	const uint32_t *field_map = tuple_field_map(tuple);
-
-	/* Calculate the key size. */
-	for (uint32_t i = 0; i < part_count; ++i) {
-		const char *field =
-			tuple_field_raw(format, data, field_map,
-					key_def->parts[i].fieldno);
-		const char *end = field;
-		/*
-		 * Skip sequential part in order to minimize
-		 * tuple_field_raw() calls.
-		 */
-		for (; i < key_def->part_count - 1; i++) {
-			if (key_def->parts[i].fieldno + 1 !=
-				key_def->parts[i + 1].fieldno) {
-				/* End of sequential part */
-				break;
-			}
-			mp_next(&end);
-		}
-		mp_next(&end);
-		bsize += end - field;
-	}
-
-	char *key = (char *) region_alloc(&fiber()->gc, bsize);
-	if (key == NULL) {
-		diag_set(OutOfMemory, bsize, "region", "tuple_extract_key");
-		return NULL;
-	}
-	char *key_buf = mp_encode_array(key, part_count);
-	for (uint32_t i = 0; i < part_count; ++i) {
-		const char *field =
-			tuple_field_raw(format, data, field_map,
-					key_def->parts[i].fieldno);
-		const char *end = field;
-		/*
-		 * Skip sequential part in order to minimize
-		 * tuple_field_raw() calls
-		 */
-		for (; i < key_def->part_count - 1; i++) {
-			if (key_def->parts[i].fieldno + 1 !=
-				key_def->parts[i + 1].fieldno) {
-				/* End of sequential part */
-				break;
-			}
-			mp_next(&end);
-		}
-		mp_next(&end);
-		bsize = end - field;
-		memcpy(key_buf, field, bsize);
-		key_buf += bsize;
-	}
-	if (key_size != NULL)
-		*key_size = key_buf - key;
-	return key;
-}
-
-/**
- * General-purpose version of tuple_extract_key_raw()
- * @copydoc tuple_extract_key_raw()
- */
-static char *
-tuple_extract_key_slowpath_raw(const char *data, const char *data_end,
-			       const struct key_def *key_def,
-			       uint32_t *key_size)
-{
-	/* allocate buffer with maximal possible size */
-	char *key = (char *) region_alloc(&fiber()->gc, data_end - data);
-	if (key == NULL) {
-		diag_set(OutOfMemory, data_end - data, "region",
-			 "tuple_extract_key_raw");
-		return NULL;
-	}
-	char *key_buf = mp_encode_array(key, key_def->part_count);
-	const char *field0 = data;
-	mp_decode_array(&field0);
-	const char *field0_end = field0;
-	mp_next(&field0_end);
-	const char *field = field0;
-	const char *field_end = field0_end;
-	uint32_t current_fieldno = 0;
-	for (uint32_t i = 0; i < key_def->part_count; i++) {
-		uint32_t fieldno = key_def->parts[i].fieldno;
-		for (; i < key_def->part_count - 1; i++) {
-			if (key_def->parts[i].fieldno + 1 !=
-			    key_def->parts[i + 1].fieldno)
-				break;
-		}
-		if (fieldno < current_fieldno) {
-			/* Rewind. */
-			field = field0;
-			field_end = field0_end;
-			current_fieldno = 0;
-		}
-
-		while (current_fieldno < fieldno) {
-			/* search first field of key in tuple raw data */
-			field = field_end;
-			mp_next(&field_end);
-			current_fieldno++;
-		}
-
-		while (current_fieldno < key_def->parts[i].fieldno) {
-			/* search the last field in subsequence */
-			mp_next(&field_end);
-			current_fieldno++;
-		}
-		memcpy(key_buf, field, field_end - field);
-		key_buf += field_end - field;
-		assert(key_buf - key <= data_end - data);
-	}
-	if (key_size != NULL)
-		*key_size = (uint32_t)(key_buf - key);
-	return key;
-}
-
-/**
- * Initialize tuple_extract_key() and tuple_extract_key_raw()
- */
-void
-tuple_extract_key_set(struct key_def *key_def)
-{
-	if (key_def_is_sequential(key_def)) {
-		key_def->tuple_extract_key = tuple_extract_key_sequential;
-		key_def->tuple_extract_key_raw = tuple_extract_key_sequential_raw;
-	} else {
-		key_def->tuple_extract_key = tuple_extract_key_slowpath;
-		key_def->tuple_extract_key_raw = tuple_extract_key_slowpath_raw;
-	}
-}
-
 int
 tuple_init(field_name_hash_f hash)
 {
diff --git a/src/box/tuple.h b/src/box/tuple.h
index 27c475056..6ebedf5f2 100644
--- a/src/box/tuple.h
+++ b/src/box/tuple.h
@@ -285,20 +285,6 @@ box_tuple_t *
 box_tuple_upsert(const box_tuple_t *tuple, const char *expr, const
 		 char *expr_end);
 
-/**
- * Extract key from tuple according to key definition of given index.
- * Returned buffer is allocated on box_txn_alloc() with this key.
- * This function has O(n) complexity, where n is the number of key parts.
- * @param tuple tuple from which need to extract key
- * @param space_id space identifier
- * @param index_id index identifier
- * @retval not NULL Success
- * @retval NULL Memory allocation error
- */
-char *
-box_tuple_extract_key(const box_tuple_t *tuple, uint32_t space_id,
-		      uint32_t index_id, uint32_t *key_size);
-
 /** \endcond public */
 
 /**
@@ -409,51 +395,6 @@ tuple_snprint(char *buf, int size, const struct tuple *tuple);
 const char *
 tuple_str(const struct tuple *tuple);
 
-/**
- * Initialize key extraction functions in the key_def
- * @param key_def key definition
- */
-void
-tuple_extract_key_set(struct key_def *key_def);
-
-/* Extract key from tuple by given key definition and return
- * buffer allocated on box_txn_alloc with this key. This function
- * has O(n) complexity, where n is the number of key parts.
- * @param tuple - tuple from which need to extract key
- * @param key_def - definition of key that need to extract
- * @param key_size - here will be size of extracted key
- *
- * @retval not NULL Success
- * @retval NULL     Memory allocation error
- */
-static inline char *
-tuple_extract_key(const struct tuple *tuple, const struct key_def *key_def,
-		  uint32_t *key_size)
-{
-	return key_def->tuple_extract_key(tuple, key_def, key_size);
-}
-
-/**
- * Extract key from raw msgpuck by given key definition and return
- * buffer allocated on box_txn_alloc with this key.
- * This function has O(n*m) complexity, where n is the number of key parts
- * and m is the tuple size.
- * @param data - msgpuck data from which need to extract key
- * @param data_end - pointer at the end of data
- * @param key_def - definition of key that need to extract
- * @param key_size - here will be size of extracted key
- *
- * @retval not NULL Success
- * @retval NULL     Memory allocation error
- */
-static inline char *
-tuple_extract_key_raw(const char *data, const char *data_end,
-		      const struct key_def *key_def, uint32_t *key_size)
-{
-	return key_def->tuple_extract_key_raw(data, data_end, key_def,
-					      key_size);
-}
-
 /**
  * Get the format of the tuple.
  * @param tuple Tuple.
diff --git a/src/box/tuple_extract_key.cc b/src/box/tuple_extract_key.cc
new file mode 100644
index 000000000..83006a179
--- /dev/null
+++ b/src/box/tuple_extract_key.cc
@@ -0,0 +1,196 @@
+#include "tuple_extract_key.h"
+#include "fiber.h"
+
+/**
+ * Optimized version of tuple_extract_key_raw() for sequential key defs
+ * @copydoc tuple_extract_key_raw()
+ */
+static char *
+tuple_extract_key_sequential_raw(const char *data, const char *data_end,
+				 const struct key_def *key_def,
+				 uint32_t *key_size)
+{
+	assert(key_def_is_sequential(key_def));
+	const char *field_start = data;
+	uint32_t bsize = mp_sizeof_array(key_def->part_count);
+
+	mp_decode_array(&field_start);
+	const char *field_end = field_start;
+
+	for (uint32_t i = 0; i < key_def->part_count; i++)
+		mp_next(&field_end);
+	bsize += field_end - field_start;
+
+	assert(!data_end || (field_end - field_start <= data_end - data));
+	(void) data_end;
+
+	char *key = (char *) region_alloc(&fiber()->gc, bsize);
+	if (key == NULL) {
+		diag_set(OutOfMemory, bsize, "region",
+			"tuple_extract_key_raw_sequential");
+		return NULL;
+	}
+	char *key_buf = mp_encode_array(key, key_def->part_count);
+	memcpy(key_buf, field_start, field_end - field_start);
+
+	if (key_size != NULL)
+		*key_size = bsize;
+	return key;
+}
+
+/**
+ * Optimized version of tuple_extract_key() for sequential key defs
+ * @copydoc tuple_extract_key()
+ */
+static inline char *
+tuple_extract_key_sequential(const struct tuple *tuple,
+			     const struct key_def *key_def,
+			     uint32_t *key_size)
+{
+	assert(key_def_is_sequential(key_def));
+	const char *data = tuple_data(tuple);
+	return tuple_extract_key_sequential_raw(data, NULL, key_def, key_size);
+}
+
+/**
+ * General-purpose implementation of tuple_extract_key()
+ * @copydoc tuple_extract_key()
+ */
+static char *
+tuple_extract_key_slowpath(const struct tuple *tuple,
+			   const struct key_def *key_def, uint32_t *key_size)
+{
+	const char *data = tuple_data(tuple);
+	uint32_t part_count = key_def->part_count;
+	uint32_t bsize = mp_sizeof_array(part_count);
+	const struct tuple_format *format = tuple_format(tuple);
+	const uint32_t *field_map = tuple_field_map(tuple);
+
+	/* Calculate the key size. */
+	for (uint32_t i = 0; i < part_count; ++i) {
+		const char *field =
+			tuple_field_raw(format, data, field_map,
+					key_def->parts[i].fieldno);
+		const char *end = field;
+		/*
+		 * Skip sequential part in order to minimize
+		 * tuple_field_raw() calls.
+		 */
+		for (; i < key_def->part_count - 1; i++) {
+			if (key_def->parts[i].fieldno + 1 !=
+				key_def->parts[i + 1].fieldno) {
+				/* End of sequential part */
+				break;
+			}
+			mp_next(&end);
+		}
+		mp_next(&end);
+		bsize += end - field;
+	}
+
+	char *key = (char *) region_alloc(&fiber()->gc, bsize);
+	if (key == NULL) {
+		diag_set(OutOfMemory, bsize, "region", "tuple_extract_key");
+		return NULL;
+	}
+	char *key_buf = mp_encode_array(key, part_count);
+	for (uint32_t i = 0; i < part_count; ++i) {
+		const char *field =
+			tuple_field_raw(format, data, field_map,
+					key_def->parts[i].fieldno);
+		const char *end = field;
+		/*
+		 * Skip sequential part in order to minimize
+		 * tuple_field_raw() calls
+		 */
+		for (; i < key_def->part_count - 1; i++) {
+			if (key_def->parts[i].fieldno + 1 !=
+				key_def->parts[i + 1].fieldno) {
+				/* End of sequential part */
+				break;
+			}
+			mp_next(&end);
+		}
+		mp_next(&end);
+		bsize = end - field;
+		memcpy(key_buf, field, bsize);
+		key_buf += bsize;
+	}
+	if (key_size != NULL)
+		*key_size = key_buf - key;
+	return key;
+}
+
+/**
+ * General-purpose version of tuple_extract_key_raw()
+ * @copydoc tuple_extract_key_raw()
+ */
+static char *
+tuple_extract_key_slowpath_raw(const char *data, const char *data_end,
+			       const struct key_def *key_def,
+			       uint32_t *key_size)
+{
+	/* allocate buffer with maximal possible size */
+	char *key = (char *) region_alloc(&fiber()->gc, data_end - data);
+	if (key == NULL) {
+		diag_set(OutOfMemory, data_end - data, "region",
+			 "tuple_extract_key_raw");
+		return NULL;
+	}
+	char *key_buf = mp_encode_array(key, key_def->part_count);
+	const char *field0 = data;
+	mp_decode_array(&field0);
+	const char *field0_end = field0;
+	mp_next(&field0_end);
+	const char *field = field0;
+	const char *field_end = field0_end;
+	uint32_t current_fieldno = 0;
+	for (uint32_t i = 0; i < key_def->part_count; i++) {
+		uint32_t fieldno = key_def->parts[i].fieldno;
+		for (; i < key_def->part_count - 1; i++) {
+			if (key_def->parts[i].fieldno + 1 !=
+			    key_def->parts[i + 1].fieldno)
+				break;
+		}
+		if (fieldno < current_fieldno) {
+			/* Rewind. */
+			field = field0;
+			field_end = field0_end;
+			current_fieldno = 0;
+		}
+
+		while (current_fieldno < fieldno) {
+			/* search first field of key in tuple raw data */
+			field = field_end;
+			mp_next(&field_end);
+			current_fieldno++;
+		}
+
+		while (current_fieldno < key_def->parts[i].fieldno) {
+			/* search the last field in subsequence */
+			mp_next(&field_end);
+			current_fieldno++;
+		}
+		memcpy(key_buf, field, field_end - field);
+		key_buf += field_end - field;
+		assert(key_buf - key <= data_end - data);
+	}
+	if (key_size != NULL)
+		*key_size = (uint32_t)(key_buf - key);
+	return key;
+}
+
+/**
+ * Initialize tuple_extract_key() and tuple_extract_key_raw()
+ */
+void
+tuple_extract_key_set(struct key_def *key_def)
+{
+	if (key_def_is_sequential(key_def)) {
+		key_def->tuple_extract_key = tuple_extract_key_sequential;
+		key_def->tuple_extract_key_raw = tuple_extract_key_sequential_raw;
+	} else {
+		key_def->tuple_extract_key = tuple_extract_key_slowpath;
+		key_def->tuple_extract_key_raw = tuple_extract_key_slowpath_raw;
+	}
+}
diff --git a/src/box/tuple_extract_key.h b/src/box/tuple_extract_key.h
new file mode 100644
index 000000000..f404ddc46
--- /dev/null
+++ b/src/box/tuple_extract_key.h
@@ -0,0 +1,108 @@
+#ifndef TARANTOOL_BOX_TUPLE_EXTRACT_KEY_H_INCLUDED
+#define TARANTOOL_BOX_TUPLE_EXTRACT_KEY_H_INCLUDED
+/*
+ * Copyright 2010-2016, 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 "key_def.h"
+#include "tuple.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* defined(__cplusplus) */
+
+/**
+ * Initialize key extraction functions in the key_def
+ * @param key_def key definition
+ */
+void
+tuple_extract_key_set(struct key_def *key_def);
+
+/**
+ * Extract key from tuple by given key definition and return
+ * buffer allocated on box_txn_alloc with this key. This function
+ * has O(n) complexity, where n is the number of key parts.
+ * @param tuple - tuple from which need to extract key
+ * @param key_def - definition of key that need to extract
+ * @param key_size - here will be size of extracted key
+ *
+ * @retval not NULL Success
+ * @retval NULL     Memory allocation error
+ */
+static inline char *
+tuple_extract_key(const struct tuple *tuple, const struct key_def *key_def,
+		  uint32_t *key_size)
+{
+	return key_def->tuple_extract_key(tuple, key_def, key_size);
+}
+
+/**
+ * Extract key from raw msgpuck by given key definition and return
+ * buffer allocated on box_txn_alloc with this key.
+ * This function has O(n*m) complexity, where n is the number of key parts
+ * and m is the tuple size.
+ * @param data - msgpuck data from which need to extract key
+ * @param data_end - pointer at the end of data
+ * @param key_def - definition of key that need to extract
+ * @param key_size - here will be size of extracted key
+ *
+ * @retval not NULL Success
+ * @retval NULL     Memory allocation error
+ */
+static inline char *
+tuple_extract_key_raw(const char *data, const char *data_end,
+		      const struct key_def *key_def, uint32_t *key_size)
+{
+	return key_def->tuple_extract_key_raw(data, data_end, key_def,
+					      key_size);
+}
+
+/** \cond public */
+
+/**
+ * Extract key from tuple according to key definition of given index.
+ * Returned buffer is allocated on box_txn_alloc() with this key.
+ * This function has O(n) complexity, where n is the number of key parts.
+ * @param tuple tuple from which need to extract key
+ * @param space_id space identifier
+ * @param index_id index identifier
+ * @retval not NULL Success
+ * @retval NULL Memory allocation error
+ */
+char *
+box_tuple_extract_key(const box_tuple_t *tuple, uint32_t space_id,
+		      uint32_t index_id, uint32_t *key_size);
+
+/** \endcond public */
+
+#if defined(__cplusplus)
+} /* extern "C" */
+#endif /* defined(__cplusplus) */
+
+#endif /* TARANTOOL_BOX_TUPLE_EXTRACT_KEY_H_INCLUDED */
diff --git a/src/box/vinyl.c b/src/box/vinyl.c
index bd41829f1..248394239 100644
--- a/src/box/vinyl.c
+++ b/src/box/vinyl.c
@@ -72,6 +72,7 @@
 #include "checkpoint.h"
 #include "session.h"
 #include "wal.h" /* wal_mode() */
+#include "tuple_extract_key.h"
 
 /**
  * Yield after iterating over this many objects (e.g. ranges).
diff --git a/src/box/vy_run.c b/src/box/vy_run.c
index ccbb0ca1f..67059240e 100644
--- a/src/box/vy_run.c
+++ b/src/box/vy_run.c
@@ -37,7 +37,7 @@
 #include "fio.h"
 #include "cbus.h"
 #include "memory.h"
-
+#include "tuple_extract_key.h"
 #include "replication.h"
 #include "tuple_hash.h" /* for bloom filter */
 #include "xlog.h"
diff --git a/src/box/vy_stmt.c b/src/box/vy_stmt.c
index 5e38a424d..c0f692986 100644
--- a/src/box/vy_stmt.c
+++ b/src/box/vy_stmt.c
@@ -42,6 +42,7 @@
 
 #include "error.h"
 #include "tuple_format.h"
+#include "tuple_extract_key.h"
 #include "xrow.h"
 #include "fiber.h"
 
-- 
2.14.3 (Apple Git-98)




More information about the Tarantool-patches mailing list