From 8e5834b818513d7f84af4dbdc8527782e6959777 Mon Sep 17 00:00:00 2001 From: Vladimir Davydov <vdavydov.dev@gmail.com> Date: Mon, 19 Jun 2017 16:39:24 +0300 Subject: [PATCH] vinyl: do not (ab)use vy_quota for vy_cache Using vy_quota, which was implemented to support watermarking, throttling, timeouts, for accounting cached tuples is an overkill. Replace it with mem_used and mem_quota counters. --- src/box/vinyl.c | 3 ++- src/box/vy_cache.c | 26 +++++++++++++++----------- src/box/vy_cache.h | 9 +++++---- src/box/vy_quota.h | 11 +++++------ 4 files changed, 27 insertions(+), 22 deletions(-) diff --git a/src/box/vinyl.c b/src/box/vinyl.c index 8d6f30519d..38c125171e 100644 --- a/src/box/vinyl.c +++ b/src/box/vinyl.c @@ -36,6 +36,7 @@ #include "vy_log.h" #include "vy_upsert.h" #include "vy_write_iterator.h" +#include "vy_quota.h" #include "vy_stat.h" #define RB_COMPACT 1 @@ -4485,7 +4486,7 @@ vy_info_append_performance(struct vy_env *env, struct info_handler *h) struct vy_cache_env *ce = &env->cache_env; info_table_begin(h, "cache"); info_append_int(h, "count", ce->cached_count); - info_append_int(h, "used", ce->quota.used); + info_append_int(h, "used", ce->mem_used); info_table_end(h); info_table_begin(h, "iterator"); diff --git a/src/box/vy_cache.c b/src/box/vy_cache.c index 48f480ced7..33799a89f9 100644 --- a/src/box/vy_cache.c +++ b/src/box/vy_cache.c @@ -51,11 +51,11 @@ enum { void vy_cache_env_create(struct vy_cache_env *e, struct slab_cache *slab_cache, - uint64_t mem_quota) + size_t mem_quota) { rlist_create(&e->cache_lru); - vy_quota_init(&e->quota, NULL, NULL, NULL); - vy_quota_set_limit(&e->quota, mem_quota); + e->mem_used = 0; + e->mem_quota = mem_quota; mempool_create(&e->cache_entry_mempool, slab_cache, sizeof(struct vy_cache_entry)); e->cached_count = 0; @@ -67,6 +67,12 @@ vy_cache_env_destroy(struct vy_cache_env *e) mempool_destroy(&e->cache_entry_mempool); } +static inline size_t +vy_cache_entry_size(const struct vy_cache_entry *entry) +{ + return sizeof(*entry) + tuple_size(entry->stmt); +} + static struct vy_cache_entry * vy_cache_entry_new(struct vy_cache_env *env, struct vy_cache *cache, struct tuple *stmt) @@ -82,8 +88,7 @@ vy_cache_entry_new(struct vy_cache_env *env, struct vy_cache *cache, entry->left_boundary_level = cache->key_def->part_count; entry->right_boundary_level = cache->key_def->part_count; rlist_add(&env->cache_lru, &entry->in_lru); - size_t use = sizeof(struct vy_cache_entry) + tuple_size(stmt); - vy_quota_force_use(&env->quota, use); + env->mem_used += vy_cache_entry_size(entry); env->cached_count++; return entry; } @@ -91,11 +96,11 @@ vy_cache_entry_new(struct vy_cache_env *env, struct vy_cache *cache, static void vy_cache_entry_delete(struct vy_cache_env *env, struct vy_cache_entry *entry) { - struct tuple *stmt = entry->stmt; - size_t put = sizeof(struct vy_cache_entry) + tuple_size(stmt); + assert(env->cached_count > 0); env->cached_count--; - vy_quota_release(&env->quota, put); - tuple_unref(stmt); + assert(env->mem_used >= vy_cache_entry_size(entry)); + env->mem_used -= vy_cache_entry_size(entry); + tuple_unref(entry->stmt); rlist_del(&entry->in_lru); TRASH(entry); mempool_free(&env->cache_entry_mempool, entry); @@ -190,9 +195,8 @@ vy_cache_gc_step(struct vy_cache_env *env) static void vy_cache_gc(struct vy_cache_env *env) { - struct vy_quota *q = &env->quota; for (uint32_t i = 0; - vy_quota_is_exceeded(q) && i < VY_CACHE_CLEANUP_MAX_STEPS; + env->mem_used > env->mem_quota && i < VY_CACHE_CLEANUP_MAX_STEPS; i++) { vy_cache_gc_step(env); } diff --git a/src/box/vy_cache.h b/src/box/vy_cache.h index 0e7792b554..15f7d39842 100644 --- a/src/box/vy_cache.h +++ b/src/box/vy_cache.h @@ -39,7 +39,6 @@ #include "index.h" /* enum iterator_type */ #include "vy_stmt.h" /* for comparators */ #include "vy_stmt_iterator.h" /* struct vy_stmt_iterator */ -#include "vy_quota.h" #include "small/mempool.h" #if defined(__cplusplus) @@ -115,12 +114,14 @@ vy_cache_tree_key_cmp(struct vy_cache_entry *a, struct vy_cache_env { /** Common LRU list of read cache. The first element is the newest */ struct rlist cache_lru; - /** Common quota for read cache */ - struct vy_quota quota; /** Common mempool for vy_cache_entry struct */ struct mempool cache_entry_mempool; /** Number of cached tuples */ size_t cached_count; + /** Size of memory occupied by cached tuples */ + size_t mem_used; + /** Max memory size that can be used for cache */ + size_t mem_quota; }; /** @@ -131,7 +132,7 @@ struct vy_cache_env { */ void vy_cache_env_create(struct vy_cache_env *env, struct slab_cache *slab_cache, - uint64_t mem_quota); + size_t mem_quota); /** * Destroy and free resources of cache environment. diff --git a/src/box/vy_quota.h b/src/box/vy_quota.h index 2eeabd80db..3b187d191f 100644 --- a/src/box/vy_quota.h +++ b/src/box/vy_quota.h @@ -120,7 +120,7 @@ static inline void vy_quota_set_limit(struct vy_quota *q, size_t limit) { q->limit = q->watermark = limit; - if (q->quota_exceeded_cb != NULL && q->used >= limit) + if (q->used >= limit) q->quota_exceeded_cb(q); } @@ -132,7 +132,7 @@ static inline void vy_quota_set_watermark(struct vy_quota *q, size_t watermark) { q->watermark = watermark; - if (q->quota_exceeded_cb != NULL && q->used >= watermark) + if (q->used >= watermark) q->quota_exceeded_cb(q); } @@ -144,7 +144,7 @@ static inline void vy_quota_force_use(struct vy_quota *q, size_t size) { q->used += size; - if (q->quota_exceeded_cb != NULL && q->used >= q->watermark) + if (q->used >= q->watermark) q->quota_exceeded_cb(q); } @@ -156,7 +156,7 @@ vy_quota_release(struct vy_quota *q, size_t size) { assert(q->used >= size); q->used -= size; - if (q->quota_released_cb != NULL && q->used < q->limit) + if (q->used < q->limit) q->quota_released_cb(q); } @@ -169,8 +169,7 @@ static inline int vy_quota_use(struct vy_quota *q, size_t size, ev_tstamp timeout) { vy_quota_force_use(q, size); - while (q->quota_throttled_cb != NULL && - q->used >= q->limit && timeout > 0) + while (q->used >= q->limit && timeout > 0) timeout = q->quota_throttled_cb(q, timeout); if (q->used > q->limit) { vy_quota_release(q, size); -- GitLab