From ed6648ba469c30b074e83bc102298ba0b183e231 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Mon, 14 Jan 2013 16:39:22 +0100 Subject: [PATCH] pack: evict objects from the cache in groups of eight This drops the cache eviction below libcrypto and zlib in the perf output. The number has been chosen empirically. --- src/pack.c | 44 +++++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/src/pack.c b/src/pack.c index ddba5d686..d4ae29072 100644 --- a/src/pack.c +++ b/src/pack.c @@ -116,29 +116,51 @@ static git_pack_cache_entry *cache_get(git_pack_cache *cache, git_off_t offset) return entry; } +#define BASE_DELTA_EVICT_NR 8 + /* Run with the cache lock held */ static void free_lowest_entry(git_pack_cache *cache) { - git_pack_cache_entry *lowest = NULL, *entry; - khiter_t k, lowest_k; + git_pack_cache_entry *entry; + khiter_t k; + + git_pack_cache_entry *lru[BASE_DELTA_EVICT_NR] = {NULL}; + khiter_t lru_k[BASE_DELTA_EVICT_NR]; + int i; for (k = kh_begin(cache->entries); k != kh_end(cache->entries); k++) { if (!kh_exist(cache->entries, k)) continue; entry = kh_value(cache->entries, k); - if (lowest == NULL || entry->last_usage < lowest->last_usage) { - lowest_k = k; - lowest = entry; + + for (i = 0; i < BASE_DELTA_EVICT_NR; i++) { + if (lru[i] == NULL || + (entry->last_usage < lru[i]->last_usage && + entry->refcount.val == 0)) { + int j; + + for (j = 0; j < i; j++) { + lru[j] = lru[j+1]; + lru_k[j] = lru_k[j+1]; + } + + lru[i] = entry; + lru_k[i] = k; + + /* jump out and try with the next entry */ + break; + } } } - if (!lowest) /* there's nothing to free */ - return; - - cache->memory_used -= lowest->raw.len; - kh_del(off, cache->entries, lowest_k); - free_cache_object(lowest); + for (i = 0; i < BASE_DELTA_EVICT_NR; i++) { + if (lru[i]) { + cache->memory_used -= lru[i]->raw.len; + kh_del(off, cache->entries, lru_k[i]); + free_cache_object(lru[i]); + } + } } static int cache_add(git_pack_cache *cache, git_rawobj *base, git_off_t offset)