mirror of
https://git.proxmox.com/git/libgit2
synced 2025-08-15 15:06:16 +00:00
cache: Max cache size, and evict when the cache fills up
This commit is contained in:
parent
cf9709b64e
commit
d877159260
@ -131,7 +131,8 @@ enum {
|
|||||||
GIT_OPT_SET_MWINDOW_MAPPED_LIMIT,
|
GIT_OPT_SET_MWINDOW_MAPPED_LIMIT,
|
||||||
GIT_OPT_GET_SEARCH_PATH,
|
GIT_OPT_GET_SEARCH_PATH,
|
||||||
GIT_OPT_SET_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
|
GIT_OPT_ENABLE_CACHING
|
||||||
};
|
};
|
||||||
|
|
||||||
|
25
src/cache.c
25
src/cache.c
@ -18,6 +18,7 @@
|
|||||||
GIT__USE_OIDMAP
|
GIT__USE_OIDMAP
|
||||||
|
|
||||||
bool git_cache__enabled = true;
|
bool git_cache__enabled = true;
|
||||||
|
size_t git_cache__max_storage = (4 * 1024 * 1024);
|
||||||
|
|
||||||
static size_t git_cache__max_object_size[8] = {
|
static size_t git_cache__max_object_size[8] = {
|
||||||
0, /* GIT_OBJ__EXT1 */
|
0, /* GIT_OBJ__EXT1 */
|
||||||
@ -70,19 +71,25 @@ int git_cache_init(git_cache *cache)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void git_cache_clear(git_cache *cache)
|
/* called with lock */
|
||||||
|
static void clear_cache(git_cache *cache)
|
||||||
{
|
{
|
||||||
git_cached_obj *evict = NULL;
|
git_cached_obj *evict = NULL;
|
||||||
|
|
||||||
if (git_mutex_lock(&cache->lock) < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
kh_foreach_value(cache->map, evict, {
|
kh_foreach_value(cache->map, evict, {
|
||||||
git_cached_obj_decref(evict);
|
git_cached_obj_decref(evict);
|
||||||
});
|
});
|
||||||
|
|
||||||
kh_clear(oid, cache->map);
|
kh_clear(oid, cache->map);
|
||||||
cache->used_memory = 0;
|
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);
|
git_mutex_unlock(&cache->lock);
|
||||||
}
|
}
|
||||||
@ -95,14 +102,15 @@ void git_cache_free(git_cache *cache)
|
|||||||
git_mutex_free(&cache->lock);
|
git_mutex_free(&cache->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Call with lock, yo */
|
/* Called with lock */
|
||||||
static void cache_evict_entries(git_cache *cache, size_t evict_count)
|
static void cache_evict_entries(git_cache *cache)
|
||||||
{
|
{
|
||||||
uint32_t seed = rand();
|
uint32_t seed = rand();
|
||||||
|
size_t evict_count = 8;
|
||||||
|
|
||||||
/* do not infinite loop if there's not enough entries to evict */
|
/* do not infinite loop if there's not enough entries to evict */
|
||||||
if (evict_count > kh_size(cache->map)) {
|
if (evict_count > kh_size(cache->map)) {
|
||||||
git_cache_clear(cache);
|
clear_cache(cache);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,6 +171,9 @@ static void *cache_store(git_cache *cache, git_cached_obj *entry)
|
|||||||
if (git_mutex_lock(&cache->lock) < 0)
|
if (git_mutex_lock(&cache->lock) < 0)
|
||||||
return entry;
|
return entry;
|
||||||
|
|
||||||
|
if (cache->used_memory > git_cache__max_storage)
|
||||||
|
cache_evict_entries(cache);
|
||||||
|
|
||||||
pos = kh_get(oid, cache->map, &entry->oid);
|
pos = kh_get(oid, cache->map, &entry->oid);
|
||||||
|
|
||||||
/* not found */
|
/* not found */
|
||||||
|
@ -35,6 +35,7 @@ typedef struct {
|
|||||||
} git_cache;
|
} git_cache;
|
||||||
|
|
||||||
extern bool git_cache__enabled;
|
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);
|
int git_cache_set_max_object_size(git_otype type, size_t size);
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ int git_libgit2_opts(int key, ...)
|
|||||||
error = git_futils_dirs_set(error, va_arg(ap, const char *));
|
error = git_futils_dirs_set(error, va_arg(ap, const char *));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GIT_OPT_SET_CACHE_LIMIT:
|
case GIT_OPT_SET_CACHE_OBJECT_LIMIT:
|
||||||
{
|
{
|
||||||
git_otype type = (git_otype)va_arg(ap, int);
|
git_otype type = (git_otype)va_arg(ap, int);
|
||||||
size_t size = va_arg(ap, size_t);
|
size_t size = va_arg(ap, size_t);
|
||||||
@ -103,6 +103,10 @@ int git_libgit2_opts(int key, ...)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case GIT_OPT_SET_CACHE_MAX_SIZE:
|
||||||
|
git_cache__max_storage = va_arg(ap, size_t);
|
||||||
|
break;
|
||||||
|
|
||||||
case GIT_OPT_ENABLE_CACHING:
|
case GIT_OPT_ENABLE_CACHING:
|
||||||
git_cache__enabled = (va_arg(ap, int) != 0);
|
git_cache__enabled = (va_arg(ap, int) != 0);
|
||||||
break;
|
break;
|
||||||
|
@ -13,7 +13,7 @@ void test_object_cache__cleanup(void)
|
|||||||
git_repository_free(g_repo);
|
git_repository_free(g_repo);
|
||||||
g_repo = NULL;
|
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 {
|
static struct {
|
||||||
@ -54,7 +54,7 @@ void test_object_cache__cache_everything(void)
|
|||||||
git_odb *odb;
|
git_odb *odb;
|
||||||
|
|
||||||
git_libgit2_opts(
|
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));
|
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_object *obj;
|
||||||
git_odb *odb;
|
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));
|
cl_git_pass(git_repository_odb(&odb, g_repo));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user