[PATCH v4 0/3] box: introduce hint option for memtx tree index

Vladimir Davydov vdavydov.dev at gmail.com
Wed Mar 6 12:41:03 MSK 2019


For the record. We've discussed the issue with Kostja and agreed to
try to implement comparison hints / multikey indexes with neither
templates nor macros (both implementations look rather cumbersome).
Something like the code below should do fine, but without 'if' in
memtx_tree_elem_compare (we need to move it to key_def vtab instead).
memtx_tree_index_replace, which differs for multikey and hinted tree
implementations, can be overridden via index vtab.

diff --git a/src/box/memtx_tree.c b/src/box/memtx_tree.c
index 250df7f2..3728728e 100644
--- a/src/box/memtx_tree.c
+++ b/src/box/memtx_tree.c
@@ -40,6 +40,25 @@
 #include <small/mempool.h>
 
 /**
+ * Struct that represents a memtrx tree element.
+ */
+struct memtx_tree_elem {
+	struct tuple *tuple;
+	union {
+		/**
+		 * Hint to speed up tuple comparisons
+		 * (not used for multikey indexes).
+		 */
+		uint64_t hint;
+		/**
+		 * Offset of the indexed value in 
+		 * a multikey array.
+		 */
+		uint64_t multikey_offset;
+	};
+};
+
+/**
  * Struct that is used as a key in BPS tree definition.
  */
 struct memtx_tree_key_data {
@@ -47,12 +66,40 @@ struct memtx_tree_key_data {
 	const char *key;
 	/** Number of msgpacked search fields. */
 	uint32_t part_count;
+	/** Hint to speed up comparisons. */
+	uint64_t hint;
 };
 
 /**
+ * BPS tree element comparator.
+ * @param elem1 - first element.
+ * @param elem2 - second element.
+ * @param def - key definition.
+ * @retval 0  if elem1 == elem2 in terms of def.
+ * @retval <0 if elem1 < elem2 in terms of def.
+ * @retval >0 if elem1 > elem2 in terms of def.
+ */
+static int
+memtx_tree_compare(const struct memtx_tree_elem elem1,
+		   const struct memtx_tree_elem elem2,
+		   struct key_def *def)
+{
+	if (!def->has_multikey) {
+		if (elem1.hint != elem2.hint)
+			return elem1.hint - elem2.hint;
+		else
+			return tuple_compare(elem1.tuple, elem2.tuple, def);
+	} else {
+		return tuple_compare_multikey(elem1.tuple, elem1.mutlikey_offset,
+					      elem2.tuple, elem2.mutlikey_offset,
+					      def);
+	}
+}
+
+/**
  * BPS tree element vs key comparator.
  * Defined in header in order to allow compiler to inline it.
- * @param tuple - tuple to compare.
+ * @param elem - element to compare.
  * @param key_data - key to compare with.
  * @param def - key definition.
  * @retval 0  if tuple == key in terms of def.
@@ -60,20 +107,29 @@ struct memtx_tree_key_data {
  * @retval >0 if tuple > key in terms of def.
  */
 static int
-memtx_tree_compare_key(const struct tuple *tuple,
+memtx_tree_compare_key(const struct memtx_tree_elem elem,
 		       const struct memtx_tree_key_data *key_data,
 		       struct key_def *def)
 {
-	return tuple_compare_with_key(tuple, key_data->key,
-				      key_data->part_count, def);
+	if (!def->has_multikey) {
+		if (elem.hint != key_data.hint)
+			return elem.hint - key_data.hint;
+		else
+			return tuple_compare_with_key(elem.tuple, key_data->key,
+						      key_data->part_count, def);
+	} else {
+		return tuple_compare_with(elem.tuple, elem.multikey_offset,
+					  key_data->key, key_data->part_count
+					  def);
+	}
 }
 
 #define BPS_TREE_NAME memtx_tree
 #define BPS_TREE_BLOCK_SIZE (512)
 #define BPS_TREE_EXTENT_SIZE MEMTX_EXTENT_SIZE
-#define BPS_TREE_COMPARE(a, b, arg) tuple_compare(a, b, arg)
+#define BPS_TREE_COMPARE(a, b, arg) memtx_tree_compare(a, b, arg)
 #define BPS_TREE_COMPARE_KEY(a, b, arg) memtx_tree_compare_key(a, b, arg)
-#define bps_tree_elem_t struct tuple *
+#define bps_tree_elem_t struct memtx_tree_elem
 #define bps_tree_key_t struct memtx_tree_key_data *
 #define bps_tree_arg_t struct key_def *



More information about the Tarantool-patches mailing list