diff --git a/include/git2/common.h b/include/git2/common.h index b8c3e42ce..5318e66b7 100644 --- a/include/git2/common.h +++ b/include/git2/common.h @@ -131,6 +131,8 @@ enum { GIT_OPT_SET_MWINDOW_MAPPED_LIMIT, GIT_OPT_GET_SEARCH_PATH, GIT_OPT_SET_SEARCH_PATH, + GIT_OPT_GET_ODB_CACHE_SIZE, + GIT_OPT_SET_ODB_CACHE_SIZE, }; /** @@ -167,6 +169,15 @@ enum { * - `level` must be GIT_CONFIG_LEVEL_SYSTEM, GIT_CONFIG_LEVEL_GLOBAL, * or GIT_CONFIG_LEVEL_XDG. * + * opts(GIT_OPT_GET_ODB_CACHE_SIZE): + * Get the size of the libgit2 odb cache. + * + * opts(GIT_OPT_SET_ODB_CACHE_SIZE): + * Set the size of the of the libgit2 odb cache. This needs + * to be done before git_repository_open is called, since + * git_repository_open initializes the odb layer. Defaults + * to 128. + * * @param option Option key * @param ... value to set the option * @return 0 on success, <0 on failure diff --git a/src/odb.c b/src/odb.c index 5a0d8871a..c98df247c 100644 --- a/src/odb.c +++ b/src/odb.c @@ -32,6 +32,8 @@ typedef struct int is_alternate; } backend_internal; +size_t git_odb__cache_size = GIT_DEFAULT_CACHE_SIZE; + static int load_alternates(git_odb *odb, const char *objects_dir, int alternate_depth); int git_odb__format_object_header(char *hdr, size_t n, size_t obj_len, git_otype obj_type) @@ -351,7 +353,7 @@ int git_odb_new(git_odb **out) git_odb *db = git__calloc(1, sizeof(*db)); GITERR_CHECK_ALLOC(db); - if (git_cache_init(&db->cache, GIT_DEFAULT_CACHE_SIZE, &free_odb_object) < 0 || + if (git_cache_init(&db->cache, git_odb__cache_size, &free_odb_object) < 0 || git_vector_init(&db->backends, 4, backend_sort_cmp) < 0) { git__free(db); diff --git a/src/util.c b/src/util.c index f5b4a1d68..44ac1af73 100644 --- a/src/util.c +++ b/src/util.c @@ -38,6 +38,7 @@ int git_libgit2_capabilities() /* Declarations for tuneable settings */ extern size_t git_mwindow__window_size; extern size_t git_mwindow__mapped_limit; +extern size_t git_odb__cache_size; static int config_level_to_futils_dir(int config_level) { @@ -92,6 +93,14 @@ int git_libgit2_opts(int key, ...) if ((error = config_level_to_futils_dir(va_arg(ap, int))) >= 0) error = git_futils_dirs_set(error, va_arg(ap, const char *)); break; + + case GIT_OPT_GET_ODB_CACHE_SIZE: + *(va_arg(ap, size_t *)) = git_odb__cache_size; + break; + + case GIT_OPT_SET_ODB_CACHE_SIZE: + git_odb__cache_size = va_arg(ap, size_t); + break; } va_end(ap); diff --git a/tests-clar/core/opts.c b/tests-clar/core/opts.c index 6468b357a..907339d51 100644 --- a/tests-clar/core/opts.c +++ b/tests-clar/core/opts.c @@ -1,4 +1,5 @@ #include "clar_libgit2.h" +#include "cache.h" void test_core_opts__readwrite(void) { @@ -15,4 +16,15 @@ void test_core_opts__readwrite(void) git_libgit2_opts(GIT_OPT_GET_MWINDOW_SIZE, &new_val); cl_assert(new_val == old_val); + + git_libgit2_opts(GIT_OPT_GET_ODB_CACHE_SIZE, &old_val); + + cl_assert(old_val == GIT_DEFAULT_CACHE_SIZE); + + git_libgit2_opts(GIT_OPT_SET_ODB_CACHE_SIZE, (size_t)GIT_DEFAULT_CACHE_SIZE*2); + git_libgit2_opts(GIT_OPT_GET_ODB_CACHE_SIZE, &new_val); + + cl_assert(new_val == (GIT_DEFAULT_CACHE_SIZE*2)); + + git_libgit2_opts(GIT_OPT_GET_ODB_CACHE_SIZE, &old_val); }