[PATCH 13/13] Make tuple comparison hints mandatory

Vladimir Davydov vdavydov.dev at gmail.com
Tue Apr 2 20:33:50 MSK 2019


There isn't much point in having separate versions of tuple comparators
that don't take tuple comparison hints anymore, because all hot paths
have been patched to use the hinted versions. Let's strip the _hinted
suffix from tuple_compare_hinted and others and zap un-hinted versions.
In a few remaining places in the code that still use un-hinted versions,
let's simply pass HINT_NONE.
---
 src/box/key_def.c           |   5 +-
 src/box/key_def.h           |  89 ++++-----------------
 src/box/memtx_hash.c        |   6 +-
 src/box/memtx_space.c       |   4 +-
 src/box/memtx_tree.c        |  27 +++----
 src/box/space.c             |   3 +-
 src/box/sql/analyze.c       |   5 +-
 src/box/tuple_compare.cc    | 190 +++++++++-----------------------------------
 src/box/vinyl.c             |  13 +--
 src/box/vy_cache.c          |  24 +++---
 src/box/vy_cache.h          |   6 +-
 src/box/vy_lsm.c            |  14 ++--
 src/box/vy_mem.c            |  38 +++++----
 src/box/vy_mem.h            |   8 +-
 src/box/vy_range.c          |  36 +++++----
 src/box/vy_read_iterator.c  |  43 +++++-----
 src/box/vy_read_set.c       |  18 ++---
 src/box/vy_run.c            |  80 +++++++++----------
 src/box/vy_stmt.h           |  56 ++++---------
 src/box/vy_tx.c             |  34 ++++----
 src/box/vy_upsert.c         |   3 +-
 src/box/vy_write_iterator.c |   5 +-
 22 files changed, 250 insertions(+), 457 deletions(-)

diff --git a/src/box/key_def.c b/src/box/key_def.c
index 55dcf1eb..f4a6c93c 100644
--- a/src/box/key_def.c
+++ b/src/box/key_def.c
@@ -276,7 +276,7 @@ int
 box_tuple_compare(const box_tuple_t *tuple_a, const box_tuple_t *tuple_b,
 		  box_key_def_t *key_def)
 {
-	return tuple_compare(tuple_a, tuple_b, key_def);
+	return tuple_compare(tuple_a, HINT_NONE, tuple_b, HINT_NONE, key_def);
 }
 
 int
@@ -284,7 +284,8 @@ box_tuple_compare_with_key(const box_tuple_t *tuple_a, const char *key_b,
 			   box_key_def_t *key_def)
 {
 	uint32_t part_count = mp_decode_array(&key_b);
-	return tuple_compare_with_key(tuple_a, key_b, part_count, key_def);
+	return tuple_compare_with_key(tuple_a, HINT_NONE, key_b, part_count,
+				      HINT_NONE, key_def);
 
 }
 
diff --git a/src/box/key_def.h b/src/box/key_def.h
index 7bb2986b..97ca0348 100644
--- a/src/box/key_def.h
+++ b/src/box/key_def.h
@@ -150,27 +150,18 @@ key_part_is_nullable(const struct key_part *part)
 }
 
 /** @copydoc tuple_compare_with_key() */
