[patches] [PATCH 2/3] tuple: check key for sequential parts on compile time

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


Closes #2048

Signed-off-by: Vladislav Shpilevoy <v.shpilevoy at tarantool.org>
---
 src/box/tuple_extract_key.cc | 68 ++++++++++++++++++++++++++++++--------------
 1 file changed, 47 insertions(+), 21 deletions(-)

diff --git a/src/box/tuple_extract_key.cc b/src/box/tuple_extract_key.cc
index 83006a179..8765c16b5 100644
--- a/src/box/tuple_extract_key.cc
+++ b/src/box/tuple_extract_key.cc
@@ -56,6 +56,7 @@ tuple_extract_key_sequential(const struct tuple *tuple,
  * General-purpose implementation of tuple_extract_key()
  * @copydoc tuple_extract_key()
  */
+template <bool contains_sequential_parts>
 static char *
 tuple_extract_key_slowpath(const struct tuple *tuple,
 			   const struct key_def *key_def, uint32_t *key_size)
@@ -72,17 +73,21 @@ tuple_extract_key_slowpath(const struct tuple *tuple,
 			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;
+		if (contains_sequential_parts) {
+			/*
+			 * 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);
 		}
 		mp_next(&end);
 		bsize += end - field;
@@ -99,17 +104,21 @@ tuple_extract_key_slowpath(const struct tuple *tuple,
 			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;
+		if (contains_sequential_parts) {
+			/*
+			 * 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);
 		}
 		mp_next(&end);
 		bsize = end - field;
@@ -180,6 +189,17 @@ tuple_extract_key_slowpath_raw(const char *data, const char *data_end,
 	return key;
 }
 
+/** True, if a key con contain two or more parts in sequence. */
+static bool
+key_def_contains_sequential_parts(struct key_def *def)
+{
+	for (uint32_t i = 0; i < def->part_count - 1; ++i) {
+		if (def->parts[i].fieldno + 1 == def->parts[i + 1].fieldno)
+			return true;
+	}
+	return false;
+}
+
 /**
  * Initialize tuple_extract_key() and tuple_extract_key_raw()
  */
@@ -190,7 +210,13 @@ tuple_extract_key_set(struct key_def *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;
+		if (key_def_contains_sequential_parts(key_def)) {
+			key_def->tuple_extract_key =
+				tuple_extract_key_slowpath<true>;
+		} else {
+			key_def->tuple_extract_key =
+				tuple_extract_key_slowpath<false>;
+		}
 		key_def->tuple_extract_key_raw = tuple_extract_key_slowpath_raw;
 	}
 }
-- 
2.14.3 (Apple Git-98)




More information about the Tarantool-patches mailing list