summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVicent Marti <tanoku@gmail.com>2013-04-22 17:04:52 +0200
committerVicent Marti <tanoku@gmail.com>2013-04-22 17:04:52 +0200
commitd87715926049390a2417a2476742114ec966686a (patch)
treef5cf7daf3913578f57076c2efc94bfd1f728068c
parentcf9709b64eb49d5a0ee1181b80c950e518fb45b0 (diff)
downloadlibgit2-vmg/new-cache.tar.gz
cache: Max cache size, and evict when the cache fills upvmg/new-cache
-rw-r--r--include/git2/common.h3
-rw-r--r--src/cache.c25
-rw-r--r--src/cache.h1
-rw-r--r--src/util.c6
-rw-r--r--tests-clar/object/cache.c6
5 files changed, 29 insertions, 12 deletions
diff --git a/include/git2/common.h b/include/git2/common.h
index 80d83d345..ccd252fda 100644
--- a/include/git2/common.h
+++ b/include/git2/common.h
@@ -131,7 +131,8 @@ enum {
GIT_OPT_SET_MWINDOW_MAPPED_LIMIT,
GIT_OPT_GET_SEARCH_PATH,
GIT_OPT_SET_SEARCH_PATH,
- GIT_OPT_SET_CACHE_LIMIT,
+ GIT_OPT_SET_CACHE_OBJECT_LIMIT,
+ GIT_OPT_SET_CACHE_MAX_SIZE,
GIT_OPT_ENABLE_CACHING
};
diff --git a/src/cache.c b/src/cache.c
index c51be895e..ca122fb77 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -18,6 +18,7 @@
GIT__USE_OIDMAP
bool git_cache__enabled = true;
+size_t git_cache__max_storage = (4 * 1024 * 1024);
static size_t git_cache__max_object_size[8] = {
0, /* GIT_OBJ__EXT1 */
@@ -70,19 +71,25 @@ int git_cache_init(git_cache *cache)
return 0;
}
-void git_cache_clear(git_cache *cache)
+/* called with lock */
+static void clear_cache(git_cache *cache)
{
git_cached_obj *evict = NULL;
- if (git_mutex_lock(&cache->lock) < 0)
- return;
-
kh_foreach_value(cache->map, evict, {
git_cached_obj_decref(evict);
});
kh_clear(oid, cache->map);
cache->used_memory = 0;
+}
+
+void git_cache_clear(git_cache *cache)
+{
+ if (git_mutex_lock(&cache->lock) < 0)
+ return;
+
+ clear_cache(cache);
git_mutex_unlock(&cache->lock);
}
@@ -95,14 +102,15 @@ void git_cache_free(git_cache *cache)
git_mutex_free(&cache->lock);
}
-/* Call with lock, yo */
-static void cache_evict_entries(git_cache *cache, size_t evict_count)
+/* Called with lock */
+static void cache_evict_entries(git_cache *cache)
{
uint32_t seed = rand();
+ size_t evict_count = 8;
/* do not infinite loop if there's not enough entries to evict */
if (evict_count > kh_size(cache->map)) {
- git_cache_clear(cache);
+ clear_cache(cache);
return;
}
@@ -163,6 +171,9 @@ static void *cache_store(git_cache *cache, git_cached_obj *entry)
if (git_mutex_lock(&cache->lock) < 0)
return entry;
+ if (cache->used_memory > git_cache__max_storage)
+ cache_evict_entries(cache);
+
pos = kh_get(oid, cache->map, &entry->oid);
/* not found */
diff --git a/src/cache.h b/src/cache.h
index e95d521fe..1715c7220 100644
--- a/src/cache.h
+++ b/src/cache.h
@@ -35,6 +35,7 @@ typedef struct {
} git_cache;
extern bool git_cache__enabled;
+extern size_t git_cache__max_storage;
int git_cache_set_max_object_size(git_otype type, size_t size);
diff --git a/src/util.c b/src/util.c
index 1ed5d5d16..c3fc69756 100644
--- a/src/util.c
+++ b/src/util.c
@@ -95,7 +95,7 @@ int git_libgit2_opts(int key, ...)
error = git_futils_dirs_set(error, va_arg(ap, const char *));
break;
- case GIT_OPT_SET_CACHE_LIMIT:
+ case GIT_OPT_SET_CACHE_OBJECT_LIMIT:
{
git_otype type = (git_otype)va_arg(ap, int);
size_t size = va_arg(ap, size_t);
@@ -103,6 +103,10 @@ int git_libgit2_opts(int key, ...)
break;
}
+ case GIT_OPT_SET_CACHE_MAX_SIZE:
+ git_cache__max_storage = va_arg(ap, size_t);
+ break;
+
case GIT_OPT_ENABLE_CACHING:
git_cache__enabled = (va_arg(ap, int) != 0);
break;
diff --git a/tests-clar/object/cache.c b/tests-clar/object/cache.c
index b36bf2726..a3eba8737 100644
--- a/tests-clar/object/cache.c
+++ b/tests-clar/object/cache.c
@@ -13,7 +13,7 @@ void test_object_cache__cleanup(void)
git_repository_free(g_repo);
g_repo = NULL;
- git_libgit2_opts(GIT_OPT_SET_CACHE_LIMIT, (int)GIT_OBJ_BLOB, (size_t)0);
+ git_libgit2_opts(GIT_OPT_SET_CACHE_OBJECT_LIMIT, (int)GIT_OBJ_BLOB, (size_t)0);
}
static struct {
@@ -54,7 +54,7 @@ void test_object_cache__cache_everything(void)
git_odb *odb;
git_libgit2_opts(
- GIT_OPT_SET_CACHE_LIMIT, (int)GIT_OBJ_BLOB, (size_t)32767);
+ GIT_OPT_SET_CACHE_OBJECT_LIMIT, (int)GIT_OBJ_BLOB, (size_t)32767);
cl_git_pass(git_repository_odb(&odb, g_repo));
@@ -103,7 +103,7 @@ void test_object_cache__cache_no_blobs(void)
git_object *obj;
git_odb *odb;
- git_libgit2_opts(GIT_OPT_SET_CACHE_LIMIT, (int)GIT_OBJ_BLOB, (size_t)0);
+ git_libgit2_opts(GIT_OPT_SET_CACHE_OBJECT_LIMIT, (int)GIT_OBJ_BLOB, (size_t)0);
cl_git_pass(git_repository_odb(&odb, g_repo));