commit - 9ee99c5ff9b64d01be6bd3b425b442a0a3421fcf
commit + e06b866a738a376b3f75017e7cd76811a5eb594d
blob - e5a41478d3a0377cea133fe0ac9e193fe49b3f3d
blob + f9b2e1b5ba6a61b6d98b7686b525ec83b0f5c170
--- src/box/space_cache.c
+++ src/box/space_cache.c
*/
uint32_t space_cache_version;
+/**
+ * Value of space_cache_version at the time of the last space lookup,
+ * see space_by_id_fast().
+ */
+uint32_t prev_space_cache_version;
+
+/** Last looked up space, see space_by_id_fast(). */
+struct space *prev_space;
+
const char *space_cache_holder_type_strs[SPACE_HOLDER_MAX] = {
"foreign key",
};
mh_strnptr_delete(spaces_by_name);
}
-/** Return space by its number */
struct space *
-space_by_id(uint32_t id)
+space_by_id_slow(uint32_t id)
{
mh_int_t space = mh_i32ptr_find(spaces, id, NULL);
if (space == mh_end(spaces))
}
return false;
}
+
+#undef space_by_id
+
+/** Define the space_by_id() symbol for FFI. */
+struct space *
+space_by_id(uint32_t id)
+{
+ return space_by_id_fast(id);
+}
blob - 97d64b52b1bf2294777699449d5c464659b0b258
blob + 86ed250a205c5fe97af4f5f47ec3d8ae045fe7e8
--- src/box/space_cache.h
+++ src/box/space_cache.h
space_cache_destroy(void);
/**
+ * Slow version of space lookup by id.
+ * Performs a direct lookup in the spaces hash table.
+ * Returns NULL if not found (doesn't set diag).
+ */
+struct space *
+space_by_id_slow(uint32_t id);
+
+/**
+ * Fast version of space lookup by id.
+ * Caches the last looked up space.
+ * Returns NULL if not found (doesn't set diag).
+ */
+static inline struct space *
+space_by_id_fast(uint32_t id)
+{
+ extern uint32_t prev_space_cache_version;
+ extern struct space *prev_space;
+ if (prev_space_cache_version == space_cache_version &&
+ prev_space != NULL && prev_space->def->id == id)
+ return prev_space;
+ prev_space = space_by_id_slow(id);
+ prev_space_cache_version = space_cache_version;
+ return prev_space;
+}
+
+/**
* Try to look up a space by space number in the space cache.
* FFI-friendly no-exception-thrown space lookup function.
*
struct space *
space_by_id(uint32_t id);
+/*
+ * Use the inline function for space lookups in Tarantool.
+ * The space_by_id() symbol exists only for FFI.
+ */
+#define space_by_id(id) space_by_id_fast(id)
+
/**
* Try to look up a space by space name in the space name cache.
*
static inline struct space *
space_cache_find(uint32_t id)
{
- static uint32_t prev_space_cache_version;
- static struct space *space;
- if (prev_space_cache_version != space_cache_version)
- space = NULL;
- if (space && space->def->id == id)
+ struct space *space = space_by_id(id);
+ if (space != NULL)
return space;
- space = space_by_id(id);
- if (space != NULL) {
- prev_space_cache_version = space_cache_version;
- return space;
- }
diag_set(ClientError, ER_NO_SUCH_SPACE, int2str(id));
return NULL;
}
blob - 59ceb6c5691b0fbd9dd9e83c38af46e435238ec4
blob + ab7058df77339f8cc2fe48fa52a2658ad2cf5203
--- test/unit/vy_point_lookup.c
+++ test/unit/vy_point_lookup.c
uint64_t schema_version;
uint32_t space_cache_version;
-struct space *space_by_id(uint32_t id) { return NULL; }
+uint32_t prev_space_cache_version;
+struct space *prev_space;
+struct space *
+space_by_id_slow(uint32_t id) { return NULL; }
struct vy_lsm *vy_lsm(struct index *index) { return NULL; }
void index_delete(struct index *index) { unreachable(); }