]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lib/cache: decrease LMDB size by KRU size docs-cache-kru-8qejro/deployments/7210
authorLukáš Ondráček <lukas.ondracek@nic.cz>
Wed, 16 Jul 2025 23:35:46 +0000 (01:35 +0200)
committerLukáš Ondráček <lukas.ondracek@nic.cz>
Wed, 16 Jul 2025 23:35:46 +0000 (01:35 +0200)
lib/cache/api.c
lib/cache/top.c
lib/cache/top.h

index 737d38857577531201d01ec161bfb9815c534ef4..1677240bef5e529113670d126764de855e37b62c 100644 (file)
@@ -116,6 +116,15 @@ int kr_cache_open(struct kr_cache *cache, const struct kr_cdb_api *api, struct k
        if (!api)
                api = kr_cdb_lmdb();
        cache->api = api;
+
+       size_t orig_maxsize = opts->maxsize;
+       if (opts->maxsize) {
+               const size_t top_size = kr_cache_top_get_size(opts->maxsize);
+               if (!kr_fails_assert(top_size < opts->maxsize)) {
+                       opts->maxsize -= top_size;
+               }
+       }
+
        int ret = cache->api->open(&cache->db, &cache->stats, opts, mm);
        if (ret == 0) {
                ret = assert_right_version(cache);
@@ -161,7 +170,7 @@ int kr_cache_open(struct kr_cache *cache, const struct kr_cdb_api *api, struct k
                ret = kr_error(errno);
        }
        if (ret == 0) {
-               ret = kr_cache_top_init(&cache->top, top_path, maxsize);
+               ret = kr_cache_top_init(&cache->top, top_path, orig_maxsize);
                free(top_path);
        }
        if (ret != 0) {
index 37cdd363b8969f630e019b4c1293a6f95d7f4e93..a26e5d5b108aba8e39f12565bd3a5b4cc32a8588 100644 (file)
 #define FILE_FORMAT_VERSION 1  // fail if different
 
 
-#define KRU_CAPACITY(cache_size) (cache_size / 64)   // KRU size is approx. (8 * capacity) B
-       // average entry size seems to be 70-100 B
-       // -> KRU size is around 12.5 % of cache size, so 112.5 % of the set value is required
+#define KRU_CAPACITY(cache_size) (cache_size / 128)   // KRU size is approx. (8 * capacity) B
+       // average entry size seems to be 100-200 B,
+       // make KRU capacity between cache_size/128 and cache_size/64 (power of two)
+       // -> KRU size: between cache_size/16 and cache_size/8 (cache data size is the rest)
 #define TICK_SEC        1
 #define NORMAL_SIZE  (150 + KR_CACHE_SIZE_OVERHEAD)  // B; normal size of cache entry
        // used as baseline for the following
@@ -93,13 +94,29 @@ static inline bool first_access(struct kr_cache_top_context *ctx, kru_hash_t has
 }
 
 
-int kr_cache_top_init(struct kr_cache_top *top, char *mmap_file, size_t cache_size) {
+static inline void get_size_capacity(size_t cache_size, size_t *top_size, size_t *capacity_log)
+{
+       *top_size = 0;
+       *capacity_log = 0;
+
+       const size_t capacity = KRU_CAPACITY(cache_size);
+       for (size_t c = capacity - 1; c > 0; c >>= 1) (*capacity_log)++;
+
+       *top_size = offsetof(struct top_data, kru) + KRU.get_size(*capacity_log);
+}
+
+int kr_cache_top_get_size(size_t cache_size)
+{
+       size_t top_size, capacity_log;
+       get_size_capacity(cache_size, &top_size, &capacity_log);
+       return top_size;
+}
+
+int kr_cache_top_init(struct kr_cache_top *top, char *mmap_file, size_t cache_size)
+{
        size_t size = 0, capacity_log = 0;
        if (cache_size > 0) {
-               const size_t capacity = KRU_CAPACITY(cache_size);
-               for (size_t c = capacity - 1; c > 0; c >>= 1) capacity_log++;
-
-               size = offsetof(struct top_data, kru) + KRU.get_size(capacity_log);
+               get_size_capacity(cache_size, &size, &capacity_log);
        } // else use existing file settings
 
        VERBOSE_LOG("INIT, cache size %d, KRU capacity_log %d\n", cache_size, capacity_log);
index 8cdc17e91ecdc8164717c8a9aa9c9edd05561f94..c6eb920cbefe54c0d77b419dd8f08a79740fd0cc 100644 (file)
@@ -33,6 +33,9 @@ static inline kru_price_t kr_cache_top_entry_price(struct kr_cache_top *top, siz
        return top->data->base_price_norm / size;
 }
 
+KR_EXPORT
+int kr_cache_top_get_size(size_t cache_size);
+
 KR_EXPORT
 int kr_cache_top_init(struct kr_cache_top *top, char *mmap_file, size_t cache_size);