From 064236ca45067c9a7189e0d30790b8f3541b91ad Mon Sep 17 00:00:00 2001 From: Vicent Marti Date: Wed, 3 Apr 2013 23:39:42 +0200 Subject: [PATCH] Per-object max size --- src/cache.c | 56 ++++++++++++++++++++++++++--------------------------- src/cache.h | 1 + 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/src/cache.c b/src/cache.c index 316007bdf..c6e983597 100644 --- a/src/cache.c +++ b/src/cache.c @@ -17,21 +17,20 @@ GIT__USE_OIDMAP -bool git_cache__store_types[8] = { - false, /* GIT_OBJ__EXT1 */ - true, /* GIT_OBJ_COMMIT */ - true, /* GIT_OBJ_TREE */ - false, /* GIT_OBJ_BLOB */ - true, /* GIT_OBJ_TAG */ - false, /* GIT_OBJ__EXT2 */ - false, /* GIT_OBJ_OFS_DELTA */ - false /* GIT_OBJ_REF_DELTA */ +size_t git_cache__max_object_size[8] = { + 0, /* GIT_OBJ__EXT1 */ + 4096, /* GIT_OBJ_COMMIT */ + 4096, /* GIT_OBJ_TREE */ + 0, /* GIT_OBJ_BLOB */ + 4096, /* GIT_OBJ_TAG */ + 0, /* GIT_OBJ__EXT2 */ + 0, /* GIT_OBJ_OFS_DELTA */ + 0 /* GIT_OBJ_REF_DELTA */ }; -size_t git_cache__max_object_size = 4096; - int git_cache_init(git_cache *cache) { + cache->used_memory = 0; cache->map = git_oidmap_alloc(); git_mutex_init(&cache->lock); return 0; @@ -43,30 +42,35 @@ void git_cache_free(git_cache *cache) git_mutex_free(&cache->lock); } -static void cache_evict_entries(git_cache *cache, size_t evict) +/* Call with lock, yo */ +static void cache_evict_entries(git_cache *cache, size_t evict_count) { uint32_t seed = rand(); /* do not infinite loop if there's not enough entries to evict */ - if (evict > kh_size(cache->map)) + if (evict_count > kh_size(cache->map)) return; - while (evict > 0) { + while (evict_count > 0) { khiter_t pos = seed++ % kh_end(cache->map); if (kh_exist(cache->map, pos)) { + git_cached_obj *evict = kh_val(cache->map, pos); + + evict_count--; + cache->used_memory -= evict->size; + git_cached_obj_decref(evict); + kh_del(oid, cache->map, pos); - evict--; } } } static bool cache_should_store(git_otype object_type, size_t object_size) { - if (!git_cache__store_types[object_type]) - return false; + size_t max_size = git_cache__max_object_size[object_type]; - if (object_size > git_cache__max_object_size) + if (max_size == 0 || object_size > max_size) return false; return true; @@ -100,6 +104,11 @@ static void *cache_store(git_cache *cache, git_cached_obj *entry) { khiter_t pos; + git_cached_obj_incref(entry); + + if (!cache_should_store(entry->type, entry->size)) + return entry; + if (git_mutex_lock(&cache->lock) < 0) return entry; @@ -114,6 +123,7 @@ static void *cache_store(git_cache *cache, git_cached_obj *entry) kh_key(cache->map, pos) = &entry->oid; kh_val(cache->map, pos) = entry; git_cached_obj_incref(entry); + cache->used_memory += entry->size; } } /* found */ @@ -142,22 +152,12 @@ static void *cache_store(git_cache *cache, git_cached_obj *entry) void *git_cache_store_raw(git_cache *cache, git_odb_object *entry) { - git_cached_obj_incref(entry); - - if (!cache_should_store(entry->cached.type, entry->cached.size)) - return entry; - entry->cached.flags = GIT_CACHE_STORE_RAW; return cache_store(cache, (git_cached_obj *)entry); } void *git_cache_store_parsed(git_cache *cache, git_object *entry) { - git_cached_obj_incref(entry); - - if (!cache_should_store(entry->cached.type, entry->cached.size)) - return entry; - entry->cached.flags = GIT_CACHE_STORE_PARSED; return cache_store(cache, (git_cached_obj *)entry); } diff --git a/src/cache.h b/src/cache.h index d57f244dd..65a6e5766 100644 --- a/src/cache.h +++ b/src/cache.h @@ -31,6 +31,7 @@ typedef struct { typedef struct { git_oidmap *map; git_mutex lock; + size_t used_memory; } git_cache; int git_cache_init(git_cache *cache);