-typedef int (*tuple_compare_with_key_t)(const struct tuple *tuple_a,
+typedef int (*tuple_compare_with_key_t)(const struct tuple *tuple,
+					hint_t tuple_hint,
 					const char *key,
 					uint32_t part_count,
+					hint_t key_hint,
 					struct key_def *key_def);
-/** @copydoc tuple_compare_with_key_hinted() */
-typedef int (*tuple_compare_with_key_hinted_t)(const struct tuple *tuple,
-					       hint_t tuple_hint,
-					       const char *key,
-					       uint32_t part_count,
-					       hint_t key_hint,
-					       struct key_def *key_def);
 /** @copydoc tuple_compare() */
 typedef int (*tuple_compare_t)(const struct tuple *tuple_a,
+			       hint_t tuple_a_hint,
 			       const struct tuple *tuple_b,
+			       hint_t tuple_b_hint,
 			       struct key_def *key_def);
-/** @copydoc tuple_compare_hinted() */
-typedef int (*tuple_compare_hinted_t)(const struct tuple *tuple_a,
-				      hint_t tuple_a_hint,
-				      const struct tuple *tuple_b,
-				      hint_t tuple_b_hint,
-				      struct key_def *key_def);
 /** @copydoc tuple_extract_key() */
 typedef char *(*tuple_extract_key_t)(const struct tuple *tuple,
 				     struct key_def *key_def,
@@ -197,12 +188,8 @@ typedef hint_t (*key_hint_t)(const char *key, uint32_t part_count,
 struct key_def {
 	/** @see tuple_compare() */
 	tuple_compare_t tuple_compare;
-	/** @see tuple_compare_hinted() */
-	tuple_compare_hinted_t tuple_compare_hinted;
 	/** @see tuple_compare_with_key() */
 	tuple_compare_with_key_t tuple_compare_with_key;
-	/** @see tuple_compare_with_key_hinted() */
-	tuple_compare_with_key_hinted_t tuple_compare_with_key_hinted;
 	/** @see tuple_extract_key() */
 	tuple_extract_key_t tuple_extract_key;
 	/** @see tuple_extract_key_raw() */
@@ -575,19 +562,6 @@ tuple_extract_key_raw(const char *data, const char *data_end,
 }
 
 /**
- * Compare keys using the key definition.
- * @param key_a key parts with MessagePack array header
- * @param key_b key_parts with MessagePack array header
- * @param key_def key definition
- *
- * @retval 0  if key_a == key_b
- * @retval <0 if key_a < key_b
- * @retval >0 if key_a > key_b
- */
-int
-key_compare(const char *key_a, const char *key_b, struct key_def *key_def);
-
-/**
  * Compare keys using the key definition and comparison hints.
  * @param key_a key parts with MessagePack array header
  * @param key_a_hint comparison hint of @a key_a
@@ -600,25 +574,9 @@ key_compare(const char *key_a, const char *key_b, struct key_def *key_def);
  * @retval >0 if key_a > key_b
  */
 int
-key_compare_hinted(const char *key_a, hint_t key_a_hint,
-		   const char *key_b, hint_t key_b_hint,
-		   struct key_def *key_def);
-
-/**
- * Compare tuples using the key definition.
- * @param tuple_a first tuple
- * @param tuple_b second tuple
- * @param key_def key definition
- * @retval 0  if key_fields(tuple_a) == key_fields(tuple_b)
- * @retval <0 if key_fields(tuple_a) < key_fields(tuple_b)
- * @retval >0 if key_fields(tuple_a) > key_fields(tuple_b)
- */
-static inline int
-tuple_compare(const struct tuple *tuple_a, const struct tuple *tuple_b,
-	      struct key_def *key_def)
-{
-	return key_def->tuple_compare(tuple_a, tuple_b, key_def);
-}
+key_compare(const char *key_a, hint_t key_a_hint,
+	    const char *key_b, hint_t key_b_hint,
+	    struct key_def *key_def);
 
 /**
  * Compare tuples using the key definition and comparison hints.
@@ -632,30 +590,12 @@ tuple_compare(const struct tuple *tuple_a, const struct tuple *tuple_b,
  * @retval >0 if key_fields(tuple_a) > key_fields(tuple_b)
  */
 static inline int
-tuple_compare_hinted(const struct tuple *tuple_a, hint_t tuple_a_hint,
+tuple_compare(const struct tuple *tuple_a, hint_t tuple_a_hint,
 		     const struct tuple *tuple_b, hint_t tuple_b_hint,
 		     struct key_def *key_def)
 {
-	return key_def->tuple_compare_hinted(tuple_a, tuple_a_hint, tuple_b,
-					     tuple_b_hint, key_def);
-}
-
-/**
- * @brief Compare tuple with key using the key definition.
- * @param tuple tuple
- * @param key key parts without MessagePack array header
- * @param part_count the number of parts in @a key
- * @param key_def key definition
- *
- * @retval 0  if key_fields(tuple) == parts(key)
- * @retval <0 if key_fields(tuple) < parts(key)
- * @retval >0 if key_fields(tuple) > parts(key)
- */
-static inline int
-tuple_compare_with_key(const struct tuple *tuple, const char *key,
-		       uint32_t part_count, struct key_def *key_def)
-{
-	return key_def->tuple_compare_with_key(tuple, key, part_count, key_def);
+	return key_def->tuple_compare(tuple_a, tuple_a_hint, tuple_b,
+				      tuple_b_hint, key_def);
 }
 
 /**
@@ -672,13 +612,12 @@ tuple_compare_with_key(const struct tuple *tuple, const char *key,
  * @retval >0 if key_fields(tuple) > parts(key)
  */
 static inline int
-tuple_compare_with_key_hinted(const struct tuple *tuple, hint_t tuple_hint,
+tuple_compare_with_key(const struct tuple *tuple, hint_t tuple_hint,
 			      const char *key, uint32_t part_count,
 			      hint_t key_hint, struct key_def *key_def)
 {
-	return key_def->tuple_compare_with_key_hinted(tuple, tuple_hint, key,
-						      part_count, key_hint,
-						      key_def);
+	return key_def->tuple_compare_with_key(tuple, tuple_hint, key,
+					       part_count, key_hint, key_def);
 }
 
 /**
diff --git a/src/box/memtx_hash.c b/src/box/memtx_hash.c
index ff478bdc..585cf3e0 100644
--- a/src/box/memtx_hash.c
+++ b/src/box/memtx_hash.c
@@ -44,14 +44,16 @@ static inline bool
 memtx_hash_equal(struct tuple *tuple_a, struct tuple *tuple_b,
 		 struct key_def *key_def)
 {
-	return tuple_compare(tuple_a, tuple_b, key_def) == 0;
+	return tuple_compare(tuple_a, HINT_NONE,
+			     tuple_b, HINT_NONE, key_def) == 0;
 }
 
 static inline bool
 memtx_hash_equal_key(struct tuple *tuple, const char *key,
 		     struct key_def *key_def)
 {
-	return tuple_compare_with_key(tuple, key, key_def->part_count,
+	return tuple_compare_with_key(tuple, HINT_NONE, key,
+				      key_def->part_count, HINT_NONE,
 				      key_def) == 0;
 }
 
diff --git a/src/box/memtx_space.c b/src/box/memtx_space.c
index d8529fe0..73df4395 100644
--- a/src/box/memtx_space.c
+++ b/src/box/memtx_space.c
@@ -514,8 +514,8 @@ memtx_space_execute_upsert(struct space *space, struct txn *txn,
 		struct index *pk = space->index[0];
 		if (!key_update_can_be_skipped(pk->def->key_def->column_mask,
 					       column_mask) &&
-		    tuple_compare(old_tuple, stmt->new_tuple,
-				  pk->def->key_def) != 0) {
+		    tuple_compare(old_tuple, HINT_NONE, stmt->new_tuple,
+				  HINT_NONE, pk->def->key_def) != 0) {
 			/* Primary key is changed: log error and do nothing. */
 			diag_set(ClientError, ER_CANT_UPDATE_PRIMARY_KEY,
 				 pk->def->name, space_name(space));
diff --git a/src/box/memtx_tree.c b/src/box/memtx_tree.c
index fe037c54..ddace2e3 100644
--- a/src/box/memtx_tree.c
+++ b/src/box/memtx_tree.c
@@ -80,11 +80,10 @@ memtx_tree_data_identical(const struct memtx_tree_data *a,
 #define BPS_TREE_BLOCK_SIZE (512)
 #define BPS_TREE_EXTENT_SIZE MEMTX_EXTENT_SIZE
 #define BPS_TREE_COMPARE(a, b, arg)\
-	tuple_compare_hinted((&a)->tuple, (&a)->hint, (&b)->tuple,\
-			     (&b)->hint, arg)
+	tuple_compare((&a)->tuple, (&a)->hint, (&b)->tuple, (&b)->hint, arg)
 #define BPS_TREE_COMPARE_KEY(a, b, arg)\
-	tuple_compare_with_key_hinted((&a)->tuple, (&a)->hint, (b)->key,\
-				      (b)->part_count, (b)->hint, arg)
+	tuple_compare_with_key((&a)->tuple, (&a)->hint, (b)->key,\
+			       (b)->part_count, (b)->hint, arg)
 #define BPS_TREE_IDENTICAL(a, b) memtx_tree_data_identical(&a, &b)
 #define bps_tree_elem_t struct memtx_tree_data
 #define bps_tree_key_t struct memtx_tree_key_data *
@@ -125,8 +124,8 @@ memtx_tree_qcompare(const void* a, const void *b, void *c)
 	const struct memtx_tree_data *data_a = a;
 	const struct memtx_tree_data *data_b = b;
 	struct key_def *key_def = c;
-	return tuple_compare_hinted(data_a->tuple, data_a->hint, data_b->tuple,
-				    data_b->hint, key_def);
+	return tuple_compare(data_a->tuple, data_a->hint, data_b->tuple,
+			     data_b->hint, key_def);
 }
 
 /* {{{ MemtxTree Iterators ****************************************/
@@ -248,11 +247,9 @@ tree_iterator_next_equal(struct iterator *iterator, struct tuple **ret)
 		memtx_tree_iterator_get_elem(it->tree, &it->tree_iterator);
 	/* Use user key def to save a few loops. */
 	if (res == NULL ||
-	    tuple_compare_with_key_hinted(res->tuple, res->hint,
-					  it->key_data.key,
-					  it->key_data.part_count,
-					  it->key_data.hint,
-					  it->index_def->key_def) != 0) {
+	    tuple_compare_with_key(res->tuple, res->hint, it->key_data.key,
+				   it->key_data.part_count, it->key_data.hint,
+				   it->index_def->key_def) != 0) {
 		iterator->next = tree_iterator_dummie;
 		it->current.tuple = NULL;
 		*ret = NULL;
@@ -281,11 +278,9 @@ tree_iterator_prev_equal(struct iterator *iterator, struct tuple **ret)
 		memtx_tree_iterator_get_elem(it->tree, &it->tree_iterator);
 	/* Use user key def to save a few loops. */
 	if (res == NULL ||
-	    tuple_compare_with_key_hinted(res->tuple, res->hint,
-					  it->key_data.key,
-					  it->key_data.part_count,
-					  it->key_data.hint,
-					  it->index_def->key_def) != 0) {
+	    tuple_compare_with_key(res->tuple, res->hint, it->key_data.key,
+				   it->key_data.part_count, it->key_data.hint,
+				   it->index_def->key_def) != 0) {
 		iterator->next = tree_iterator_dummie;
 		it->current.tuple = NULL;
 		*ret = NULL;
diff --git a/src/box/space.c b/src/box/space.c
index 1379fa34..e201a63c 100644
--- a/src/box/space.c
+++ b/src/box/space.c
@@ -445,7 +445,8 @@ space_before_replace(struct space *space, struct txn *txn,
 	 */
 	if (pk != NULL && request_changed &&
 	    old_tuple != NULL && new_tuple != NULL &&
-	    tuple_compare(old_tuple, new_tuple, pk->def->key_def) != 0) {
+	    tuple_compare(old_tuple, HINT_NONE, new_tuple, HINT_NONE,
+			  pk->def->key_def) != 0) {
 		diag_set(ClientError, ER_CANT_UPDATE_PRIMARY_KEY,
 			 pk->def->name, space->def->name);
 		rc = -1;
diff --git a/src/box/sql/analyze.c b/src/box/sql/analyze.c
index 0663c66b..a2177f08 100644
--- a/src/box/sql/analyze.c
+++ b/src/box/sql/analyze.c
@@ -1345,8 +1345,9 @@ static int
 sample_compare(const void *a, const void *b, void *arg)
 {
 	struct key_def *def = (struct key_def *)arg;
-	return key_compare(((struct index_sample *) a)->sample_key,
-			   ((struct index_sample *) b)->sample_key, def);
+	return key_compare(((struct index_sample *) a)->sample_key, HINT_NONE,
+			   ((struct index_sample *) b)->sample_key, HINT_NONE,
+			   def);
 }
 
 /**
diff --git a/src/box/tuple_compare.cc b/src/box/tuple_compare.cc
index 055f3181..95c4ab83 100644
--- a/src/box/tuple_compare.cc
+++ b/src/box/tuple_compare.cc
@@ -447,9 +447,9 @@ tuple_compare_field_with_type(const char *field_a, enum mp_type a_type,
 
 template<bool is_nullable, bool has_optional_parts, bool has_json_paths>
 static inline int
-tuple_compare_slowpath_hinted(const struct tuple *tuple_a, hint_t tuple_a_hint,
-			      const struct tuple *tuple_b, hint_t tuple_b_hint,
-			      struct key_def *key_def)
+tuple_compare_slowpath(const struct tuple *tuple_a, hint_t tuple_a_hint,
+		       const struct tuple *tuple_b, hint_t tuple_b_hint,
+		       struct key_def *key_def)
 {
 	assert(has_json_paths == key_def->has_json_paths);
 	assert(!has_optional_parts || is_nullable);
@@ -582,17 +582,7 @@ tuple_compare_slowpath_hinted(const struct tuple *tuple_a, hint_t tuple_a_hint,
 
 template<bool is_nullable, bool has_optional_parts, bool has_json_paths>
 static inline int
-tuple_compare_slowpath(const struct tuple *tuple_a, const struct tuple *tuple_b,
-		       struct key_def *key_def)
-{
-	return tuple_compare_slowpath_hinted
-		<is_nullable, has_optional_parts, has_json_paths>
-		(tuple_a, HINT_NONE, tuple_b, HINT_NONE, key_def);
-}
-
-template<bool is_nullable, bool has_optional_parts, bool has_json_paths>
-static inline int
-tuple_compare_with_key_slowpath_hinted(const struct tuple *tuple,
+tuple_compare_with_key_slowpath(const struct tuple *tuple,
 		hint_t tuple_hint, const char *key, uint32_t part_count,
 		hint_t key_hint, struct key_def *key_def)
 {
@@ -678,16 +668,6 @@ tuple_compare_with_key_slowpath_hinted(const struct tuple *tuple,
 	return 0;
 }
 
-template<bool is_nullable, bool has_optional_parts, bool has_json_paths>
-static inline int
-tuple_compare_with_key_slowpath(const struct tuple *tuple, const char *key,
-				uint32_t part_count, struct key_def *key_def)
-{
-	return tuple_compare_with_key_slowpath_hinted
-		<is_nullable, has_optional_parts, has_json_paths>
-		(tuple, HINT_NONE, key, part_count, HINT_NONE, key_def);
-}
-
 template<bool is_nullable>
 static inline int
 key_compare_parts(const char *key_a, const char *key_b, uint32_t part_count,
@@ -746,7 +726,7 @@ key_compare_parts(const char *key_a, const char *key_b, uint32_t part_count,
 
 template<bool is_nullable, bool has_optional_parts>
 static inline int
-tuple_compare_with_key_sequential_hinted(const struct tuple *tuple,
+tuple_compare_with_key_sequential(const struct tuple *tuple,
 		hint_t tuple_hint, const char *key, uint32_t part_count,
 		hint_t key_hint, struct key_def *key_def)
 {
@@ -789,19 +769,14 @@ tuple_compare_with_key_sequential_hinted(const struct tuple *tuple,
 	return 0;
 }
 
-template<bool is_nullable, bool has_optional_parts>
-static inline int
-tuple_compare_with_key_sequential(const struct tuple *tuple, const char *key,
-				  uint32_t part_count, struct key_def *key_def)
-{
-	return tuple_compare_with_key_sequential_hinted
-		<is_nullable, has_optional_parts>
-		(tuple, HINT_NONE, key, part_count, HINT_NONE, key_def);
-}
-
 int
-key_compare(const char *key_a, const char *key_b, struct key_def *key_def)
+key_compare(const char *key_a, hint_t key_a_hint,
+	    const char *key_b, hint_t key_b_hint,
+	    struct key_def *key_def)
 {
+	int rc = hint_cmp(key_a_hint, key_b_hint);
+	if (rc != 0)
+		return rc;
 	uint32_t part_count_a = mp_decode_array(&key_a);
 	uint32_t part_count_b = mp_decode_array(&key_b);
 	assert(part_count_a <= key_def->part_count);
@@ -817,22 +792,11 @@ key_compare(const char *key_a, const char *key_b, struct key_def *key_def)
 	}
 }
 
-int
-key_compare_hinted(const char *key_a, hint_t key_a_hint,
-		   const char *key_b, hint_t key_b_hint,
-		   struct key_def *key_def)
-{
-	int rc = hint_cmp(key_a_hint, key_b_hint);
-	if (rc != 0)
-		return rc;
-	return key_compare(key_a, key_b, key_def);
-}
-
 template <bool is_nullable, bool has_optional_parts>
 static int
-tuple_compare_sequential_hinted(const struct tuple *tuple_a, hint_t tuple_a_hint,
-				const struct tuple *tuple_b, hint_t tuple_b_hint,
-				struct key_def *key_def)
+tuple_compare_sequential(const struct tuple *tuple_a, hint_t tuple_a_hint,
+			 const struct tuple *tuple_b, hint_t tuple_b_hint,
+			 struct key_def *key_def)
 {
 	assert(!has_optional_parts || is_nullable);
 	assert(has_optional_parts == key_def->has_optional_parts);
@@ -900,16 +864,6 @@ tuple_compare_sequential_hinted(const struct tuple *tuple_a, hint_t tuple_a_hint
 	return 0;
 }
 
-template <bool is_nullable, bool has_optional_parts>
-static int
-tuple_compare_sequential(const struct tuple *tuple_a,
-			 const struct tuple *tuple_b, struct key_def *key_def)
-{
-	return tuple_compare_sequential_hinted
-		<is_nullable, has_optional_parts>
-		(tuple_a, HINT_NONE, tuple_b, HINT_NONE, key_def);
-}
-
 template <int TYPE>
 static inline int
 field_compare(const char **field_a, const char **field_b);
@@ -1025,10 +979,13 @@ struct FieldCompare<IDX, TYPE>
 template <int IDX, int TYPE, int ...MORE_TYPES>
 struct TupleCompare
 {
-	static int compare(const struct tuple *tuple_a,
-			   const struct tuple *tuple_b,
+	static int compare(const struct tuple *tuple_a, hint_t tuple_a_hint,
+			   const struct tuple *tuple_b, hint_t tuple_b_hint,
 			   struct key_def *)
 	{
+		int rc = hint_cmp(tuple_a_hint, tuple_b_hint);
+		if (rc != 0)
+			return rc;
 		struct tuple_format *format_a = tuple_format(tuple_a);
 		struct tuple_format *format_b = tuple_format(tuple_b);
 		const char *field_a, *field_b;
@@ -1040,26 +997,17 @@ struct TupleCompare
 			compare(tuple_a, tuple_b, format_a,
 				format_b, field_a, field_b);
 	}
-
-	static int compare_hinted(const struct tuple *tuple_a,
-				  hint_t tuple_a_hint,
-				  const struct tuple *tuple_b,
-				  hint_t tuple_b_hint,
-				  struct key_def *key_def)
-	{
-		int rc = hint_cmp(tuple_a_hint, tuple_b_hint);
-		if (rc != 0)
-			return rc;
-		return compare(tuple_a, tuple_b, key_def);
-	}
 };
 
 template <int TYPE, int ...MORE_TYPES>
 struct TupleCompare<0, TYPE, MORE_TYPES...> {
-	static int compare(const struct tuple *tuple_a,
-			   const struct tuple *tuple_b,
+	static int compare(const struct tuple *tuple_a, hint_t tuple_a_hint,
+			   const struct tuple *tuple_b, hint_t tuple_b_hint,
 			   struct key_def *)
 	{
+		int rc = hint_cmp(tuple_a_hint, tuple_b_hint);
+		if (rc != 0)
+			return rc;
 		struct tuple_format *format_a = tuple_format(tuple_a);
 		struct tuple_format *format_b = tuple_format(tuple_b);
 		const char *field_a = tuple_data(tuple_a);
@@ -1069,30 +1017,15 @@ struct TupleCompare<0, TYPE, MORE_TYPES...> {
 		return FieldCompare<0, TYPE, MORE_TYPES...>::compare(tuple_a, tuple_b,
 					format_a, format_b, field_a, field_b);
 	}
-
-	static int compare_hinted(const struct tuple *tuple_a,
-				  hint_t tuple_a_hint,
-				  const struct tuple *tuple_b,
-				  hint_t tuple_b_hint,
-				  struct key_def *key_def)
-	{
-		int rc = hint_cmp(tuple_a_hint, tuple_b_hint);
-		if (rc != 0)
-			return rc;
-		return compare(tuple_a, tuple_b, key_def);
-	}
 };
 } /* end of anonymous namespace */
 
 struct comparator_signature {
 	tuple_compare_t f;
-	tuple_compare_hinted_t f_hinted;
 	uint32_t p[64];
 };
 #define COMPARATOR(...) \
-	{ TupleCompare<__VA_ARGS__>::compare, \
-	  TupleCompare<__VA_ARGS__>::compare_hinted, \
-	  { __VA_ARGS__, UINT32_MAX } },
+	{ TupleCompare<__VA_ARGS__>::compare, { __VA_ARGS__, UINT32_MAX } },
 
 /**
  * field1 no, field1 type, field2 no, field2 type, ...
@@ -1230,12 +1163,16 @@ template <int FLD_ID, int IDX, int TYPE, int ...MORE_TYPES>
 struct TupleCompareWithKey
 {
 	static int
-	compare(const struct tuple *tuple, const char *key,
-		uint32_t part_count, struct key_def *key_def)
+	compare(const struct tuple *tuple, hint_t tuple_hint,
+		const char *key, uint32_t part_count, hint_t key_hint,
+		struct key_def *key_def)
 	{
 		/* Part count can be 0 in wildcard searches. */
 		if (part_count == 0)
 			return 0;
+		int rc = hint_cmp(tuple_hint, key_hint);
+		if (rc != 0)
+			return rc;
 		struct tuple_format *format = tuple_format(tuple);
 		const char *field = tuple_field_raw(format, tuple_data(tuple),
 						    tuple_field_map(tuple),
@@ -1244,30 +1181,22 @@ struct TupleCompareWithKey
 				compare(tuple, key, part_count,
 					key_def, format, field);
 	}
-
-	static int
-	compare_hinted(const struct tuple *tuple, hint_t tuple_hint,
-		       const char *key, uint32_t part_count, hint_t key_hint,
-		       struct key_def *key_def)
-	{
-		int rc = hint_cmp(tuple_hint, key_hint);
-		if (rc != 0)
-			return rc;
-		return compare(tuple, key, part_count, key_def);
-	}
 };
 
 template <int TYPE, int ...MORE_TYPES>
 struct TupleCompareWithKey<0, 0, TYPE, MORE_TYPES...>
 {
-	static int compare(const struct tuple *tuple,
-				  const char *key,
-				  uint32_t part_count,
-				  struct key_def *key_def)
+	static int
+	compare(const struct tuple *tuple, hint_t tuple_hint,
+		const char *key, uint32_t part_count, hint_t key_hint,
+		struct key_def *key_def)
 	{
 		/* Part count can be 0 in wildcard searches. */
 		if (part_count == 0)
 			return 0;
+		int rc = hint_cmp(tuple_hint, key_hint);
+		if (rc != 0)
+			return rc;
 		struct tuple_format *format = tuple_format(tuple);
 		const char *field = tuple_data(tuple);
 		mp_decode_array(&field);
@@ -1275,17 +1204,6 @@ struct TupleCompareWithKey<0, 0, TYPE, MORE_TYPES...>
 			compare(tuple, key, part_count,
 				key_def, format, field);
 	}
-
-	static int
-	compare_hinted(const struct tuple *tuple, hint_t tuple_hint,
-		       const char *key, uint32_t part_count, hint_t key_hint,
-		       struct key_def *key_def)
-	{
-		int rc = hint_cmp(tuple_hint, key_hint);
-		if (rc != 0)
-			return rc;
-		return compare(tuple, key, part_count, key_def);
-	}
 };
 
 } /* end of anonymous namespace */
@@ -1293,14 +1211,11 @@ struct TupleCompareWithKey<0, 0, TYPE, MORE_TYPES...>
 struct comparator_with_key_signature
 {
 	tuple_compare_with_key_t f;
-	tuple_compare_with_key_hinted_t f_hinted;
 	uint32_t p[64];
 };
 
 #define KEY_COMPARATOR(...) \
-	{ TupleCompareWithKey<0, __VA_ARGS__>::compare, \
-	  TupleCompareWithKey<0, __VA_ARGS__>::compare_hinted, \
-	  { __VA_ARGS__ } },
+	{ TupleCompareWithKey<0, __VA_ARGS__>::compare, { __VA_ARGS__ } },
 
 static const comparator_with_key_signature cmp_wk_arr[] = {
 	KEY_COMPARATOR(0, FIELD_TYPE_UNSIGNED, 1, FIELD_TYPE_UNSIGNED, 2, FIELD_TYPE_UNSIGNED)
@@ -1681,9 +1596,7 @@ key_def_set_compare_func_fast(struct key_def *def)
 	assert(!key_def_has_collation(def));
 
 	tuple_compare_t cmp = NULL;
-	tuple_compare_hinted_t cmp_hinted = NULL;
 	tuple_compare_with_key_t cmp_wk = NULL;
-	tuple_compare_with_key_hinted_t cmp_wk_hinted = NULL;
 	bool is_sequential = key_def_is_sequential(def);
 
 	/*
@@ -1698,7 +1611,6 @@ key_def_set_compare_func_fast(struct key_def *def)
 				break;
 		if (i == def->part_count && cmp_arr[k].p[i * 2] == UINT32_MAX) {
 			cmp = cmp_arr[k].f;
-			cmp_hinted = cmp_arr[k].f_hinted;
 			break;
 		}
 	}
@@ -1711,7 +1623,6 @@ key_def_set_compare_func_fast(struct key_def *def)
 		}
 		if (i == def->part_count) {
 			cmp_wk = cmp_wk_arr[k].f;
-			cmp_wk_hinted = cmp_wk_arr[k].f_hinted;
 			break;
 		}
 	}
@@ -1719,23 +1630,15 @@ key_def_set_compare_func_fast(struct key_def *def)
 		cmp = is_sequential ?
 			tuple_compare_sequential<false, false> :
 			tuple_compare_slowpath<false, false, false>;
-		cmp_hinted = is_sequential ?
-			tuple_compare_sequential_hinted<false, false> :
-			tuple_compare_slowpath_hinted<false, false, false>;
 	}
 	if (cmp_wk == NULL) {
 		cmp_wk = is_sequential ?
 			tuple_compare_with_key_sequential<false, false> :
 			tuple_compare_with_key_slowpath<false, false, false>;
-		cmp_wk_hinted = is_sequential ?
-			tuple_compare_with_key_sequential_hinted<false, false> :
-			tuple_compare_with_key_slowpath_hinted<false, false, false>;
 	}
 
 	def->tuple_compare = cmp;
-	def->tuple_compare_hinted = cmp_hinted;
 	def->tuple_compare_with_key = cmp_wk;
-	def->tuple_compare_with_key_hinted = cmp_wk_hinted;
 }
 
 template<bool is_nullable, bool has_optional_parts>
@@ -1746,23 +1649,13 @@ key_def_set_compare_func_plain(struct key_def *def)
 	if (key_def_is_sequential(def)) {
 		def->tuple_compare = tuple_compare_sequential
 					<is_nullable, has_optional_parts>;
-		def->tuple_compare_hinted = tuple_compare_sequential_hinted
-					<is_nullable, has_optional_parts>;
 		def->tuple_compare_with_key = tuple_compare_with_key_sequential
 					<is_nullable, has_optional_parts>;
-		def->tuple_compare_with_key_hinted =
-					tuple_compare_with_key_sequential_hinted
-					<is_nullable, has_optional_parts>;
 	} else {
 		def->tuple_compare = tuple_compare_slowpath
 				<is_nullable, has_optional_parts, false>;
-		def->tuple_compare_hinted = tuple_compare_slowpath_hinted
-				<is_nullable, has_optional_parts, false>;
 		def->tuple_compare_with_key = tuple_compare_with_key_slowpath
 				<is_nullable, has_optional_parts, false>;
-		def->tuple_compare_with_key_hinted =
-					tuple_compare_with_key_slowpath_hinted
-					<is_nullable, has_optional_parts, false>;
 	}
 }
 
@@ -1773,13 +1666,8 @@ key_def_set_compare_func_json(struct key_def *def)
 	assert(def->has_json_paths);
 	def->tuple_compare = tuple_compare_slowpath
 			<is_nullable, has_optional_parts, true>;
-	def->tuple_compare_hinted = tuple_compare_slowpath_hinted
-			<is_nullable, has_optional_parts, true>;
 	def->tuple_compare_with_key = tuple_compare_with_key_slowpath
 			<is_nullable, has_optional_parts, true>;
-	def->tuple_compare_with_key_hinted =
-			tuple_compare_with_key_slowpath_hinted
-			<is_nullable, has_optional_parts, true>;
 }
 
 void
diff --git a/src/box/vinyl.c b/src/box/vinyl.c
index fc90b372..cb6bedb0 100644
--- a/src/box/vinyl.c
+++ b/src/box/vinyl.c
@@ -1354,7 +1354,8 @@ vy_get_by_secondary_tuple(struct vy_lsm *lsm, struct vy_tx *tx,
 	}
 
 	if (*result == NULL ||
-	    vy_stmt_compare(*result, tuple, lsm->cmp_def) != 0) {
+	    vy_stmt_compare(*result, HINT_NONE, tuple, HINT_NONE,
+			    lsm->cmp_def) != 0) {
 		/*
 		 * If a tuple read from a secondary index doesn't
 		 * match the tuple corresponding to it in the
@@ -1581,7 +1582,8 @@ vy_check_is_unique_secondary(struct vy_tx *tx, const struct vy_read_view **rv,
 	 * fail here.
 	 */
 	if (found != NULL && vy_stmt_type(stmt) == IPROTO_REPLACE &&
-	    vy_stmt_compare(stmt, found, lsm->pk->key_def) == 0) {
+	    vy_stmt_compare(stmt, HINT_NONE, found, HINT_NONE,
+			    lsm->pk->key_def) == 0) {
 		tuple_unref(found);
 		return 0;
 	}
@@ -1786,7 +1788,8 @@ vy_check_update(struct space *space, const struct vy_lsm *pk,
 		uint64_t column_mask)
 {
 	if (!key_update_can_be_skipped(pk->key_def->column_mask, column_mask) &&
-	    vy_stmt_compare(old_tuple, new_tuple, pk->key_def) != 0) {
+	    vy_stmt_compare(old_tuple, HINT_NONE, new_tuple, HINT_NONE,
+			    pk->key_def) != 0) {
 		diag_set(ClientError, ER_CANT_UPDATE_PRIMARY_KEY,
 			 index_name_by_id(space, pk->index_id),
 			 space_name(space));
@@ -3577,8 +3580,8 @@ vy_squash_process(struct vy_squash *squash)
 	while (!vy_mem_tree_iterator_is_invalid(&mem_itr)) {
 		struct vy_mem_tree_elem elem;
 		elem = *vy_mem_tree_iterator_get_elem(&mem->tree, &mem_itr);
-		if (vy_stmt_compare_hinted(result, hint, elem.stmt, elem.hint,
-					   lsm->cmp_def) != 0 ||
+		if (vy_stmt_compare(result, hint, elem.stmt, elem.hint,
+				    lsm->cmp_def) != 0 ||
 		    vy_stmt_type(elem.stmt) != IPROTO_UPSERT)
 			break;
 		assert(vy_stmt_lsn(elem.stmt) >= MAX_LSN);
diff --git a/src/box/vy_cache.c b/src/box/vy_cache.c
index ee3581f3..6415047c 100644
--- a/src/box/vy_cache.c
+++ b/src/box/vy_cache.c
@@ -374,10 +374,8 @@ vy_cache_add(struct vy_cache *cache, struct tuple *stmt, hint_t hint,
 		assert(*prev_check_entry != NULL);
 		struct tuple *prev_check_stmt = (*prev_check_entry)->stmt;
 		hint_t prev_check_hint = (*prev_check_entry)->hint;
-		int cmp = vy_stmt_compare_hinted(prev_stmt, prev_hint,
-						 prev_check_stmt,
-						 prev_check_hint,
-						 cache->cmp_def);
+		int cmp = vy_stmt_compare(prev_stmt, prev_hint, prev_check_stmt,
+					  prev_check_hint, cache->cmp_def);
 
 		if (entry->flags & flag) {
 			/* The found entry must be exactly prev_stmt. (2) */
@@ -611,8 +609,8 @@ vy_cache_iterator_step(struct vy_cache_iterator *itr)
 		*vy_cache_tree_iterator_get_elem(tree, &itr->curr_pos);
 
 	if (itr->iterator_type == ITER_EQ &&
-	    vy_stmt_compare_hinted(itr->key, itr->hint, entry->stmt,
-				   entry->hint, itr->cache->cmp_def)) {
+	    vy_stmt_compare(itr->key, itr->hint, entry->stmt, entry->hint,
+			    itr->cache->cmp_def)) {
 		return vy_cache_iterator_is_end_stop(itr, prev_entry);
 	}
 	itr->curr_stmt = entry->stmt;
@@ -695,8 +693,8 @@ vy_cache_iterator_seek(struct vy_cache_iterator *itr,
 	if (itr->iterator_type == ITER_EQ &&
 	    ((last_key == NULL && !exact) ||
 	     (last_key != NULL &&
-	      vy_stmt_compare_hinted(itr->key, itr->hint, entry->stmt,
-				     entry->hint, itr->cache->cmp_def) != 0)))
+	      vy_stmt_compare(itr->key, itr->hint, entry->stmt, entry->hint,
+			      itr->cache->cmp_def) != 0)))
 		return false;
 
 	itr->curr_stmt = entry->stmt;
@@ -747,9 +745,8 @@ vy_cache_iterator_skip(struct vy_cache_iterator *itr,
 	if (itr->search_started &&
 	    (itr->curr_stmt == NULL || last_stmt == NULL ||
 	     iterator_direction(itr->iterator_type) *
-	     vy_stmt_compare_hinted(itr->curr_stmt, itr->curr_hint,
-				    last_stmt, last_hint,
-				    itr->cache->cmp_def) > 0))
+	     vy_stmt_compare(itr->curr_stmt, itr->curr_hint, last_stmt,
+			     last_hint, itr->cache->cmp_def) > 0))
 		return 0;
 
 	vy_history_cleanup(history);
@@ -831,9 +828,8 @@ vy_cache_iterator_restore(struct vy_cache_iterator *itr,
 				break;
 			struct vy_cache_entry *entry =
 				*vy_cache_tree_iterator_get_elem(tree, &pos);
-			int cmp = dir * vy_stmt_compare_hinted(entry->stmt,
-							       entry->hint,
-							       key, hint, def);
+			int cmp = dir * vy_stmt_compare(entry->stmt, entry->hint,
+							key, hint, def);
 			if (cmp < 0 || (cmp == 0 && !key_belongs))
 				break;
 			if (vy_stmt_lsn(entry->stmt) <= (**itr->read_view).vlsn) {
diff --git a/src/box/vy_cache.h b/src/box/vy_cache.h
index 9be2fe68..5c89dc7e 100644
--- a/src/box/vy_cache.h
+++ b/src/box/vy_cache.h
@@ -90,8 +90,7 @@ static inline int
 vy_cache_tree_cmp(struct vy_cache_entry *a,
 		  struct vy_cache_entry *b, struct key_def *cmp_def)
 {
-	return vy_stmt_compare_hinted(a->stmt, a->hint,
-				      b->stmt, b->hint, cmp_def);
+	return vy_stmt_compare(a->stmt, a->hint, b->stmt, b->hint, cmp_def);
 }
 
 /**
@@ -101,8 +100,7 @@ static inline int
 vy_cache_tree_key_cmp(struct vy_cache_entry *a, struct vy_cache_tree_key *b,
 		      struct key_def *cmp_def)
 {
-	return vy_stmt_compare_hinted(a->stmt, a->hint,
-				      b->stmt, b->hint, cmp_def);
+	return vy_stmt_compare(a->stmt, a->hint, b->stmt, b->hint, cmp_def);
 }
 
 #define VY_CACHE_TREE_EXTENT_SIZE (16 * 1024)
diff --git a/src/box/vy_lsm.c b/src/box/vy_lsm.c
index f2f9fdaf..d109aa3c 100644
--- a/src/box/vy_lsm.c
+++ b/src/box/vy_lsm.c
@@ -415,8 +415,8 @@ vy_lsm_recover_slice(struct vy_lsm *lsm, struct vy_range *range,
 		end_hint = vy_stmt_hint(end, lsm->cmp_def);
 	}
 	if (begin != NULL && end != NULL &&
-	    vy_stmt_compare_hinted(begin, begin_hint, end, end_hint,
-				   lsm->cmp_def) >= 0) {
+	    vy_stmt_compare(begin, begin_hint, end, end_hint,
+			    lsm->cmp_def) >= 0) {
 		diag_set(ClientError, ER_INVALID_VYLOG_FILE,
 			 tt_sprintf("begin >= end for slice %lld",
 				    (long long)slice_info->id));
@@ -466,8 +466,8 @@ vy_lsm_recover_range(struct vy_lsm *lsm,
 		end_hint = vy_stmt_hint(end, lsm->cmp_def);
 	}
 	if (begin != NULL && end != NULL &&
-	    vy_stmt_compare_hinted(begin, begin_hint, end, end_hint,
-				   lsm->cmp_def) >= 0) {
+	    vy_stmt_compare(begin, begin_hint, end, end_hint,
+			    lsm->cmp_def) >= 0) {
 		diag_set(ClientError, ER_INVALID_VYLOG_FILE,
 			 tt_sprintf("begin >= end for range %lld",
 				    (long long)range_info->id));
@@ -650,9 +650,9 @@ vy_lsm_recover(struct vy_lsm *lsm, struct vy_recovery *recovery,
 		int cmp = 0;
 		if (prev != NULL &&
 		    (prev->end == NULL || range->begin == NULL ||
-		     (cmp = vy_stmt_compare_hinted(prev->end, prev->end_hint,
-						   range->begin, range->begin_hint,
-						   lsm->cmp_def)) != 0)) {
+		     (cmp = vy_stmt_compare(prev->end, prev->end_hint,
+					    range->begin, range->begin_hint,
+					    lsm->cmp_def)) != 0)) {
 			const char *errmsg = cmp > 0 ?
 				"Nearby ranges %lld and %lld overlap" :
 				"Keys between ranges %lld and %lld not spanned";
diff --git a/src/box/vy_mem.c b/src/box/vy_mem.c
index 4947df2a..96bf60fa 100644
--- a/src/box/vy_mem.c
+++ b/src/box/vy_mem.c
@@ -162,8 +162,8 @@ vy_mem_older_lsn(struct vy_mem *mem, const struct tuple *stmt, hint_t hint)
 
 	struct vy_mem_tree_elem result;
 	result = *vy_mem_tree_iterator_get_elem(&mem->tree, &itr);
-	if (vy_stmt_compare_hinted(result.stmt, result.hint,
-				   stmt, hint, mem->cmp_def) != 0)
+	if (vy_stmt_compare(result.stmt, result.hint, stmt, hint,
+			    mem->cmp_def) != 0)
 		return NULL;
 	return result.stmt;
 }
@@ -214,8 +214,8 @@ vy_mem_insert_upsert(struct vy_mem *mem, const struct tuple *stmt, hint_t hint)
 	struct vy_mem_tree_elem older;
 	older = *vy_mem_tree_iterator_get_elem(&mem->tree, &inserted);
 	if (vy_stmt_type(older.stmt) != IPROTO_UPSERT ||
-	    vy_stmt_compare_hinted(stmt, hint, older.stmt, older.hint,
-				   mem->cmp_def) != 0)
+	    vy_stmt_compare(stmt, hint, older.stmt, older.hint,
+			    mem->cmp_def) != 0)
 		return 0;
 	uint8_t n_upserts = vy_stmt_n_upserts(older.stmt);
 	/*
@@ -333,9 +333,8 @@ vy_mem_iterator_find_lsn(struct vy_mem_iterator *itr)
 	       vy_stmt_flags(itr->curr.stmt) & VY_STMT_SKIP_READ) {
 		if (vy_mem_iterator_step(itr) != 0 ||
 		    (itr->iterator_type == ITER_EQ &&
-		     vy_stmt_compare_hinted(itr->key, itr->hint,
-					    itr->curr.stmt, itr->curr.hint,
-					    cmp_def) != 0)) {
+		     vy_stmt_compare(itr->key, itr->hint, itr->curr.stmt,
+				     itr->curr.hint, cmp_def) != 0)) {
 			itr->curr = vy_mem_tree_elem_invalid();
 			return 1;
 		}
@@ -356,8 +355,8 @@ vy_mem_iterator_find_lsn(struct vy_mem_iterator *itr)
 	struct vy_mem_tree_elem prev;
 	prev = *vy_mem_tree_iterator_get_elem(&itr->mem->tree, &prev_pos);
 	if (vy_stmt_lsn(prev.stmt) > (**itr->read_view).vlsn ||
-	    vy_stmt_compare_hinted(itr->curr.stmt, itr->curr.hint,
-				   prev.stmt, prev.hint, cmp_def) != 0) {
+	    vy_stmt_compare(itr->curr.stmt, itr->curr.hint,
+			    prev.stmt, prev.hint, cmp_def) != 0) {
 		/*
 		 * The next statement is either invisible in
 		 * the read view or for another key.
@@ -447,9 +446,8 @@ vy_mem_iterator_seek(struct vy_mem_iterator *itr, const struct tuple *last_key,
 	if (itr->iterator_type == ITER_EQ &&
 	    ((last_key == NULL && !exact) ||
 	     (last_key != NULL &&
-	      vy_stmt_compare_hinted(itr->key, itr->hint,
-				     itr->curr.stmt, itr->curr.hint,
-				     itr->mem->cmp_def) != 0))) {
+	      vy_stmt_compare(itr->key, itr->hint, itr->curr.stmt,
+			      itr->curr.hint, itr->mem->cmp_def) != 0))) {
 		itr->curr = vy_mem_tree_elem_invalid();
 		return 1;
 	}
@@ -511,13 +509,13 @@ vy_mem_iterator_next_key(struct vy_mem_iterator *itr)
 	 * for this key so instead of iterating further we simply
 	 * look up the next key - it's pretty cheap anyway.
 	 */
-	if (vy_stmt_compare_hinted(prev.stmt, prev.hint, itr->curr.stmt,
-				   itr->curr.hint, cmp_def) == 0)
+	if (vy_stmt_compare(prev.stmt, prev.hint, itr->curr.stmt,
+			    itr->curr.hint, cmp_def) == 0)
 		return vy_mem_iterator_seek(itr, itr->curr.stmt, itr->curr.hint);
 
 	if (itr->iterator_type == ITER_EQ &&
-	    vy_stmt_compare_hinted(itr->key, itr->hint, itr->curr.stmt,
-				   itr->curr.hint, cmp_def) != 0) {
+	    vy_stmt_compare(itr->key, itr->hint, itr->curr.stmt,
+			    itr->curr.hint, cmp_def) != 0) {
 		itr->curr = vy_mem_tree_elem_invalid();
 		return 1;
 	}
@@ -548,8 +546,8 @@ next:
 
 	struct vy_mem_tree_elem next;
 	next = *vy_mem_tree_iterator_get_elem(&itr->mem->tree, &next_pos);
-	if (vy_stmt_compare_hinted(itr->curr.stmt, itr->curr.hint,
-				   next.stmt, next.hint, cmp_def) != 0)
+	if (vy_stmt_compare(itr->curr.stmt, itr->curr.hint,
+			    next.stmt, next.hint, cmp_def) != 0)
 		return 1;
 
 	itr->curr_pos = next_pos;
@@ -603,8 +601,8 @@ vy_mem_iterator_skip(struct vy_mem_iterator *itr,
 	if (itr->search_started &&
 	    (itr->curr.stmt == NULL || last_stmt == NULL ||
 	     iterator_direction(itr->iterator_type) *
-	     vy_stmt_compare_hinted(itr->curr.stmt, itr->curr.hint, last_stmt,
-				    last_hint, itr->mem->cmp_def) > 0))
+	     vy_stmt_compare(itr->curr.stmt, itr->curr.hint, last_stmt,
+			     last_hint, itr->mem->cmp_def) > 0))
 		return 0;
 
 	vy_history_cleanup(history);
diff --git a/src/box/vy_mem.h b/src/box/vy_mem.h
index 360e1d9c..5c6b055d 100644
--- a/src/box/vy_mem.h
+++ b/src/box/vy_mem.h
@@ -121,8 +121,8 @@ static int
 vy_mem_tree_cmp(struct vy_mem_tree_elem a, struct vy_mem_tree_elem b,
 		struct key_def *cmp_def)
 {
-	int res = vy_stmt_compare_hinted(a.stmt, a.hint,
-					 b.stmt, b.hint, cmp_def);
+	int res = vy_stmt_compare(a.stmt, a.hint,
+				  b.stmt, b.hint, cmp_def);
 	if (res)
 		return res;
 	int64_t a_lsn = vy_stmt_lsn(a.stmt), b_lsn = vy_stmt_lsn(b.stmt);
@@ -136,8 +136,8 @@ static int
 vy_mem_tree_cmp_key(struct vy_mem_tree_elem elem, struct vy_mem_tree_key *key,
 		    struct key_def *cmp_def)
 {
-	int res = vy_stmt_compare_hinted(elem.stmt, elem.hint,
-					 key->stmt, key->hint, cmp_def);
+	int res = vy_stmt_compare(elem.stmt, elem.hint,
+				  key->stmt, key->hint, cmp_def);
 	if (res == 0) {
 		if (key->lsn == INT64_MAX - 1)
 			return 0;
diff --git a/src/box/vy_range.c b/src/box/vy_range.c
index edeb8a5f..f8e66655 100644
--- a/src/box/vy_range.c
+++ b/src/box/vy_range.c
@@ -63,9 +63,9 @@ vy_range_tree_cmp(struct vy_range *range_a, struct vy_range *range_b)
 		return 1;
 
 	assert(range_a->cmp_def == range_b->cmp_def);
-	return vy_stmt_compare_hinted(range_a->begin, range_a->begin_hint,
-				      range_b->begin, range_b->begin_hint,
-				      range_a->cmp_def);
+	return vy_stmt_compare(range_a->begin, range_a->begin_hint,
+			       range_b->begin, range_b->begin_hint,
+			       range_a->cmp_def);
 }
 
 int
@@ -74,8 +74,8 @@ vy_range_tree_key_cmp(struct vy_range_tree_key *key, struct vy_range *range)
 	/* Any key > -inf. */
 	if (range->begin == NULL)
 		return 1;
-	return vy_stmt_compare_hinted(key->stmt, key->hint, range->begin,
-				      range->begin_hint, range->cmp_def);
+	return vy_stmt_compare(key->stmt, key->hint, range->begin,
+			       range->begin_hint, range->cmp_def);
 }
 
 struct vy_range *
@@ -128,9 +128,8 @@ vy_range_tree_find_by_key(vy_range_tree_t *tree,
 		/* switch to previous for case (4) */
 		if (range != NULL && range->begin != NULL &&
 		    !vy_stmt_is_full_key(key, range->cmp_def) &&
-		    vy_stmt_compare_hinted(key, hint, range->begin,
-					   range->begin_hint,
-					   range->cmp_def) == 0)
+		    vy_stmt_compare(key, hint, range->begin, range->begin_hint,
+				    range->cmp_def) == 0)
 			range = vy_range_tree_prev(tree, range);
 		/* for case 5 or subcase of case 4 */
 		if (range == NULL)
@@ -164,9 +163,9 @@ vy_range_tree_find_by_key(vy_range_tree_t *tree,
 		if (range != NULL) {
 			/* fix curr_range for cases 2 and 3 */
 			if (range->begin != NULL &&
-			    vy_stmt_compare_hinted(key, hint, range->begin,
-						   range->begin_hint,
-						   range->cmp_def) != 0) {
+			    vy_stmt_compare(key, hint, range->begin,
+					    range->begin_hint,
+					    range->cmp_def) != 0) {
 				struct vy_range *prev;
 				prev = vy_range_tree_prev(tree, range);
 				if (prev != NULL)
@@ -488,7 +487,8 @@ vy_range_needs_split(struct vy_range *range, int64_t range_size,
 						slice->first_page_no);
 
 	/* No point in splitting if a new range is going to be empty. */
-	if (key_compare(first_page->min_key, mid_page->min_key,
+	if (key_compare(first_page->min_key, first_page->hint,
+			mid_page->min_key, mid_page->hint,
 			range->cmp_def) == 0)
 		return false;
 	/*
@@ -507,15 +507,19 @@ vy_range_needs_split(struct vy_range *range, int64_t range_size,
 	 *
 	 * In such cases there's no point in splitting the range.
 	 */
-	if (slice->begin != NULL && key_compare(mid_page->min_key,
-			tuple_data(slice->begin), range->cmp_def) <= 0)
+	if (slice->begin != NULL &&
+	    key_compare(mid_page->min_key, mid_page->hint,
+			tuple_data(slice->begin), slice->begin_hint,
+			range->cmp_def) <= 0)
 		return false;
 	/*
 	 * The median key can't be >= the end of the slice as we
 	 * take the min key of a page for the median key.
 	 */
-	assert(slice->end == NULL || key_compare(mid_page->min_key,
-			tuple_data(slice->end), range->cmp_def) < 0);
+	assert(slice->end == NULL ||
+	       key_compare(mid_page->min_key, mid_page->hint,
+			   tuple_data(slice->end), slice->end_hint,
+			   range->cmp_def) < 0);
 
 	*p_split_key = mid_page->min_key;
 	return true;
diff --git a/src/box/vy_read_iterator.c b/src/box/vy_read_iterator.c
index ba280f25..f56b08a4 100644
--- a/src/box/vy_read_iterator.c
+++ b/src/box/vy_read_iterator.c
@@ -149,20 +149,20 @@ vy_read_iterator_range_is_done(struct vy_read_iterator *itr,
 
 	if (dir > 0 && range->end != NULL &&
 	    (next_key == NULL ||
-	     vy_stmt_compare_hinted(next_key, next_hint, range->end,
-				    range->end_hint, cmp_def) >= 0) &&
+	     vy_stmt_compare(next_key, next_hint, range->end,
+			     range->end_hint, cmp_def) >= 0) &&
 	    (itr->iterator_type != ITER_EQ ||
-	     vy_stmt_compare_hinted(itr->key, itr->hint, range->end,
-				    range->end_hint, cmp_def) >= 0))
+	     vy_stmt_compare(itr->key, itr->hint, range->end,
+			     range->end_hint, cmp_def) >= 0))
 		return true;
 
 	if (dir < 0 && range->begin != NULL &&
 	    (next_key == NULL ||
-	     vy_stmt_compare_hinted(next_key, next_hint, range->begin,
-				    range->begin_hint, cmp_def) < 0) &&
+	     vy_stmt_compare(next_key, next_hint, range->begin,
+			     range->begin_hint, cmp_def) < 0) &&
 	    (itr->iterator_type != ITER_REQ ||
-	     vy_stmt_compare_hinted(itr->key, itr->hint, range->begin,
-				    range->begin_hint, cmp_def) <= 0))
+	     vy_stmt_compare(itr->key, itr->hint, range->begin,
+			     range->begin_hint, cmp_def) <= 0))
 		return true;
 
 	return false;
@@ -190,7 +190,7 @@ vy_read_iterator_cmp_stmt(struct vy_read_iterator *itr,
 	if (a == NULL && b == NULL)
 		return 0;
 	return iterator_direction(itr->iterator_type) *
-		vy_stmt_compare_hinted(a, a_hint, b, b_hint, itr->lsm->cmp_def);
+		vy_stmt_compare(a, a_hint, b, b_hint, itr->lsm->cmp_def);
 }
 
 /**
@@ -213,8 +213,7 @@ vy_read_iterator_is_exact_match(struct vy_read_iterator *itr,
 		(type == ITER_EQ || type == ITER_REQ ||
 		 type == ITER_GE || type == ITER_LE) &&
 		vy_stmt_is_full_key(itr->key, cmp_def) &&
-		vy_stmt_compare_hinted(stmt, hint, itr->key,
-				       itr->hint, cmp_def) == 0;
+		vy_stmt_compare(stmt, hint, itr->key, itr->hint, cmp_def) == 0;
 }
 
 /**
@@ -566,9 +565,9 @@ done:
 #ifndef NDEBUG
 	/* Check that the statement meets search criteria. */
 	if (next_key != NULL) {
-		int cmp = vy_stmt_compare_hinted(next_key, next_hint,
-						 itr->key, itr->hint,
-						 itr->lsm->cmp_def);
+		int cmp = vy_stmt_compare(next_key, next_hint,
+					  itr->key, itr->hint,
+					  itr->lsm->cmp_def);
 		cmp *= iterator_direction(itr->iterator_type);
 		if (itr->iterator_type == ITER_GT ||
 		    itr->iterator_type == ITER_LT)
@@ -586,8 +585,8 @@ done:
 	}
 #endif
 	if (itr->need_check_eq && next_key != NULL &&
-	    vy_stmt_compare_hinted(next_key, next_hint, itr->key, itr->hint,
-				   itr->lsm->cmp_def) != 0)
+	    vy_stmt_compare(next_key, next_hint, itr->key, itr->hint,
+			    itr->lsm->cmp_def) != 0)
 		itr->front_id++;
 	return 0;
 }
@@ -814,15 +813,15 @@ vy_read_iterator_next_range(struct vy_read_iterator *itr)
 		 */
 		if (dir > 0 &&
 		    (range->end == NULL ||
-		     vy_stmt_compare_hinted(itr->last_stmt, itr->last_hint,
-					    range->end, range->end_hint,
-					    cmp_def) < 0))
+		     vy_stmt_compare(itr->last_stmt, itr->last_hint,
+				     range->end, range->end_hint,
+				     cmp_def) < 0))
 			break;
 		if (dir < 0 &&
 		    (range->begin == NULL ||
-		     vy_stmt_compare_hinted(itr->last_stmt, itr->last_hint,
-					    range->begin, range->begin_hint,
-					    cmp_def) > 0))
+		     vy_stmt_compare(itr->last_stmt, itr->last_hint,
+				     range->begin, range->begin_hint,
+				     cmp_def) > 0))
 			break;
 	}
 	itr->curr_range = range;
diff --git a/src/box/vy_read_set.c b/src/box/vy_read_set.c
index 464ff060..11d33404 100644
--- a/src/box/vy_read_set.c
+++ b/src/box/vy_read_set.c
@@ -46,8 +46,8 @@ vy_read_interval_cmpl(const struct vy_read_interval *a,
 {
 	assert(a->lsm == b->lsm);
 	struct key_def *cmp_def = a->lsm->cmp_def;
-	int cmp = vy_stmt_compare_hinted(a->left, a->left_hint,
-					 b->left, b->left_hint, cmp_def);
+	int cmp = vy_stmt_compare(a->left, a->left_hint,
+				  b->left, b->left_hint, cmp_def);
 	if (cmp != 0)
 		return cmp;
 	if (a->left_belongs && !b->left_belongs)
@@ -68,8 +68,8 @@ vy_read_interval_cmpr(const struct vy_read_interval *a,
 {
 	assert(a->lsm == b->lsm);
 	struct key_def *cmp_def = a->lsm->cmp_def;
-	int cmp = vy_stmt_compare_hinted(a->right, a->right_hint,
-					 b->right, b->right_hint, cmp_def);
+	int cmp = vy_stmt_compare(a->right, a->right_hint,
+				  b->right, b->right_hint, cmp_def);
 	if (cmp != 0)
 		return cmp;
 	if (a->right_belongs && !b->right_belongs)
@@ -91,8 +91,8 @@ vy_read_interval_should_merge(const struct vy_read_interval *l,
 	assert(l->lsm == r->lsm);
 	assert(vy_read_interval_cmpl(l, r) <= 0);
 	struct key_def *cmp_def = l->lsm->cmp_def;
-	int cmp = vy_stmt_compare_hinted(l->right, l->right_hint,
-					 r->left, r->left_hint, cmp_def);
+	int cmp = vy_stmt_compare(l->right, l->right_hint,
+				  r->left, r->left_hint, cmp_def);
 	if (cmp > 0)
 		return true;
 	if (cmp < 0)
@@ -121,7 +121,7 @@ vy_tx_conflict_iterator_next(struct vy_tx_conflict_iterator *it)
 		assert(left == NULL || left->lsm == curr->lsm);
 		assert(right == NULL || right->lsm == curr->lsm);
 
-		int cmp_right = vy_stmt_compare_hinted(it->stmt, it->hint,
+		int cmp_right = vy_stmt_compare(it->stmt, it->hint,
 					last->right, last->right_hint, cmp_def);
 		if (cmp_right == 0 && !last->right_belongs)
 			cmp_right = 1;
@@ -141,7 +141,7 @@ vy_tx_conflict_iterator_next(struct vy_tx_conflict_iterator *it)
 			/* Optimize comparison out. */
 			cmp_left = cmp_right;
 		} else {
-			cmp_left = vy_stmt_compare_hinted(it->stmt, it->hint,
+			cmp_left = vy_stmt_compare(it->stmt, it->hint,
 					curr->left, curr->left_hint, cmp_def);
 			if (cmp_left == 0 && !curr->left_belongs)
 				cmp_left = -1;
@@ -169,7 +169,7 @@ vy_tx_conflict_iterator_next(struct vy_tx_conflict_iterator *it)
 			/* Optimize comparison out. */
 			cmp_right = cmp_left;
 		} else if (curr != last) {
-			cmp_right = vy_stmt_compare_hinted(it->stmt, it->hint,
+			cmp_right = vy_stmt_compare(it->stmt, it->hint,
 					curr->right, curr->right_hint, cmp_def);
 			if (cmp_right == 0 && !curr->right_belongs)
 				cmp_right = 1;
diff --git a/src/box/vy_run.c b/src/box/vy_run.c
index 2aac2b42..7c063f0a 100644
--- a/src/box/vy_run.c
+++ b/src/box/vy_run.c
@@ -343,8 +343,8 @@ vy_page_index_find_page(struct vy_run *run, enum iterator_type itype,
 	do {
 		int32_t mid = range[0] + (range[1] - range[0]) / 2;
 		struct vy_page_info *info = vy_run_page_info(run, mid);
-		int cmp = vy_stmt_compare_with_raw_key_hinted(key, hint,
-					info->min_key, info->hint, cmp_def);
+		int cmp = vy_stmt_compare_with_raw_key(key, hint, info->min_key,
+						       info->hint, cmp_def);
 		if (is_lower_bound)
 			range[cmp <= 0] = mid;
 		else
@@ -459,24 +459,24 @@ vy_slice_cut(struct vy_slice *slice, int64_t id, struct tuple *begin,
 	*result = NULL;
 
 	if (begin != NULL && slice->end != NULL &&
-	    vy_stmt_compare_hinted(begin, begin_hint, slice->end,
-				   slice->end_hint, cmp_def) >= 0)
+	    vy_stmt_compare(begin, begin_hint, slice->end,
+			    slice->end_hint, cmp_def) >= 0)
 		return 0; /* no intersection: begin >= slice->end */
 
 	if (end != NULL && slice->begin != NULL &&
-	    vy_stmt_compare_hinted(end, end_hint, slice->begin,
-				   slice->begin_hint, cmp_def) <= 0)
+	    vy_stmt_compare(end, end_hint, slice->begin,
+			    slice->begin_hint, cmp_def) <= 0)
 		return 0; /* no intersection: end <= slice->end */
 
 	/* begin = MAX(begin, slice->begin) */
 	if (slice->begin != NULL &&
-	    (begin == NULL || vy_stmt_compare_hinted(begin, begin_hint,
+	    (begin == NULL || vy_stmt_compare(begin, begin_hint,
 			slice->begin, slice->begin_hint, cmp_def) < 0))
 		begin = slice->begin;
 
 	/* end = MIN(end, slice->end) */
 	if (slice->end != NULL &&
-	    (end == NULL || vy_stmt_compare_hinted(end, end_hint,
+	    (end == NULL || vy_stmt_compare(end, end_hint,
 			slice->end, slice->end_hint, cmp_def) > 0))
 		end = slice->end;
 
@@ -1078,8 +1078,8 @@ vy_run_iterator_search_in_page(struct vy_run_iterator *itr,
 						     itr->format, &fnd_hint);
 		if (fnd_key == NULL)
 			return end;
-		int cmp = vy_stmt_compare_hinted(fnd_key, fnd_hint,
-						 key, hint, itr->cmp_def);
+		int cmp = vy_stmt_compare(fnd_key, fnd_hint, key, hint,
+					  itr->cmp_def);
 		cmp = cmp ? cmp : zero_cmp;
 		*equal_key = *equal_key || cmp == 0;
 		if (cmp < 0)
@@ -1210,8 +1210,8 @@ vy_run_iterator_find_lsn(struct vy_run_iterator *itr,
 					 &itr->curr_hint) != 0)
 			return -1;
 		if (itr->iterator_type == ITER_EQ &&
-		    vy_stmt_compare_hinted(itr->curr_stmt, itr->curr_hint,
-					   itr->key, itr->hint, cmp_def) != 0) {
+		    vy_stmt_compare(itr->curr_stmt, itr->curr_hint,
+				    itr->key, itr->hint, cmp_def) != 0) {
 			vy_run_iterator_stop(itr);
 			return 0;
 		}
@@ -1227,10 +1227,8 @@ vy_run_iterator_find_lsn(struct vy_run_iterator *itr,
 				return -1;
 			if (vy_stmt_lsn(test_stmt) > (**itr->read_view).vlsn ||
 			    vy_stmt_flags(test_stmt) & VY_STMT_SKIP_READ ||
-			    vy_stmt_compare_hinted(itr->curr_stmt,
-						   itr->curr_hint,
-						   test_stmt, test_hint,
-						   cmp_def) != 0) {
+			    vy_stmt_compare(itr->curr_stmt, itr->curr_hint,
+					    test_stmt, test_hint, cmp_def) != 0) {
 				tuple_unref(test_stmt);
 				break;
 			}
@@ -1243,9 +1241,9 @@ vy_run_iterator_find_lsn(struct vy_run_iterator *itr,
 	/* Check if the result is within the slice boundaries. */
 	if (itr->iterator_type == ITER_LE || itr->iterator_type == ITER_LT) {
 		if (slice->begin != NULL &&
-		    vy_stmt_compare_hinted(itr->curr_stmt, itr->curr_hint,
-					   slice->begin, slice->begin_hint,
-					   cmp_def) < 0) {
+		    vy_stmt_compare(itr->curr_stmt, itr->curr_hint,
+				    slice->begin, slice->begin_hint,
+				    cmp_def) < 0) {
 			vy_run_iterator_stop(itr);
 			return 0;
 		}
@@ -1254,9 +1252,9 @@ vy_run_iterator_find_lsn(struct vy_run_iterator *itr,
 		       itr->iterator_type == ITER_GT ||
 		       itr->iterator_type == ITER_EQ);
 		if (slice->end != NULL &&
-		    vy_stmt_compare_hinted(itr->curr_stmt, itr->curr_hint,
-					   slice->end, slice->end_hint,
-					   cmp_def) >= 0) {
+		    vy_stmt_compare(itr->curr_stmt, itr->curr_hint,
+				    slice->end, slice->end_hint,
+				    cmp_def) >= 0) {
 			vy_run_iterator_stop(itr);
 			return 0;
 		}
@@ -1396,8 +1394,8 @@ vy_run_iterator_seek(struct vy_run_iterator *itr, const struct tuple *last_key,
 		 *         | ge  | begin | ge  |
 		 *         | eq  |    stop     |
 		 */
-		int cmp = vy_stmt_compare_hinted(key, hint, slice->begin,
-						 slice->begin_hint, cmp_def);
+		int cmp = vy_stmt_compare(key, hint, slice->begin,
+					  slice->begin_hint, cmp_def);
 		if (cmp < 0 && iterator_type == ITER_EQ) {
 			vy_run_iterator_stop(itr);
 			return 0;
@@ -1423,8 +1421,8 @@ vy_run_iterator_seek(struct vy_run_iterator *itr, const struct tuple *last_key,
 		 * > end   | lt  | end   | lt  |
 		 *         | le  | end   | lt  |
 		 */
-		int cmp = vy_stmt_compare_hinted(key, hint, slice->end,
-						 slice->end_hint, cmp_def);
+		int cmp = vy_stmt_compare(key, hint, slice->end,
+					  slice->end_hint, cmp_def);
 		if (cmp > 0 || (cmp == 0 && iterator_type != ITER_LT)) {
 			iterator_type = ITER_LT;
 			key = slice->end;
@@ -1451,7 +1449,7 @@ vy_run_iterator_seek(struct vy_run_iterator *itr, const struct tuple *last_key,
 		return -1;
 
 	/* Check EQ constraint if necessary. */
-	if (check_eq && vy_stmt_compare_hinted(itr->curr_stmt, itr->curr_hint,
+	if (check_eq && vy_stmt_compare(itr->curr_stmt, itr->curr_hint,
 					itr->key, itr->hint, itr->cmp_def) != 0)
 		goto not_found;
 
@@ -1543,16 +1541,16 @@ vy_run_iterator_next_key(struct vy_run_iterator *itr, struct tuple **ret,
 		if (vy_run_iterator_read(itr, itr->curr_pos,
 					 &next_key, &next_hint) != 0)
 			return -1;
-	} while (vy_stmt_compare_hinted(itr->curr_stmt, itr->curr_hint,
-					next_key, next_hint, itr->cmp_def) == 0);
+	} while (vy_stmt_compare(itr->curr_stmt, itr->curr_hint,
+				 next_key, next_hint, itr->cmp_def) == 0);
 
 	tuple_unref(itr->curr_stmt);
 	itr->curr_stmt = next_key;
 	itr->curr_hint = next_hint;
 
 	if (itr->iterator_type == ITER_EQ &&
-	    vy_stmt_compare_hinted(next_key, next_hint, itr->key, itr->hint,
-				   itr->cmp_def) != 0) {
+	    vy_stmt_compare(next_key, next_hint, itr->key, itr->hint,
+			    itr->cmp_def) != 0) {
 		vy_run_iterator_stop(itr);
 		return 0;
 	}
@@ -1587,8 +1585,8 @@ next:
 	if (vy_run_iterator_read(itr, next_pos, &next_key, &next_hint) != 0)
 		return -1;
 
-	if (vy_stmt_compare_hinted(itr->curr_stmt, itr->curr_hint,
-				   next_key, next_hint, itr->cmp_def) != 0) {
+	if (vy_stmt_compare(itr->curr_stmt, itr->curr_hint,
+			    next_key, next_hint, itr->cmp_def) != 0) {
 		tuple_unref(next_key);
 		return 0;
 	}
@@ -1638,8 +1636,8 @@ vy_run_iterator_skip(struct vy_run_iterator *itr,
 	if (itr->search_started &&
 	    (itr->curr_stmt == NULL || last_stmt == NULL ||
 	     iterator_direction(itr->iterator_type) *
-	     vy_stmt_compare_hinted(itr->curr_stmt, itr->curr_hint,
-				    last_stmt, last_hint, itr->cmp_def) > 0))
+	     vy_stmt_compare(itr->curr_stmt, itr->curr_hint,
+			     last_stmt, last_hint, itr->cmp_def) > 0))
 		return 0;
 
 	vy_history_cleanup(history);
@@ -2646,10 +2644,10 @@ vy_slice_stream_search(struct vy_stmt_stream *virt_stream)
 				stream->cmp_def, stream->format, &fnd_hint);
 		if (fnd_key == NULL)
 			return -1;
-		int cmp = vy_stmt_compare_hinted(fnd_key, fnd_hint,
-						 stream->slice->begin,
-						 stream->slice->begin_hint,
-						 stream->cmp_def);
+		int cmp = vy_stmt_compare(fnd_key, fnd_hint,
+					  stream->slice->begin,
+					  stream->slice->begin_hint,
+					  stream->cmp_def);
 		if (cmp < 0)
 			beg = mid + 1;
 		else
@@ -2703,8 +2701,8 @@ vy_slice_stream_next(struct vy_stmt_stream *virt_stream,
 	/* Check that the tuple is not out of slice bounds = */
 	if (stream->slice->end != NULL &&
 	    stream->page_no >= stream->slice->last_page_no &&
-	    vy_stmt_compare_hinted(tuple, hint, stream->slice->end,
-			stream->slice->end_hint, stream->cmp_def) >= 0) {
+	    vy_stmt_compare(tuple, hint, stream->slice->end,
+			    stream->slice->end_hint, stream->cmp_def) >= 0) {
 		tuple_unref(tuple);
 		return 0;
 	}
diff --git a/src/box/vy_stmt.h b/src/box/vy_stmt.h
index 8467c2d7..ef1b25a2 100644
--- a/src/box/vy_stmt.h
+++ b/src/box/vy_stmt.h
@@ -379,57 +379,31 @@ vy_stmt_hint(const struct tuple *stmt, struct key_def *key_def)
 
 /**
  * Compare two vinyl statements taking into account their
- * formats (key or tuple).
- */
-static inline int
-vy_stmt_compare(const struct tuple *a, const struct tuple *b,
-		struct key_def *key_def)
-{
-	bool a_is_tuple = !vy_stmt_is_key(a);
-	bool b_is_tuple = !vy_stmt_is_key(b);
-	if (a_is_tuple && b_is_tuple) {
-		return tuple_compare(a, b, key_def);
-	} else if (a_is_tuple && !b_is_tuple) {
-		const char *key = tuple_data(b);
-		uint32_t part_count = mp_decode_array(&key);
-		return tuple_compare_with_key(a, key, part_count, key_def);
-	} else if (!a_is_tuple && b_is_tuple) {
-		const char *key = tuple_data(a);
-		uint32_t part_count = mp_decode_array(&key);
-		return -tuple_compare_with_key(b, key, part_count, key_def);
-	} else {
-		assert(!a_is_tuple && !b_is_tuple);
-		return key_compare(tuple_data(a), tuple_data(b), key_def);
-	}
-}
-
-/**
- * Compare two vinyl statements taking into account their
  * formats (key or tuple) and using comparison hints.
  */
 static inline int
-vy_stmt_compare_hinted(const struct tuple *a, hint_t a_hint,
-		       const struct tuple *b, hint_t b_hint,
-		       struct key_def *key_def)
+vy_stmt_compare(const struct tuple *a, hint_t a_hint,
+		const struct tuple *b, hint_t b_hint,
+		struct key_def *key_def)
 {
 	bool a_is_tuple = !vy_stmt_is_key(a);
 	bool b_is_tuple = !vy_stmt_is_key(b);
 	if (a_is_tuple && b_is_tuple) {
-		return tuple_compare_hinted(a, a_hint, b, b_hint, key_def);
+		return tuple_compare(a, a_hint, b, b_hint, key_def);
 	} else if (a_is_tuple && !b_is_tuple) {
 		const char *key = tuple_data(b);
 		uint32_t part_count = mp_decode_array(&key);
-		return tuple_compare_with_key_hinted(a, a_hint, key, part_count,
+		return tuple_compare_with_key(a, a_hint, key, part_count,
 						     b_hint, key_def);
 	} else if (!a_is_tuple && b_is_tuple) {
 		const char *key = tuple_data(a);
 		uint32_t part_count = mp_decode_array(&key);
-		return -tuple_compare_with_key_hinted(b, b_hint, key, part_count,
+		return -tuple_compare_with_key(b, b_hint, key, part_count,
 						      a_hint, key_def);
 	} else {
 		assert(!a_is_tuple && !b_is_tuple);
-		return key_compare_hinted(tuple_data(a), a_hint,
-					  tuple_data(b), b_hint, key_def);
+		return key_compare(tuple_data(a), a_hint,
+				   tuple_data(b), b_hint, key_def);
 	}
 }
 
@@ -438,17 +412,17 @@ vy_stmt_compare_hinted(const struct tuple *a, hint_t a_hint,
  * (msgpack array).
  */
 static inline int
-vy_stmt_compare_with_raw_key_hinted(const struct tuple *stmt, hint_t stmt_hint,
-				    const char *key, hint_t key_hint,
-				    struct key_def *key_def)
+vy_stmt_compare_with_raw_key(const struct tuple *stmt, hint_t stmt_hint,
+			     const char *key, hint_t key_hint,
+			     struct key_def *key_def)
 {
 	if (!vy_stmt_is_key(stmt)) {
 		uint32_t part_count = mp_decode_array(&key);
-		return tuple_compare_with_key_hinted(stmt, stmt_hint, key,
-						part_count, key_hint, key_def);
+		return tuple_compare_with_key(stmt, stmt_hint, key,
+					      part_count, key_hint, key_def);
 	}
-	return key_compare_hinted(tuple_data(stmt), stmt_hint,
-				  key, key_hint, key_def);
+	return key_compare(tuple_data(stmt), stmt_hint,
+			   key, key_hint, key_def);
 }
 
 /**
diff --git a/src/box/vy_tx.c b/src/box/vy_tx.c
index 6a3f410e..bd2c141f 100644
--- a/src/box/vy_tx.c
+++ b/src/box/vy_tx.c
@@ -68,9 +68,8 @@ write_set_cmp(struct txv *a, struct txv *b)
 {
 	int rc = a->lsm < b->lsm ? -1 : a->lsm > b->lsm;
 	if (rc == 0)
-		return vy_stmt_compare_hinted(a->stmt, a->hint,
-					      b->stmt, b->hint,
-					      a->lsm->cmp_def);
+		return vy_stmt_compare(a->stmt, a->hint, b->stmt, b->hint,
+				       a->lsm->cmp_def);
 	return rc;
 }
 
@@ -79,9 +78,8 @@ write_set_key_cmp(struct write_set_key *a, struct txv *b)
 {
 	int rc = a->lsm < b->lsm ? -1 : a->lsm > b->lsm;
 	if (rc == 0)
-		return vy_stmt_compare_hinted(a->stmt, a->hint,
-					      b->stmt, b->hint,
-					      a->lsm->cmp_def);
+		return vy_stmt_compare(a->stmt, a->hint, b->stmt, b->hint,
+				       a->lsm->cmp_def);
 	return rc;
 }
 
@@ -1207,8 +1205,8 @@ vy_txw_iterator_seek(struct vy_txw_iterator *itr, const struct tuple *last_key,
 			txv = write_set_psearch(&itr->tx->write_set, &k);
 		if (txv == NULL || txv->lsm != lsm)
 			return;
-		if (vy_stmt_compare_hinted(k.stmt, k.hint, txv->stmt, txv->hint,
-					   lsm->cmp_def) == 0) {
+		if (vy_stmt_compare(k.stmt, k.hint, txv->stmt, txv->hint,
+				    lsm->cmp_def) == 0) {
 			while (true) {
 				struct txv *next;
 				if (iterator_type == ITER_LE ||
@@ -1218,9 +1216,9 @@ vy_txw_iterator_seek(struct vy_txw_iterator *itr, const struct tuple *last_key,
 					next = write_set_prev(&itr->tx->write_set, txv);
 				if (next == NULL || next->lsm != lsm)
 					break;
-				if (vy_stmt_compare_hinted(k.stmt, k.hint,
-							   next->stmt, next->hint,
-							   lsm->cmp_def) != 0)
+				if (vy_stmt_compare(k.stmt, k.hint,
+						    next->stmt, next->hint,
+						    lsm->cmp_def) != 0)
 					break;
 				txv = next;
 			}
@@ -1238,8 +1236,8 @@ vy_txw_iterator_seek(struct vy_txw_iterator *itr, const struct tuple *last_key,
 	if (txv == NULL || txv->lsm != lsm)
 		return;
 	if (itr->iterator_type == ITER_EQ && last_key != NULL &&
-	    vy_stmt_compare_hinted(itr->key, itr->hint, txv->stmt, txv->hint,
-				   lsm->cmp_def) != 0)
+	    vy_stmt_compare(itr->key, itr->hint, txv->stmt, txv->hint,
+			    lsm->cmp_def) != 0)
 		return;
 	itr->curr_txv = txv;
 }
@@ -1264,8 +1262,8 @@ vy_txw_iterator_next(struct vy_txw_iterator *itr,
 	if (itr->curr_txv != NULL && itr->curr_txv->lsm != itr->lsm)
 		itr->curr_txv = NULL;
 	if (itr->curr_txv != NULL && itr->iterator_type == ITER_EQ &&
-	    vy_stmt_compare_hinted(itr->key, itr->hint, itr->curr_txv->stmt,
-				   itr->curr_txv->hint, itr->lsm->cmp_def) != 0)
+	    vy_stmt_compare(itr->key, itr->hint, itr->curr_txv->stmt,
+			    itr->curr_txv->hint, itr->lsm->cmp_def) != 0)
 		itr->curr_txv = NULL;
 out:
 	if (itr->curr_txv != NULL) {
@@ -1292,10 +1290,8 @@ vy_txw_iterator_skip(struct vy_txw_iterator *itr,
 	if (itr->search_started &&
 	    (itr->curr_txv == NULL || last_stmt == NULL ||
 	     iterator_direction(itr->iterator_type) *
-	     vy_stmt_compare_hinted(itr->curr_txv->stmt,
-				    itr->curr_txv->hint,
-				    last_stmt, last_hint,
-				    itr->lsm->cmp_def) > 0))
+	     vy_stmt_compare(itr->curr_txv->stmt, itr->curr_txv->hint,
+			     last_stmt, last_hint, itr->lsm->cmp_def) > 0))
 		return 0;
 
 	vy_history_cleanup(history);
diff --git a/src/box/vy_upsert.c b/src/box/vy_upsert.c
index 8cf0cc19..40eef8da 100644
--- a/src/box/vy_upsert.c
+++ b/src/box/vy_upsert.c
@@ -206,7 +206,8 @@ check_key:
 	 * Check that key hasn't been changed after applying operations.
 	 */
 	if (!key_update_can_be_skipped(cmp_def->column_mask, column_mask) &&
-	    vy_stmt_compare(old_stmt, result_stmt, cmp_def) != 0) {
+	    vy_stmt_compare(old_stmt, HINT_NONE, result_stmt, HINT_NONE,
+			    cmp_def) != 0) {
 		/*
 		 * Key has been changed: ignore this UPSERT and
 		 * @retval the old stmt.
diff --git a/src/box/vy_write_iterator.c b/src/box/vy_write_iterator.c
index a2a782fb..e02e93ac 100644
--- a/src/box/vy_write_iterator.c
+++ b/src/box/vy_write_iterator.c
@@ -235,9 +235,8 @@ heap_less(heap_t *heap, struct vy_write_src *src1, struct vy_write_src *src2)
 	struct vy_write_iterator *stream =
 		container_of(heap, struct vy_write_iterator, src_heap);
 
-	int cmp = vy_stmt_compare_hinted(src1->tuple, src1->hint,
-					 src2->tuple, src2->hint,
-					 stream->cmp_def);
+	int cmp = vy_stmt_compare(src1->tuple, src1->hint,
+				  src2->tuple, src2->hint, stream->cmp_def);
 	if (cmp != 0)
 		return cmp < 0;
 
-- 
2.11.0




More information about the Tarantool-patches mailing list