From f2c25d1893cfa897b0d36005604c134a731e402d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicent=20Mart=C3=AD?= Date: Fri, 2 Mar 2012 20:08:00 +0100 Subject: [PATCH] config: Implement a proper cvar cache --- src/crlf.c | 12 +++++++-- src/filter.c | 50 ------------------------------------- src/filter.h | 21 ---------------- src/repository.c | 5 ++++ src/repository.h | 65 ++++++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 75 insertions(+), 78 deletions(-) diff --git a/src/crlf.c b/src/crlf.c index e74f8e89b..404156d6a 100644 --- a/src/crlf.c +++ b/src/crlf.c @@ -223,8 +223,16 @@ int git_filter_add__crlf_to_odb(git_vector *filters, git_repository *repo, const if (ca.crlf_action == GIT_CRLF_BINARY) return 0; - if (ca.crlf_action == GIT_CRLF_GUESS && repo->filter_options.auto_crlf == GIT_AUTO_CRLF_FALSE) - return 0; + if (ca.crlf_action == GIT_CRLF_GUESS) { + int auto_crlf; + + if ((error = git_repository__cvar( + &auto_crlf, repo, GIT_CVAR_AUTO_CRLF)) < GIT_SUCCESS) + return error; + + if (auto_crlf == GIT_AUTO_CRLF_FALSE) + return 0; + } /* If we're good, we create a new filter object and push it * into the filters array */ diff --git a/src/filter.c b/src/filter.c index 92b3566af..f93730acb 100644 --- a/src/filter.c +++ b/src/filter.c @@ -84,60 +84,10 @@ int git_text_is_binary(git_text_stats *stats) return 0; } -static int load_repository_settings(git_repository *repo) -{ - static git_cvar_map map_eol[] = { - {GIT_CVAR_FALSE, NULL, GIT_EOL_UNSET}, - {GIT_CVAR_STRING, "lf", GIT_EOL_LF}, - {GIT_CVAR_STRING, "crlf", GIT_EOL_CRLF}, - {GIT_CVAR_STRING, "native", GIT_EOL_NATIVE} - }; - - static git_cvar_map map_crlf[] = { - {GIT_CVAR_FALSE, NULL, GIT_AUTO_CRLF_FALSE}, - {GIT_CVAR_TRUE, NULL, GIT_AUTO_CRLF_TRUE}, - {GIT_CVAR_STRING, "input", GIT_AUTO_CRLF_INPUT} - }; - - git_config *config; - int error; - - if (repo->filter_options.loaded) - return GIT_SUCCESS; - - repo->filter_options.eol = GIT_EOL_DEFAULT; - repo->filter_options.auto_crlf = GIT_AUTO_CRLF_DEFAULT; - - error = git_repository_config__weakptr(&config, repo); - if (error < GIT_SUCCESS) - return error; - - error = git_config_get_mapped( - config, "core.eol", map_eol, ARRAY_SIZE(map_eol), &repo->filter_options.eol); - - if (error < GIT_SUCCESS && error != GIT_ENOTFOUND) - return error; - - error = git_config_get_mapped( - config, "core.auto_crlf", map_crlf, ARRAY_SIZE(map_crlf), &repo->filter_options.auto_crlf); - - if (error < GIT_SUCCESS && error != GIT_ENOTFOUND) - return error; - - repo->filter_options.loaded = 1; - return 0; -} - int git_filters_load(git_vector *filters, git_repository *repo, const char *path, int mode) { int error; - /* Make sure that the relevant settings from `gitconfig` have been - * cached on the repository struct to speed things up */ - error = load_repository_settings(repo); - if (error < GIT_SUCCESS) - return error; - if (mode == GIT_FILTER_TO_ODB) { /* Load the CRLF cleanup filter when writing to the ODB */ error = git_filter_add__crlf_to_odb(filters, repo, path); diff --git a/src/filter.h b/src/filter.h index 601be1836..5a77f25c6 100644 --- a/src/filter.h +++ b/src/filter.h @@ -29,29 +29,8 @@ typedef enum { GIT_CRLF_INPUT, GIT_CRLF_CRLF, GIT_CRLF_AUTO, - - GIT_SAFE_CRLF_FALSE = 0, - GIT_SAFE_CRLF_FAIL = 1, - GIT_SAFE_CRLF_WARN = 2, - - GIT_AUTO_CRLF_FALSE = 0, - GIT_AUTO_CRLF_TRUE = 1, - GIT_AUTO_CRLF_INPUT = -1, - GIT_AUTO_CRLF_DEFAULT = GIT_AUTO_CRLF_FALSE, } git_crlf_t; -typedef enum { - GIT_EOL_UNSET, - GIT_EOL_CRLF, - GIT_EOL_LF, -#ifdef GIT_WIN32 - GIT_EOL_NATIVE = GIT_EOL_CRLF, -#else - GIT_EOL_NATIVE = GIT_EOL_LF, -#endif - GIT_EOL_DEFAULT = GIT_EOL_NATIVE -} git_eol_t; - typedef struct { /* NUL, CR, LF and CRLF counts */ unsigned int nul, cr, lf, crlf; diff --git a/src/repository.c b/src/repository.c index c46dd9df9..1f8306991 100644 --- a/src/repository.c +++ b/src/repository.c @@ -43,6 +43,8 @@ static void drop_config(git_repository *repo) git_config_free(repo->_config); repo->_config = NULL; } + + git_repository__cvar_cache_clear(repo); } static void drop_index(git_repository *repo) @@ -111,6 +113,9 @@ static git_repository *repository_alloc(void) return NULL; } + /* set all the entries in the cvar cache to `unset` */ + git_repository__cvar_cache_clear(repo); + return repo; } diff --git a/src/repository.h b/src/repository.h index 83f088821..b5dcc1340 100644 --- a/src/repository.h +++ b/src/repository.h @@ -26,6 +26,49 @@ #define GIT_DIR_MODE 0755 #define GIT_BARE_DIR_MODE 0777 +/** Cvar cache identifiers */ +typedef enum { + GIT_CVAR_AUTO_CRLF = 0, /* core.autocrlf */ + GIT_CVAR_EOL, /* core.eol */ + GIT_CVAR_CACHE_MAX +} git_cvar_cached; + +/** + * CVAR value enumerations + * + * These are the values that are actually stored in the cvar cache, instead + * of their string equivalents. These values are internal and symbolic; + * make sure that none of them is set to `-1`, since that is the unique + * identifier for "not cached" + */ +typedef enum { + /* The value hasn't been loaded from the cache yet */ + GIT_CVAR_NOT_CACHED = -1, + + /* core.safecrlf: false, 'fail', 'warn' */ + GIT_SAFE_CRLF_FALSE = 0, + GIT_SAFE_CRLF_FAIL = 1, + GIT_SAFE_CRLF_WARN = 2, + + /* core.autocrlf: false, true, 'input; */ + GIT_AUTO_CRLF_FALSE = 0, + GIT_AUTO_CRLF_TRUE = 1, + GIT_AUTO_CRLF_INPUT = 2, + GIT_AUTO_CRLF_DEFAULT = GIT_AUTO_CRLF_FALSE, + + /* core.eol: unset, 'crlf', 'lf', 'native' */ + GIT_EOL_UNSET = 0, + GIT_EOL_CRLF = 1, + GIT_EOL_LF = 2, +#ifdef GIT_WIN32 + GIT_EOL_NATIVE = GIT_EOL_CRLF, +#else + GIT_EOL_NATIVE = GIT_EOL_LF, +#endif + GIT_EOL_DEFAULT = GIT_EOL_NATIVE +} git_cvar_value; + +/** Base git object for inheritance */ struct git_object { git_cached_obj cached; git_repository *repo; @@ -47,11 +90,7 @@ struct git_repository { unsigned is_bare:1; unsigned int lru_counter; - struct { - int loaded; - int eol; - int auto_crlf; - } filter_options; + git_cvar_value cvar_cache[GIT_CVAR_CACHE_MAX]; }; /* fully free the object; internal method, do not @@ -61,8 +100,24 @@ void git_object__free(void *object); int git_oid__parse(git_oid *oid, const char **buffer_out, const char *buffer_end, const char *header); void git_oid__writebuf(git_buf *buf, const char *header, const git_oid *oid); +/* + * Weak pointers to repository internals. + * + * The returned pointers do not need to be freed. Do not keep + * permanent references to these (i.e. between API calls), since they may + * become invalidated if the user replaces a repository internal. + */ int git_repository_config__weakptr(git_config **out, git_repository *repo); int git_repository_odb__weakptr(git_odb **out, git_repository *repo); int git_repository_index__weakptr(git_index **out, git_repository *repo); +/* + * CVAR cache + * + * Efficient access to the most used config variables of a repository. + * The cache is cleared everytime the config backend is replaced. + */ +int git_repository__cvar(int *out, git_repository *repo, git_cvar_cached cvar); +void git_repository__cvar_cache_clear(git_repository *repo); + #endif