[PATCH v2 2/4] schema: add space names cache
Kirill Yukhin
kyukhin at tarantool.org
Thu Oct 25 11:17:10 MSK 2018
Since SQL is heavily using name -> space mapping,
introduce (instead of scanning _space space) dedicated
cache, which maps space name to space pointer.
---
src/box/schema.cc | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
src/box/schema.h | 8 ++++++++
2 files changed, 65 insertions(+), 1 deletion(-)
diff --git a/src/box/schema.cc b/src/box/schema.cc
index 08457a46..b931fdf 100644
--- a/src/box/schema.cc
+++ b/src/box/schema.cc
@@ -55,6 +55,7 @@
/** All existing spaces. */
static struct mh_i32ptr_t *spaces;
+static struct mh_strnptr_t *spaces_by_name;
static struct mh_i32ptr_t *funcs;
static struct mh_strnptr_t *funcs_by_name;
static struct mh_i32ptr_t *sequences;
@@ -95,6 +96,17 @@ space_by_id(uint32_t id)
return (struct space *) mh_i32ptr_node(spaces, space)->val;
}
+/** Return space by its name */
+struct space *
+space_by_name(const char *name)
+{
+ mh_int_t space = mh_strnptr_find_inp(spaces_by_name, name,
+ strlen(name));
+ if (space == mh_end(spaces_by_name))
+ return NULL;
+ return (struct space *) mh_strnptr_node(spaces_by_name, space)->val;
+}
+
/** Return current schema version */
uint32_t
box_schema_version()
@@ -165,7 +177,25 @@ void
space_cache_replace(struct space *old_space, struct space *new_space)
{
assert(new_space != NULL || old_space != NULL);
+ struct space *old_space_by_n = NULL;
if (new_space != NULL) {
+ /*
+ * If replacing is performed and space name was
+ * changed, then need to explicitly remove old
+ * entry from spaces cache.
+ * NB: Since space_id never changed - no need
+ * to do so for space_id cache.
+ */
+ if (old_space != NULL && strcmp(space_name(old_space),
+ new_space->def->name) != 0) {
+ const char *name = space_name(old_space);
+ mh_int_t k = mh_strnptr_find_inp(spaces_by_name, name,
+ strlen(name));
+ assert(k != mh_end(spaces_by_name));
+ mh_strnptr_del(spaces_by_name, k, NULL);
+ old_space_by_n = (struct space *)mh_strnptr_node(spaces_by_name,
+ k)->val;
+ }
const struct mh_i32ptr_node_t node_p = { space_id(new_space),
new_space };
struct mh_i32ptr_node_t old, *p_old = &old;
@@ -174,7 +204,23 @@ space_cache_replace(struct space *old_space, struct space *new_space)
panic_syserror("Out of memory for the data "
"dictionary cache.");
}
- assert((struct space *)p_old->val == old_space);
+ const char *name = space_name(new_space);
+ uint32_t name_len = strlen(name);
+ uint32_t hash = mh_strn_hash(name, name_len);
+ const struct mh_strnptr_node_t node_s = { name, name_len, hash,
+ new_space };
+ struct mh_strnptr_node_t old_s, *p_old_s = &old_s;
+ k = mh_strnptr_put(spaces_by_name, &node_s, &p_old_s, NULL);
+ if (k == mh_end(spaces_by_name)) {
+ panic_syserror("Out of memory for the data "
+ "dictionary cache.");
+ }
+ assert(old_space_by_n == NULL || p_old_s == NULL);
+ if(old_space_by_n == NULL && p_old != NULL) {
+ assert(p_old->val == p_old_s->val);
+ old_space_by_n = (struct space *)p_old->val;
+ }
+ assert((struct space*)old_space_by_n == old_space);
} else {
mh_int_t k = mh_i32ptr_find(spaces, space_id(old_space), NULL);
assert(k != mh_end(spaces));
@@ -183,6 +229,14 @@ space_cache_replace(struct space *old_space, struct space *new_space)
(void)old_space_by_id;
assert(old_space_by_id == old_space);
mh_i32ptr_del(spaces, k, NULL);
+ const char *name = space_name(old_space);
+ k = mh_strnptr_find_inp(spaces_by_name, name, strlen(name));
+ assert(k != mh_end(spaces_by_name));
+ old_space_by_n = (struct space *)mh_strnptr_node(spaces_by_name,
+ k)->val;
+ assert(old_space_by_n == old_space_by_id);
+ (void)old_space_by_id;
+ mh_strnptr_del(spaces_by_name, k, NULL);
}
space_cache_version++;
}
@@ -302,6 +356,7 @@ schema_init()
/* Initialize the space cache. */
spaces = mh_i32ptr_new();
+ spaces_by_name = mh_strnptr_new();
funcs = mh_i32ptr_new();
funcs_by_name = mh_strnptr_new();
sequences = mh_i32ptr_new();
@@ -449,6 +504,7 @@ schema_free(void)
space_cache_replace(space, NULL);
}
mh_i32ptr_delete(spaces);
+ mh_strnptr_delete(spaces_by_name);
while (mh_size(funcs) > 0) {
mh_int_t i = mh_first(funcs);
diff --git a/src/box/schema.h b/src/box/schema.h
index 05f32de..89866a8 100644
--- a/src/box/schema.h
+++ b/src/box/schema.h
@@ -58,6 +58,14 @@ extern struct latch schema_lock;
struct space *
space_by_id(uint32_t id);
+/**
+ * Try to look up a space by space name in the space name cache.
+ *
+ * @return NULL if space not found, otherwise space object.
+ */
+struct space *
+space_by_name(const char *name);
+
uint32_t
box_schema_version();
--
2.11.0
More information about the Tarantool-patches
mailing list