From 742de9bfc69417ba3b9ec0e90ab249b28d49e40a Mon Sep 17 00:00:00 2001
From: Vladimir Davydov <vdavydov@tarantool.org>
Date: Tue, 16 Aug 2022 11:48:10 +0300
Subject: [PATCH] index: add index_read_view get method

We will use it in the read view Lua API. For memtx tree and hash
indexes, we add a stub function with a possibility of override if
ENABLE_READ_VIEW is set. For the sequence data space, we raise an
error if this function is called, because we aren't planning to
implement it in the EE repository.

Needed for https://github.com/tarantool/tarantool-ee/issues/197

NO_DOC=internal
NO_TEST=ee
NO_CHANGELOG=internal
---
 src/box/index.h       | 21 +++++++++++++++++++++
 src/box/memtx_hash.cc | 15 +++++++++++++++
 src/box/memtx_tree.cc | 16 ++++++++++++++++
 src/box/sequence.c    | 16 ++++++++++++++++
 4 files changed, 68 insertions(+)

diff --git a/src/box/index.h b/src/box/index.h
index a9c61e20ae..d162583e69 100644
--- a/src/box/index.h
+++ b/src/box/index.h
@@ -552,6 +552,19 @@ struct index_read_view_vtab {
 	/** Free an index read view instance. */
 	void
 	(*free)(struct index_read_view *rv);
+	/**
+	 * Look up a tuple by a full key in a read view.
+	 *
+	 * The tuple data and size are returned in the data and size arguments.
+	 * Note, the tuple may be allocated from the fiber region so one should
+	 * call region_truncate after using the data. If the key isn't found,
+	 * the data is set to NULL.
+	 *
+	 * Returns 0 on success. On error returns -1 and sets diag.
+	 */
+	int (*get_raw)(struct index_read_view *rv,
+		       const char *key, uint32_t part_count,
+		       const char **data, uint32_t *size);
 	/** Create an index read view iterator. */
 	struct index_read_view_iterator *
 	(*create_iterator)(struct index_read_view *rv, enum iterator_type type,
@@ -836,6 +849,14 @@ index_read_view_create(struct index_read_view *rv,
 void
 index_read_view_delete(struct index_read_view *rv);
 
+static inline int
+index_read_view_get_raw(struct index_read_view *rv,
+			const char *key, uint32_t part_count,
+			const char **data, uint32_t *size)
+{
+	return rv->vtab->get_raw(rv, key, part_count, data, size);
+}
+
 static inline struct index_read_view_iterator *
 index_read_view_create_iterator(struct index_read_view *rv,
 				enum iterator_type type,
diff --git a/src/box/memtx_hash.cc b/src/box/memtx_hash.cc
index a868a53a14..c6409f9aeb 100644
--- a/src/box/memtx_hash.cc
+++ b/src/box/memtx_hash.cc
@@ -504,6 +504,20 @@ hash_read_view_iterator_free(struct index_read_view_iterator *iterator)
 # include "memtx_hash_read_view.cc"
 #else /* !defined(ENABLE_READ_VIEW) */
 
+static int
+hash_read_view_get_raw(struct index_read_view *rv,
+		       const char *key, uint32_t part_count,
+		       const char **data, uint32_t *size)
+{
+	(void)rv;
+	(void)key;
+	(void)part_count;
+	(void)data;
+	(void)size;
+	unreachable();
+	return 0;
+}
+
 /** Implementation of next_raw index_read_view_iterator callback. */
 static int
 hash_read_view_iterator_next_raw(struct index_read_view_iterator *iterator,
@@ -580,6 +594,7 @@ memtx_hash_index_create_read_view(struct index *base)
 {
 	static const struct index_read_view_vtab vtab = {
 		.free = hash_read_view_free,
+		.get_raw = hash_read_view_get_raw,
 		.create_iterator = hash_read_view_create_iterator,
 	};
 	struct memtx_hash_index *index = (struct memtx_hash_index *)base;
diff --git a/src/box/memtx_tree.cc b/src/box/memtx_tree.cc
index a58b9d864a..4e8e384cba 100644
--- a/src/box/memtx_tree.cc
+++ b/src/box/memtx_tree.cc
@@ -1714,6 +1714,21 @@ tree_read_view_iterator_free(struct index_read_view_iterator *iterator)
 # include "memtx_tree_read_view.cc"
 #else /* !defined(ENABLE_READ_VIEW) */
 
+template <bool USE_HINT>
+static int
+tree_read_view_get_raw(struct index_read_view *rv,
+		       const char *key, uint32_t part_count,
+		       const char **data, uint32_t *size)
+{
+	(void)rv;
+	(void)key;
+	(void)part_count;
+	(void)data;
+	(void)size;
+	unreachable();
+	return 0;
+}
+
 /** Implementation of next_raw index_read_view_iterator callback. */
 template <bool USE_HINT>
 static int
@@ -1805,6 +1820,7 @@ memtx_tree_index_create_read_view(struct index *base)
 {
 	static const struct index_read_view_vtab vtab = {
 		.free = tree_read_view_free<USE_HINT>,
+		.get_raw = tree_read_view_get_raw<USE_HINT>,
 		.create_iterator = tree_read_view_create_iterator<USE_HINT>,
 	};
 	struct memtx_tree_index<USE_HINT> *index =
diff --git a/src/box/sequence.c b/src/box/sequence.c
index 4fcd487232..07438c8ae2 100644
--- a/src/box/sequence.c
+++ b/src/box/sequence.c
@@ -355,6 +355,21 @@ sequence_data_iterator_free(struct index_read_view_iterator *iter)
 	free(iter);
 }
 
+static inline int
+sequence_data_read_view_get_raw(struct index_read_view *rv,
+				const char *key, uint32_t part_count,
+				const char **data, uint32_t *size)
+{
+	(void)rv;
+	(void)key;
+	(void)part_count;
+	(void)data;
+	(void)size;
+	diag_set(ClientError, ER_UNSUPPORTED,
+		 "_sequence_data read view", "get()");
+	return -1;
+}
+
 /** Implementation of create_iterator index_read_view callback. */
 static struct index_read_view_iterator *
 sequence_data_iterator_create(struct index_read_view *base,
@@ -394,6 +409,7 @@ sequence_data_read_view_create(struct index *index)
 	(void)index;
 	static const struct index_read_view_vtab vtab = {
 		.free = sequence_data_read_view_free,
+		.get_raw = sequence_data_read_view_get_raw,
 		.create_iterator = sequence_data_iterator_create,
 	};
 	struct sequence_data_read_view *rv = xmalloc(sizeof(*rv));
-- 
GitLab