diff options
author | Patrick Steinhardt <ps@pks.im> | 2017-02-17 12:41:05 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-02-17 12:41:05 +0100 |
commit | d0c72a92ef530962e19a560001f4032893681127 (patch) | |
tree | 3810eea20d5acbb373c34874cf115cb01998f1d6 | |
parent | 021f4943a9482355c47122da4911c5272cefdb8d (diff) | |
parent | 8f1ff26bd3c46d7f4f20b6776fd2edac647f3335 (diff) | |
download | libgit2-d0c72a92ef530962e19a560001f4032893681127.tar.gz |
Merge pull request #4092 from pks-t/pks/khash-cleanups
khash cleanups
-rw-r--r-- | src/attr.c | 4 | ||||
-rw-r--r-- | src/attrcache.c | 6 | ||||
-rw-r--r-- | src/cache.c | 46 | ||||
-rw-r--r-- | src/cache.h | 2 | ||||
-rw-r--r-- | src/checkout.c | 2 | ||||
-rw-r--r-- | src/config_file.c | 4 | ||||
-rw-r--r-- | src/describe.c | 4 | ||||
-rw-r--r-- | src/diff_driver.c | 6 | ||||
-rw-r--r-- | src/fileops.c | 4 | ||||
-rw-r--r-- | src/idxmap.c | 133 | ||||
-rw-r--r-- | src/idxmap.h | 82 | ||||
-rw-r--r-- | src/index.c | 25 | ||||
-rw-r--r-- | src/indexer.c | 19 | ||||
-rw-r--r-- | src/mwindow.c | 4 | ||||
-rw-r--r-- | src/odb_mempack.c | 29 | ||||
-rw-r--r-- | src/offmap.c | 83 | ||||
-rw-r--r-- | src/offmap.h | 48 | ||||
-rw-r--r-- | src/oidmap.c | 105 | ||||
-rw-r--r-- | src/oidmap.h | 41 | ||||
-rw-r--r-- | src/pack-objects.c | 23 | ||||
-rw-r--r-- | src/pack.c | 41 | ||||
-rw-r--r-- | src/refdb_fs.c | 2 | ||||
-rw-r--r-- | src/refs.c | 2 | ||||
-rw-r--r-- | src/repository.c | 1 | ||||
-rw-r--r-- | src/revwalk.c | 14 | ||||
-rw-r--r-- | src/sortedcache.c | 8 | ||||
-rw-r--r-- | src/strmap.c | 95 | ||||
-rw-r--r-- | src/strmap.h | 54 | ||||
-rw-r--r-- | src/submodule.c | 8 | ||||
-rw-r--r-- | src/transaction.c | 22 | ||||
-rw-r--r-- | src/tree.c | 6 | ||||
-rw-r--r-- | tests/core/oidmap.c | 30 | ||||
-rw-r--r-- | tests/core/strmap.c | 4 |
33 files changed, 610 insertions, 347 deletions
diff --git a/src/attr.c b/src/attr.c index 93dea123f..999f41318 100644 --- a/src/attr.c +++ b/src/attr.c @@ -7,8 +7,6 @@ #include "git2/oid.h" #include <ctype.h> -GIT__USE_STRMAP - const char *git_attr__true = "[internal]__TRUE__"; const char *git_attr__false = "[internal]__FALSE__"; const char *git_attr__unset = "[internal]__UNSET__"; @@ -209,7 +207,7 @@ int git_attr_foreach( if (git_strmap_exists(seen, assign->name)) continue; - git_strmap_insert(seen, assign->name, assign, error); + git_strmap_insert(seen, assign->name, assign, &error); if (error < 0) goto cleanup; diff --git a/src/attrcache.c b/src/attrcache.c index cf0707ef0..6cac14bc3 100644 --- a/src/attrcache.c +++ b/src/attrcache.c @@ -5,8 +5,6 @@ #include "sysdir.h" #include "ignore.h" -GIT__USE_STRMAP - GIT_INLINE(int) attr_cache_lock(git_attr_cache *cache) { GIT_UNUSED(cache); /* avoid warning if threading is off */ @@ -82,7 +80,7 @@ static int attr_cache_make_entry( &entry, git_repository_workdir(repo), path, &cache->pool); if (!error) { - git_strmap_insert(cache->files, entry->path, entry, error); + git_strmap_insert(cache->files, entry->path, entry, &error); if (error > 0) error = 0; } @@ -435,7 +433,7 @@ int git_attr_cache__insert_macro(git_repository *repo, git_attr_rule *macro) giterr_set(GITERR_OS, "unable to get attr cache lock"); error = -1; } else { - git_strmap_insert(macros, macro->match.pattern, macro, error); + git_strmap_insert(macros, macro->match.pattern, macro, &error); git_mutex_unlock(&cache->lock); } diff --git a/src/cache.c b/src/cache.c index 16ae9b397..c92a3a78a 100644 --- a/src/cache.c +++ b/src/cache.c @@ -15,8 +15,6 @@ #include "object.h" #include "git2/oid.h" -GIT__USE_OIDMAP - bool git_cache__enabled = true; ssize_t git_cache__max_storage = (256 * 1024 * 1024); git_atomic_ssize git_cache__current_storage = {0}; @@ -47,13 +45,13 @@ void git_cache_dump_stats(git_cache *cache) { git_cached_obj *object; - if (kh_size(cache->map) == 0) + if (git_cache_size(cache) == 0) return; - printf("Cache %p: %d items cached, %"PRIdZ" bytes\n", - cache, kh_size(cache->map), cache->used_memory); + printf("Cache %p: %"PRIuZ" items cached, %"PRIdZ" bytes\n", + cache, git_cache_size(cache), cache->used_memory); - kh_foreach_value(cache->map, object, { + git_oidmap_foreach_value(cache->map, object, { char oid_str[9]; printf(" %s%c %s (%"PRIuZ")\n", git_object_type2string(object->type), @@ -81,14 +79,14 @@ static void clear_cache(git_cache *cache) { git_cached_obj *evict = NULL; - if (kh_size(cache->map) == 0) + if (git_cache_size(cache) == 0) return; - kh_foreach_value(cache->map, evict, { + git_oidmap_foreach_value(cache->map, evict, { git_cached_obj_decref(evict); }); - kh_clear(oid, cache->map); + git_oidmap_clear(cache->map); git_atomic_ssize_add(&git_cache__current_storage, -cache->used_memory); cache->used_memory = 0; } @@ -119,22 +117,22 @@ static void cache_evict_entries(git_cache *cache) ssize_t evicted_memory = 0; /* do not infinite loop if there's not enough entries to evict */ - if (evict_count > kh_size(cache->map)) { + if (evict_count > git_cache_size(cache)) { clear_cache(cache); return; } while (evict_count > 0) { - khiter_t pos = seed++ % kh_end(cache->map); + khiter_t pos = seed++ % git_oidmap_end(cache->map); - if (kh_exist(cache->map, pos)) { - git_cached_obj *evict = kh_val(cache->map, pos); + if (git_oidmap_has_data(cache->map, pos)) { + git_cached_obj *evict = git_oidmap_value_at(cache->map, pos); evict_count--; evicted_memory += evict->size; git_cached_obj_decref(evict); - kh_del(oid, cache->map, pos); + git_oidmap_delete_at(cache->map, pos); } } @@ -156,9 +154,9 @@ static void *cache_get(git_cache *cache, const git_oid *oid, unsigned int flags) if (!git_cache__enabled || git_rwlock_rdlock(&cache->lock) < 0) return NULL; - pos = kh_get(oid, cache->map, oid); - if (pos != kh_end(cache->map)) { - entry = kh_val(cache->map, pos); + pos = git_oidmap_lookup_index(cache->map, oid); + if (git_oidmap_valid_index(cache->map, pos)) { + entry = git_oidmap_value_at(cache->map, pos); if (flags && entry->flags != flags) { entry = NULL; @@ -193,16 +191,14 @@ static void *cache_store(git_cache *cache, git_cached_obj *entry) if (git_cache__current_storage.val > git_cache__max_storage) cache_evict_entries(cache); - pos = kh_get(oid, cache->map, &entry->oid); + pos = git_oidmap_lookup_index(cache->map, &entry->oid); /* not found */ - if (pos == kh_end(cache->map)) { + if (!git_oidmap_valid_index(cache->map, pos)) { int rval; - pos = kh_put(oid, cache->map, &entry->oid, &rval); + git_oidmap_insert(cache->map, &entry->oid, entry, &rval); if (rval >= 0) { - kh_key(cache->map, pos) = &entry->oid; - kh_val(cache->map, pos) = entry; git_cached_obj_incref(entry); cache->used_memory += entry->size; git_atomic_ssize_add(&git_cache__current_storage, (ssize_t)entry->size); @@ -210,7 +206,7 @@ static void *cache_store(git_cache *cache, git_cached_obj *entry) } /* found */ else { - git_cached_obj *stored_entry = kh_val(cache->map, pos); + git_cached_obj *stored_entry = git_oidmap_value_at(cache->map, pos); if (stored_entry->flags == entry->flags) { git_cached_obj_decref(entry); @@ -221,8 +217,8 @@ static void *cache_store(git_cache *cache, git_cached_obj *entry) git_cached_obj_decref(stored_entry); git_cached_obj_incref(entry); - kh_key(cache->map, pos) = &entry->oid; - kh_val(cache->map, pos) = entry; + git_oidmap_set_key_at(cache->map, pos, &entry->oid); + git_oidmap_set_value_at(cache->map, pos, entry); } else { /* NO OP */ } diff --git a/src/cache.h b/src/cache.h index 697123739..0f0bfcf5d 100644 --- a/src/cache.h +++ b/src/cache.h @@ -53,7 +53,7 @@ void *git_cache_get_any(git_cache *cache, const git_oid *oid); GIT_INLINE(size_t) git_cache_size(git_cache *cache) { - return (size_t)kh_size(cache->map); + return (size_t)git_oidmap_size(cache->map); } GIT_INLINE(void) git_cached_obj_incref(void *_obj) diff --git a/src/checkout.c b/src/checkout.c index b70d5ab35..af600da6c 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -35,8 +35,6 @@ #include "pool.h" #include "strmap.h" -GIT__USE_STRMAP - /* See docs/checkout-internals.md for more information */ enum { diff --git a/src/config_file.c b/src/config_file.c index 2e3d568bb..cd5727c05 100644 --- a/src/config_file.c +++ b/src/config_file.c @@ -21,8 +21,6 @@ #include <sys/types.h> #include <regex.h> -GIT__USE_STRMAP - typedef struct cvar_t { struct cvar_t *next; git_config_entry *entry; @@ -179,7 +177,7 @@ static int append_entry(git_strmap *values, cvar_t *var) pos = git_strmap_lookup_index(values, var->entry->name); if (!git_strmap_valid_index(values, pos)) { - git_strmap_insert(values, var->entry->name, var, error); + git_strmap_insert(values, var->entry->name, var, &error); } else { existing = git_strmap_value_at(values, pos); while (existing->next != NULL) { diff --git a/src/describe.c b/src/describe.c index 16e195542..4a1e25378 100644 --- a/src/describe.c +++ b/src/describe.c @@ -19,8 +19,6 @@ #include "vector.h" #include "repository.h" -GIT__USE_OIDMAP - /* Ported from https://github.com/git/git/blob/89dde7882f71f846ccd0359756d27bebc31108de/builtin/describe.c */ struct commit_name { @@ -127,7 +125,7 @@ static int add_to_known_names( if (!found) { int ret; - git_oidmap_insert(names, &e->peeled, e, ret); + git_oidmap_insert(names, &e->peeled, e, &ret); if (ret < 0) return -1; } diff --git a/src/diff_driver.c b/src/diff_driver.c index 0adf704fb..9109f3155 100644 --- a/src/diff_driver.c +++ b/src/diff_driver.c @@ -16,8 +16,6 @@ #include "config.h" #include "repository.h" -GIT__USE_STRMAP - typedef enum { DIFF_DRIVER_AUTO = 0, DIFF_DRIVER_BINARY = 1, @@ -217,7 +215,7 @@ static int git_diff_driver_builtin( goto done; } - git_strmap_insert(reg->drivers, drv->name, drv, error); + git_strmap_insert(reg->drivers, drv->name, drv, &error); if (error > 0) error = 0; @@ -331,7 +329,7 @@ static int git_diff_driver_load( goto done; /* store driver in registry */ - git_strmap_insert(reg->drivers, drv->name, drv, error); + git_strmap_insert(reg->drivers, drv->name, drv, &error); if (error < 0) goto done; error = 0; diff --git a/src/fileops.c b/src/fileops.c index 7a8733209..57dea8fce 100644 --- a/src/fileops.c +++ b/src/fileops.c @@ -13,8 +13,6 @@ #include "win32/findfile.h" #endif -GIT__USE_STRMAP - int git_futils_mkpath2file(const char *file_path, const mode_t mode) { return git_futils_mkdir( @@ -607,7 +605,7 @@ retry_lstat: memcpy(cache_path, make_path.ptr, make_path.size + 1); - git_strmap_insert(opts->dir_map, cache_path, cache_path, error); + git_strmap_insert(opts->dir_map, cache_path, cache_path, &error); if (error < 0) goto done; } diff --git a/src/idxmap.c b/src/idxmap.c new file mode 100644 index 000000000..10f55ad39 --- /dev/null +++ b/src/idxmap.c @@ -0,0 +1,133 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ + +#include "idxmap.h" + +/* This is __ac_X31_hash_string but with tolower and it takes the entry's stage into account */ +static kh_inline khint_t idxentry_hash(const git_index_entry *e) +{ + const char *s = e->path; + khint_t h = (khint_t)git__tolower(*s); + if (h) for (++s ; *s; ++s) h = (h << 5) - h + (khint_t)git__tolower(*s); + return h + GIT_IDXENTRY_STAGE(e); +} + +#define idxentry_equal(a, b) (GIT_IDXENTRY_STAGE(a) == GIT_IDXENTRY_STAGE(b) && strcmp(a->path, b->path) == 0) +#define idxentry_icase_equal(a, b) (GIT_IDXENTRY_STAGE(a) == GIT_IDXENTRY_STAGE(b) && strcasecmp(a->path, b->path) == 0) + +__KHASH_IMPL(idx, static kh_inline, const git_index_entry *, git_index_entry *, 1, idxentry_hash, idxentry_equal) +__KHASH_IMPL(idxicase, static kh_inline, const git_index_entry *, git_index_entry *, 1, idxentry_hash, idxentry_icase_equal) + +int git_idxmap_alloc(git_idxmap **map) +{ + if ((*map = kh_init(idx)) == NULL) { + giterr_set_oom(); + return -1; + } + + return 0; +} + +int git_idxmap_icase_alloc(git_idxmap_icase **map) +{ + if ((*map = kh_init(idxicase)) == NULL) { + giterr_set_oom(); + return -1; + } + + return 0; +} + +void git_idxmap_insert(git_idxmap *map, const git_index_entry *key, void *value, int *rval) +{ + khiter_t idx = kh_put(idx, map, key, rval); + + if ((*rval) >= 0) { + if ((*rval) == 0) + kh_key(map, idx) = key; + kh_val(map, idx) = value; + } +} + +void git_idxmap_icase_insert(git_idxmap_icase *map, const git_index_entry *key, void *value, int *rval) +{ + khiter_t idx = kh_put(idxicase, map, key, rval); + + if ((*rval) >= 0) { + if ((*rval) == 0) + kh_key(map, idx) = key; + kh_val(map, idx) = value; + } +} + +size_t git_idxmap_lookup_index(git_idxmap *map, const git_index_entry *key) +{ + return kh_get(idx, map, key); +} + +size_t git_idxmap_icase_lookup_index(git_idxmap_icase *map, const git_index_entry *key) +{ + return kh_get(idxicase, map, key); +} + +void *git_idxmap_value_at(git_idxmap *map, size_t idx) +{ + return kh_val(map, idx); +} + +int git_idxmap_valid_index(git_idxmap *map, size_t idx) +{ + return idx != kh_end(map); +} + +int git_idxmap_has_data(git_idxmap *map, size_t idx) +{ + return kh_exist(map, idx); +} + +void git_idxmap_resize(git_idxmap *map, size_t size) +{ + kh_resize(idx, map, size); +} + +void git_idxmap_icase_resize(git_idxmap_icase *map, size_t size) +{ + kh_resize(idxicase, map, size); +} + +void git_idxmap__free(git_idxmap *map) +{ + kh_destroy(idx, map); +} + +void git_idxmap_clear(git_idxmap *map) +{ + kh_clear(idx, map); +} + +void git_idxmap_delete_at(git_idxmap *map, size_t idx) +{ + kh_del(idx, map, idx); +} + +void git_idxmap_icase_delete_at(git_idxmap_icase *map, size_t idx) +{ + kh_del(idxicase, map, idx); +} + +void git_idxmap_delete(git_idxmap *map, const git_index_entry *key) +{ + khiter_t idx = git_idxmap_lookup_index(map, key); + if (git_idxmap_valid_index(map, idx)) + git_idxmap_delete_at(map, idx); +} +void git_idxmap_icase_delete(git_idxmap_icase *map, const git_index_entry *key) +{ + khiter_t idx = git_idxmap_icase_lookup_index(map, key); + if (git_idxmap_valid_index((git_idxmap *)map, idx)) + git_idxmap_icase_delete_at(map, idx); +} diff --git a/src/idxmap.h b/src/idxmap.h index 4122a89fe..e4e9ec4cd 100644 --- a/src/idxmap.h +++ b/src/idxmap.h @@ -26,66 +26,28 @@ typedef khash_t(idxicase) git_idxmap_icase; typedef khiter_t git_idxmap_iter; -/* This is __ac_X31_hash_string but with tolower and it takes the entry's stage into account */ -static kh_inline khint_t idxentry_hash(const git_index_entry *e) -{ - const char *s = e->path; - khint_t h = (khint_t)git__tolower(*s); - if (h) for (++s ; *s; ++s) h = (h << 5) - h + (khint_t)git__tolower(*s); - return h + GIT_IDXENTRY_STAGE(e); -} - -#define idxentry_equal(a, b) (GIT_IDXENTRY_STAGE(a) == GIT_IDXENTRY_STAGE(b) && strcmp(a->path, b->path) == 0) -#define idxentry_icase_equal(a, b) (GIT_IDXENTRY_STAGE(a) == GIT_IDXENTRY_STAGE(b) && strcasecmp(a->path, b->path) == 0) - -#define GIT__USE_IDXMAP \ - __KHASH_IMPL(idx, static kh_inline, const git_index_entry *, git_index_entry *, 1, idxentry_hash, idxentry_equal) - -#define GIT__USE_IDXMAP_ICASE \ - __KHASH_IMPL(idxicase, static kh_inline, const git_index_entry *, git_index_entry *, 1, idxentry_hash, idxentry_icase_equal) - -#define git_idxmap_alloc(hp) \ - ((*(hp) = kh_init(idx)) == NULL) ? giterr_set_oom(), -1 : 0 - -#define git_idxmap_icase_alloc(hp) \ - ((*(hp) = kh_init(idxicase)) == NULL) ? giterr_set_oom(), -1 : 0 - -#define git_idxmap_insert(h, key, val, rval) do { \ - khiter_t __pos = kh_put(idx, h, key, &rval); \ - if (rval >= 0) { \ - if (rval == 0) kh_key(h, __pos) = key; \ - kh_val(h, __pos) = val; \ - } } while (0) - -#define git_idxmap_icase_insert(h, key, val, rval) do { \ - khiter_t __pos = kh_put(idxicase, h, key, &rval); \ - if (rval >= 0) { \ - if (rval == 0) kh_key(h, __pos) = key; \ - kh_val(h, __pos) = val; \ - } } while (0) - -#define git_idxmap_lookup_index(h, k) kh_get(idx, h, k) -#define git_idxmap_icase_lookup_index(h, k) kh_get(idxicase, h, k) -#define git_idxmap_value_at(h, idx) kh_val(h, idx) -#define git_idxmap_valid_index(h, idx) (idx != kh_end(h)) -#define git_idxmap_has_data(h, idx) kh_exist(h, idx) - -#define git_idxmap_resize(h,s) kh_resize(idx, h, s) -#define git_idxmap_free(h) kh_destroy(idx, h), h = NULL -#define git_idxmap_clear(h) kh_clear(idx, h) - -#define git_idxmap_delete_at(h, id) kh_del(idx, h, id) -#define git_idxmap_icase_delete_at(h, id) kh_del(idxicase, h, id) - -#define git_idxmap_delete(h, key) do { \ - khiter_t __pos = git_idxmap_lookup_index(h, key); \ - if (git_idxmap_valid_index(h, __pos)) \ - git_idxmap_delete_at(h, __pos); } while (0) - -#define git_idxmap_icase_delete(h, key) do { \ - khiter_t __pos = git_idxmap_icase_lookup_index(h, key); \ - if (git_idxmap_valid_index(h, __pos)) \ - git_idxmap_icase_delete_at(h, __pos); } while (0) +int git_idxmap_alloc(git_idxmap **map); +int git_idxmap_icase_alloc(git_idxmap_icase **map); +void git_idxmap_insert(git_idxmap *map, const git_index_entry *key, void *value, int *rval); +void git_idxmap_icase_insert(git_idxmap_icase *map, const git_index_entry *key, void *value, int *rval); + +size_t git_idxmap_lookup_index(git_idxmap *map, const git_index_entry *key); +size_t git_idxmap_icase_lookup_index(git_idxmap_icase *map, const git_index_entry *key); +void *git_idxmap_value_at(git_idxmap *map, size_t idx); +int git_idxmap_valid_index(git_idxmap *map, size_t idx); +int git_idxmap_has_data(git_idxmap *map, size_t idx); + +void git_idxmap_resize(git_idxmap *map, size_t size); +void git_idxmap_icase_resize(git_idxmap_icase *map, size_t size); +#define git_idxmap_free(h) git_idxmap__free(h); (h) = NULL +void git_idxmap__free(git_idxmap *map); +void git_idxmap_clear(git_idxmap *map); + +void git_idxmap_delete_at(git_idxmap *map, size_t idx); +void git_idxmap_icase_delete_at(git_idxmap_icase *map, size_t idx); + +void git_idxmap_delete(git_idxmap *map, const git_index_entry *key); +void git_idxmap_icase_delete(git_idxmap_icase *map, const git_index_entry *key); #define git_idxmap_begin kh_begin #define git_idxmap_end kh_end diff --git a/src/index.c b/src/index.c index f27fa16d2..932a5306a 100644 --- a/src/index.c +++ b/src/index.c @@ -27,9 +27,6 @@ #include "git2/config.h" #include "git2/sys/index.h" -GIT__USE_IDXMAP -GIT__USE_IDXMAP_ICASE - #define INSERT_IN_MAP_EX(idx, map, e, err) do { \ if ((idx)->ignore_case) \ git_idxmap_icase_insert((khash_t(idxicase) *) (map), (e), (e), (err)); \ @@ -1365,7 +1362,7 @@ static int index_insert( error = git_vector_insert_sorted(&index->entries, entry, index_no_dups); if (error == 0) { - INSERT_IN_MAP(index, entry, error); + INSERT_IN_MAP(index, entry, &error); } } @@ -1592,7 +1589,7 @@ int git_index__fill(git_index *index, const git_vector *source_entries) if ((ret = git_vector_insert(&index->entries, entry)) < 0) break; - INSERT_IN_MAP(index, entry, ret); + INSERT_IN_MAP(index, entry, &ret); if (ret < 0) break; } @@ -2479,9 +2476,9 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size) assert(!index->entries.length); if (index->ignore_case) - kh_resize(idxicase, (khash_t(idxicase) *) index->entries_map, header.entry_count); + git_idxmap_icase_resize((khash_t(idxicase) *) index->entries_map, header.entry_count); else - kh_resize(idx, index->entries_map, header.entry_count); + git_idxmap_resize(index->entries_map, header.entry_count); /* Parse all the entries */ for (i = 0; i < header.entry_count && buffer_size > INDEX_FOOTER_SIZE; ++i) { @@ -2499,7 +2496,7 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size) goto done; } - INSERT_IN_MAP(index, entry, error); + INSERT_IN_MAP(index, entry, &error); if (error < 0) { index_entry_free(entry); @@ -2979,12 +2976,12 @@ int git_index_read_tree(git_index *index, const git_tree *tree) goto cleanup; if (index->ignore_case) - kh_resize(idxicase, (khash_t(idxicase) *) entries_map, entries.length); + git_idxmap_icase_resize((khash_t(idxicase) *) entries_map, entries.length); else - kh_resize(idx, entries_map, entries.length); + git_idxmap_resize(entries_map, entries.length); git_vector_foreach(&entries, i, e) { - INSERT_IN_MAP_EX(index, entries_map, e, error); + INSERT_IN_MAP_EX(index, entries_map, e, &error); if (error < 0) { giterr_set(GITERR_INDEX, "failed to insert entry into map"); @@ -3037,9 +3034,9 @@ static int git_index_read_iterator( goto done; if (index->ignore_case && new_length_hint) - kh_resize(idxicase, (khash_t(idxicase) *) new_entries_map, new_length_hint); + git_idxmap_icase_resize((khash_t(idxicase) *) new_entries_map, new_length_hint); else if (new_length_hint) - kh_resize(idx, new_entries_map, new_length_hint); + git_idxmap_resize(new_entries_map, new_length_hint); opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE | GIT_ITERATOR_INCLUDE_CONFLICTS; @@ -3103,7 +3100,7 @@ static int git_index_read_iterator( if (add_entry) { if ((error = git_vector_insert(&new_entries, add_entry)) == 0) - INSERT_IN_MAP_EX(index, new_entries_map, add_entry, error); + INSERT_IN_MAP_EX(index, new_entries_map, add_entry, &error); } if (remove_entry && error >= 0) diff --git a/src/indexer.c b/src/indexer.c index 606de2ef6..869e2299f 100644 --- a/src/indexer.c +++ b/src/indexer.c @@ -18,8 +18,6 @@ #include "oidmap.h" #include "zstream.h" -GIT__USE_OIDMAP - extern git_mutex git__mwindow_mutex; #define UINT31_MAX (0x7FFFFFFF) @@ -294,7 +292,7 @@ static int store_object(git_indexer *idx) git_oid_cpy(&pentry->sha1, &oid); pentry->offset = entry_start; - k = kh_put(oid, idx->pack->idx_cache, &pentry->sha1, &error); + k = git_oidmap_put(idx->pack->idx_cache, &pentry->sha1, &error); if (error == -1) { git__free(pentry); giterr_set_oom(); @@ -308,7 +306,7 @@ static int store_object(git_indexer *idx) } - kh_value(idx->pack->idx_cache, k) = pentry; + git_oidmap_set_value_at(idx->pack->idx_cache, k, pentry); git_oid_cpy(&entry->oid, &oid); @@ -333,9 +331,7 @@ on_error: GIT_INLINE(bool) has_entry(git_indexer *idx, git_oid *id) { - khiter_t k; - k = kh_get(oid, idx->pack->idx_cache, id); - return (k != kh_end(idx->pack->idx_cache)); + return git_oidmap_exists(idx->pack->idx_cache, id); } static int save_entry(git_indexer *idx, struct entry *entry, struct git_pack_entry *pentry, git_off_t entry_start) @@ -351,14 +347,14 @@ static int save_entry(git_indexer *idx, struct entry *entry, struct git_pack_ent } pentry->offset = entry_start; - k = kh_put(oid, idx->pack->idx_cache, &pentry->sha1, &error); + k = git_oidmap_put(idx->pack->idx_cache, &pentry->sha1, &error); if (error <= 0) { giterr_set(GITERR_INDEXER, "cannot insert object into pack"); return -1; } - kh_value(idx->pack->idx_cache, k) = pentry; + git_oidmap_set_value_at(idx->pack->idx_cache, k, pentry); /* Add the object to the list */ if (git_vector_insert(&idx->objects, entry) < 0) @@ -1106,8 +1102,9 @@ void git_indexer_free(git_indexer *idx) if (idx->pack->idx_cache) { struct git_pack_entry *pentry; - kh_foreach_value( - idx->pack->idx_cache, pentry, { git__free(pentry); }); + git_oidmap_foreach_value(idx->pack->idx_cache, pentry, { + git__free(pentry); + }); git_oidmap_free(idx->pack->idx_cache); } diff --git a/src/mwindow.c b/src/mwindow.c index 520e7685f..7bb9dbbe2 100644 --- a/src/mwindow.c +++ b/src/mwindow.c @@ -14,8 +14,6 @@ #include "strmap.h" #include "pack.h" -GIT__USE_STRMAP - #define DEFAULT_WINDOW_SIZE \ (sizeof(void*) >= 8 \ ? 1 * 1024 * 1024 * 1024 \ @@ -84,7 +82,7 @@ int git_mwindow_get_pack(struct git_pack_file **out, const char *path) git_atomic_inc(&pack->refcount); - git_strmap_insert(git__pack_cache, pack->pack_name, pack, error); + git_strmap_insert(git__pack_cache, pack->pack_name, pack, &error); git_mutex_unlock(&git__mwindow_mutex); if (error < 0) { diff --git a/src/odb_mempack.c b/src/odb_mempack.c index 84ed9c104..d6f2fb4af 100644 --- a/src/odb_mempack.c +++ b/src/odb_mempack.c @@ -18,8 +18,6 @@ #include "git2/types.h" #include "git2/pack.h" -GIT__USE_OIDMAP - struct memobject { git_oid oid; size_t len; @@ -41,7 +39,7 @@ static int impl__write(git_odb_backend *_backend, const git_oid *oid, const void size_t alloc_len; int rval; - pos = kh_put(oid, db->objects, oid, &rval); + pos = git_oidmap_put(db->objects, oid, &rval); if (rval < 0) return -1; @@ -57,8 +55,8 @@ static int impl__write(git_odb_backend *_backend, const git_oid *oid, const void obj->len = len; obj->type = type; - kh_key(db->objects, pos) = &obj->oid; - kh_val(db->objects, pos) = obj; + git_oidmap_set_key_at(db->objects, pos, &obj->oid); + git_oidmap_set_value_at(db->objects, pos, obj); if (type == GIT_OBJ_COMMIT) { struct memobject **store = git_array_alloc(db->commits); @@ -72,13 +70,8 @@ static int impl__write(git_odb_backend *_backend, const git_oid *oid, const void static int impl__exists(git_odb_backend *backend, const git_oid *oid) { struct memory_packer_db *db = (struct memory_packer_db *)backend; - khiter_t pos; - pos = kh_get(oid, db->objects, oid); - if (pos != kh_end(db->objects)) - return 1; - - return 0; + return git_oidmap_exists(db->objects, oid); } static int impl__read(void **buffer_p, size_t *len_p, git_otype *type_p, git_odb_backend *backend, const git_oid *oid) @@ -87,11 +80,11 @@ static int impl__read(void **buffer_p, size_t *len_p, git_otype *type_p, git_odb struct memobject *obj = NULL; khiter_t pos; - pos = kh_get(oid, db->objects, oid); - if (pos == kh_end(db->objects)) + pos = git_oidmap_lookup_index(db->objects, oid); + if (!git_oidmap_valid_index(db->objects, pos)) return GIT_ENOTFOUND; - obj = kh_val(db->objects, pos); + obj = git_oidmap_value_at(db->objects, pos); *len_p = obj->len; *type_p = obj->type; @@ -108,11 +101,11 @@ static int impl__read_header(size_t *len_p, git_otype *type_p, git_odb_backend * struct memobject *obj = NULL; khiter_t pos; - pos = kh_get(oid, db->objects, oid); - if (pos == kh_end(db->objects)) + pos = git_oidmap_lookup_index(db->objects, oid); + if (!git_oidmap_valid_index(db->objects, pos)) return GIT_ENOTFOUND; - obj = kh_val(db->objects, pos); + obj = git_oidmap_value_at(db->objects, pos); *len_p = obj->len; *type_p = obj->type; @@ -149,7 +142,7 @@ void git_mempack_reset(git_odb_backend *_backend) struct memory_packer_db *db = (struct memory_packer_db *)_backend; struct memobject *object = NULL; - kh_foreach_value(db->objects, object, { + git_oidmap_foreach_value(db->objects, object, { git__free(object); }); diff --git a/src/offmap.c b/src/offmap.c new file mode 100644 index 000000000..023c9b417 --- /dev/null +++ b/src/offmap.c @@ -0,0 +1,83 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ + +#include "offmap.h" + +__KHASH_IMPL(off, static kh_inline, git_off_t, void *, 1, kh_int64_hash_func, kh_int64_hash_equal) + +git_offmap *git_offmap_alloc(void) +{ + return kh_init(off); +} + +void git_offmap__free(git_offmap *map) +{ + kh_destroy(off, map); +} + +void git_offmap_clear(git_offmap *map) +{ + kh_clear(off, map); +} + +size_t git_offmap_num_entries(git_offmap *map) +{ + return kh_size(map); +} + +size_t git_offmap_lookup_index(git_offmap *map, const git_off_t key) +{ + return kh_get(off, map, key); +} + +int git_offmap_valid_index(git_offmap *map, size_t idx) +{ + return idx != kh_end(map); +} + +int git_offmap_exists(git_offmap *map, const git_off_t key) +{ + return kh_get(off, map, key) != kh_end(map); +} + +void *git_offmap_value_at(git_offmap *map, size_t idx) +{ + return kh_val(map, idx); +} + +void git_offmap_set_value_at(git_offmap *map, size_t idx, void *value) +{ + kh_val(map, idx) = value; +} + +void git_offmap_delete_at(git_offmap *map, size_t idx) +{ + kh_del(off, map, idx); +} + +int git_offmap_put(git_offmap *map, const git_off_t key, int *err) +{ + return kh_put(off, map, key, err); +} + +void git_offmap_insert(git_offmap *map, const git_off_t key, void *value, int *rval) +{ + khiter_t idx = kh_put(off, map, key, rval); + + if ((*rval) >= 0) { + if ((*rval) == 0) + kh_key(map, idx) = key; + kh_val(map, idx) = value; + } +} + +void git_offmap_delete(git_offmap *map, const git_off_t key) +{ + khiter_t idx = git_offmap_lookup_index(map, key); + if (git_offmap_valid_index(map, idx)) + git_offmap_delete_at(map, idx); +} diff --git a/src/offmap.h b/src/offmap.h index 0d0e51272..1f30cda6d 100644 --- a/src/offmap.h +++ b/src/offmap.h @@ -20,45 +20,25 @@ __KHASH_TYPE(off, git_off_t, void *) typedef khash_t(off) git_offmap; -#define GIT__USE_OFFMAP \ - __KHASH_IMPL(off, static kh_inline, git_off_t, void *, 1, kh_int64_hash_func, kh_int64_hash_equal) +git_offmap *git_offmap_alloc(void); +#define git_offmap_free(h) git_offmap__free(h); (h) = NULL +void git_offmap__free(git_offmap *map); +void git_offmap_clear(git_offmap *map); -#define git_offmap_alloc() kh_init(off) -#define git_offmap_free(h) kh_destroy(off, h), h = NULL -#define git_offmap_clear(h) kh_clear(off, h) +size_t git_offmap_num_entries(git_offmap *map); -#define git_offmap_num_entries(h) kh_size(h) +size_t git_offmap_lookup_index(git_offmap *map, const git_off_t key); +int git_offmap_valid_index(git_offmap *map, size_t idx); -#define git_offmap_lookup_index(h, k) kh_get(off, h, k) -#define git_offmap_valid_index(h, idx) (idx != kh_end(h)) +int git_offmap_exists(git_offmap *map, const git_off_t key); -#define git_offmap_exists(h, k) (kh_get(off, h, k) != kh_end(h)) +void *git_offmap_value_at(git_offmap *map, size_t idx); +void git_offmap_set_value_at(git_offmap *map, size_t idx, void *value); +void git_offmap_delete_at(git_offmap *map, size_t idx); -#define git_offmap_value_at(h, idx) kh_val(h, idx) -#define git_offmap_set_value_at(h, idx, v) kh_val(h, idx) = v -#define git_offmap_delete_at(h, idx) kh_del(off, h, idx) - -#define git_offmap_insert(h, key, val, rval) do { \ - khiter_t __pos = kh_put(off, h, key, &rval); \ - if (rval >= 0) { \ - if (rval == 0) kh_key(h, __pos) = key; \ - kh_val(h, __pos) = val; \ - } } while (0) - -#define git_offmap_insert2(h, key, val, oldv, rval) do { \ - khiter_t __pos = kh_put(off, h, key, &rval); \ - if (rval >= 0) { \ - if (rval == 0) { \ - oldv = kh_val(h, __pos); \ - kh_key(h, __pos) = key; \ - } else { oldv = NULL; } \ - kh_val(h, __pos) = val; \ - } } while (0) - -#define git_offmap_delete(h, key) do { \ - khiter_t __pos = git_offmap_lookup_index(h, key); \ - if (git_offmap_valid_index(h, __pos)) \ - git_offmap_delete_at(h, __pos); } while (0) +int git_offmap_put(git_offmap *map, const git_off_t key, int *err); +void git_offmap_insert(git_offmap *map, const git_off_t key, void *value, int *rval); +void git_offmap_delete(git_offmap *map, const git_off_t key); #define git_offmap_foreach kh_foreach #define git_offmap_foreach_value kh_foreach_value diff --git a/src/oidmap.c b/src/oidmap.c new file mode 100644 index 000000000..0df9a4f42 --- /dev/null +++ b/src/oidmap.c @@ -0,0 +1,105 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ + +#include "oidmap.h" + +GIT_INLINE(khint_t) git_oidmap_hash(const git_oid *oid) +{ + khint_t h; + memcpy(&h, oid, sizeof(khint_t)); + return h; +} + +__KHASH_IMPL(oid, static kh_inline, const git_oid *, void *, 1, git_oidmap_hash, git_oid_equal) + +git_oidmap *git_oidmap_alloc() +{ + return kh_init(oid); +} + +void git_oidmap__free(git_oidmap *map) +{ + kh_destroy(oid, map); +} + +void git_oidmap_clear(git_oidmap *map) +{ + kh_clear(oid, map); +} + +size_t git_oidmap_size(git_oidmap *map) +{ + return kh_size(map); +} + +size_t git_oidmap_lookup_index(git_oidmap *map, const git_oid *key) +{ + return kh_get(oid, map, key); +} + +int git_oidmap_valid_index(git_oidmap *map, size_t idx) +{ + return idx != kh_end(map); +} + +int git_oidmap_exists(git_oidmap *map, const git_oid *key) +{ + return kh_get(oid, map, key) != kh_end(map); +} + +int git_oidmap_has_data(git_oidmap *map, size_t idx) +{ + return kh_exist(map, idx); +} + +const git_oid *git_oidmap_key(git_oidmap *map, size_t idx) +{ + return kh_key(map, idx); +} + +void git_oidmap_set_key_at(git_oidmap *map, size_t idx, git_oid *key) +{ + kh_key(map, idx) = key; +} + +void *git_oidmap_value_at(git_oidmap *map, size_t idx) +{ + return kh_val(map, idx); +} + +void git_oidmap_set_value_at(git_oidmap *map, size_t idx, void *value) +{ + kh_val(map, idx) = value; +} + +void git_oidmap_delete_at(git_oidmap *map, size_t idx) +{ + kh_del(oid, map, idx); +} + +int git_oidmap_put(git_oidmap *map, const git_oid *key, int *err) +{ + return kh_put(oid, map, key, err); +} + +void git_oidmap_insert(git_oidmap *map, const git_oid *key, void *value, int *rval) +{ + khiter_t idx = kh_put(oid, map, key, rval); + + if ((*rval) >= 0) { + if ((*rval) == 0) + kh_key(map, idx) = key; + kh_val(map, idx) = value; + } +} + +void git_oidmap_delete(git_oidmap *map, const git_oid *key) +{ + khiter_t idx = git_oidmap_lookup_index(map, key); + if (git_oidmap_valid_index(map, idx)) + git_oidmap_delete_at(map, idx); +} diff --git a/src/oidmap.h b/src/oidmap.h index 2cf208f53..a3f8961dc 100644 --- a/src/oidmap.h +++ b/src/oidmap.h @@ -20,35 +20,32 @@ __KHASH_TYPE(oid, const git_oid *, void *) typedef khash_t(oid) git_oidmap; -GIT_INLINE(khint_t) git_oidmap_hash(const git_oid *oid) -{ - khint_t h; - memcpy(&h, oid, sizeof(khint_t)); - return h; -} +git_oidmap *git_oidmap_alloc(void); +#define git_oidmap_free(h) git_oidmap__free(h); (h) = NULL +void git_oidmap__free(git_oidmap *map); +void git_oidmap_clear(git_oidmap *map); -#define GIT__USE_OIDMAP \ - __KHASH_IMPL(oid, static kh_inline, const git_oid *, void *, 1, git_oidmap_hash, git_oid_equal) +size_t git_oidmap_size(git_oidmap *map); -#define git_oidmap_alloc() kh_init(oid) -#define git_oidmap_free(h) kh_destroy(oid,h), h = NULL +size_t git_oidmap_lookup_index(git_oidmap *map, const git_oid *key); +int git_oidmap_valid_index(git_oidmap *map, size_t idx); -#define git_oidmap_lookup_index(h, k) kh_get(oid, h, k) -#define git_oidmap_valid_index(h, idx) (idx != kh_end(h)) +int git_oidmap_exists(git_oidmap *map, const git_oid *key); +int git_oidmap_has_data(git_oidmap *map, size_t idx); -#define git_oidmap_value_at(h, idx) kh_val(h, idx) +const git_oid *git_oidmap_key(git_oidmap *map, size_t idx); +void git_oidmap_set_key_at(git_oidmap *map, size_t idx, git_oid *key); +void *git_oidmap_value_at(git_oidmap *map, size_t idx); +void git_oidmap_set_value_at(git_oidmap *map, size_t idx, void *value); +void git_oidmap_delete_at(git_oidmap *map, size_t idx); -#define git_oidmap_insert(h, key, val, rval) do { \ - khiter_t __pos = kh_put(oid, h, key, &rval); \ - if (rval >= 0) { \ - if (rval == 0) kh_key(h, __pos) = key; \ - kh_val(h, __pos) = val; \ - } } while (0) +int git_oidmap_put(git_oidmap *map, const git_oid *key, int *err); +void git_oidmap_insert(git_oidmap *map, const git_oid *key, void *value, int *rval); +void git_oidmap_delete(git_oidmap *map, const git_oid *key); #define git_oidmap_foreach_value kh_foreach_value -#define git_oidmap_size(h) kh_size(h) - -#define git_oidmap_clear(h) kh_clear(oid, h) +#define git_oidmap_begin kh_begin +#define git_oidmap_end kh_end #endif diff --git a/src/pack-objects.c b/src/pack-objects.c index 2e5de98ab..58b7b94b3 100644 --- a/src/pack-objects.c +++ b/src/pack-objects.c @@ -41,8 +41,6 @@ struct pack_write_context { git_transfer_progress *stats; }; -GIT__USE_OIDMAP - #ifdef GIT_THREADS #define GIT_PACKBUILDER__MUTEX_OP(pb, mtx, op) do { \ @@ -197,10 +195,10 @@ static void rehash(git_packbuilder *pb) size_t i; int ret; - kh_clear(oid, pb->object_ix); + git_oidmap_clear(pb->object_ix); for (i = 0, po = pb->object_list; i < pb->nr_objects; i++, po++) { - pos = kh_put(oid, pb->object_ix, &po->id, &ret); - kh_value(pb->object_ix, pos) = po; + pos = git_oidmap_put(pb->object_ix, &po->id, &ret); + git_oidmap_set_value_at(pb->object_ix, pos, po); } } @@ -216,8 +214,7 @@ int git_packbuilder_insert(git_packbuilder *pb, const git_oid *oid, /* If the object already exists in the hash table, then we don't * have any work to do */ - pos = kh_get(oid, pb->object_ix, oid); - if (pos != kh_end(pb->object_ix)) + if (git_oidmap_exists(pb->object_ix, oid)) return 0; if (pb->nr_objects >= pb->nr_alloc) { @@ -247,13 +244,13 @@ int git_packbuilder_insert(git_packbuilder *pb, const git_oid *oid, git_oid_cpy(&po->id, oid); po->hash = name_hash(name); - pos = kh_put(oid, pb->object_ix, &po->id, &ret); + pos = git_oidmap_put(pb->object_ix, &po->id, &ret); if (ret < 0) { giterr_set_oom(); return ret; } assert(ret != 0); - kh_value(pb->object_ix, pos) = po; + git_oidmap_set_value_at(pb->object_ix, pos, po); pb->done = false; @@ -517,11 +514,11 @@ static int cb_tag_foreach(const char *name, git_oid *oid, void *data) GIT_UNUSED(name); - pos = kh_get(oid, pb->object_ix, oid); - if (pos == kh_end(pb->object_ix)) + pos = git_oidmap_lookup_index(pb->object_ix, oid); + if (!git_oidmap_valid_index(pb->object_ix, pos)) return 0; - po = kh_value(pb->object_ix, pos); + po = git_oidmap_value_at(pb->object_ix, pos); po->tagged = 1; /* TODO: peel objects */ @@ -1541,7 +1538,7 @@ static int retrieve_object(git_walk_object **out, git_packbuilder *pb, const git if ((error = lookup_walk_object(&obj, pb, id)) < 0) return error; - git_oidmap_insert(pb->walk_objects, &obj->id, obj, error); + git_oidmap_insert(pb->walk_objects, &obj->id, obj, &error); } *out = obj; diff --git a/src/pack.c b/src/pack.c index 243719d9c..d59fae412 100644 --- a/src/pack.c +++ b/src/pack.c @@ -16,9 +16,6 @@ #include <zlib.h> -GIT__USE_OFFMAP -GIT__USE_OIDMAP - static int packfile_open(struct git_pack_file *p); static git_off_t nth_packed_object_offset(const struct git_pack_file *p, uint32_t n); static int packfile_unpack_compressed( @@ -78,13 +75,12 @@ static void free_cache_object(void *o) static void cache_free(git_pack_cache *cache) { - khiter_t k; + git_pack_cache_entry *entry; if (cache->entries) { - for (k = kh_begin(cache->entries); k != kh_end(cache->entries); k++) { - if (kh_exist(cache->entries, k)) - free_cache_object(kh_value(cache->entries, k)); - } + git_offmap_foreach_value(cache->entries, entry, { + free_cache_object(entry); + }); git_offmap_free(cache->entries); cache->entries = NULL; @@ -118,9 +114,9 @@ static git_pack_cache_entry *cache_get(git_pack_cache *cache, git_off_t offset) if (git_mutex_lock(&cache->lock) < 0) return NULL; - k = kh_get(off, cache->entries, offset); - if (k != kh_end(cache->entries)) { /* found it */ - entry = kh_value(cache->entries, k); + k = git_offmap_lookup_index(cache->entries, offset); + if (git_offmap_valid_index(cache->entries, k)) { /* found it */ + entry = git_offmap_value_at(cache->entries, k); git_atomic_inc(&entry->refcount); entry->last_usage = cache->use_ctr++; } @@ -135,18 +131,13 @@ static void free_lowest_entry(git_pack_cache *cache) git_pack_cache_entry *entry; khiter_t k; - for (k = kh_begin(cache->entries); k != kh_end(cache->entries); k++) { - if (!kh_exist(cache->entries, k)) - continue; - - entry = kh_value(cache->entries, k); - + git_offmap_foreach(cache->entries, k, entry, { if (entry && entry->refcount.val == 0) { cache->memory_used -= entry->raw.len; - kh_del(off, cache->entries, k); + git_offmap_delete_at(cache->entries, k); free_cache_object(entry); } - } + }); } static int cache_add( @@ -170,14 +161,14 @@ static int cache_add( return -1; } /* Add it to the cache if nobody else has */ - exists = kh_get(off, cache->entries, offset) != kh_end(cache->entries); + exists = git_offmap_exists(cache->entries, offset); if (!exists) { while (cache->memory_used + base->len > cache->memory_limit) free_lowest_entry(cache); - k = kh_put(off, cache->entries, offset, &error); + k = git_offmap_put(cache->entries, offset, &error); assert(error != 0); - kh_value(cache->entries, k) = entry; + git_offmap_set_value_at(cache->entries, k, entry); cache->memory_used += entry->raw.len; *cached_out = entry; @@ -962,10 +953,10 @@ git_off_t get_delta_base( git_oid oid; git_oid_fromraw(&oid, base_info); - k = kh_get(oid, p->idx_cache, &oid); - if (k != kh_end(p->idx_cache)) { + k = git_oidmap_lookup_index(p->idx_cache, &oid); + if (git_oidmap_valid_index(p->idx_cache, k)) { *curpos += 20; - return ((struct git_pack_entry *)kh_value(p->idx_cache, k))->offset; + return ((struct git_pack_entry *)git_oidmap_value_at(p->idx_cache, k))->offset; } else { /* If we're building an index, don't try to find the pack * entry; we just haven't seen it yet. We'll make diff --git a/src/refdb_fs.c b/src/refdb_fs.c index def5302de..e2a69d6ed 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -26,8 +26,6 @@ #include <git2/sys/refs.h> #include <git2/sys/reflog.h> -GIT__USE_STRMAP - #define DEFAULT_NESTING_LEVEL 5 #define MAX_NESTING_LEVEL 10 diff --git a/src/refs.c b/src/refs.c index 140b175af..70f5519c6 100644 --- a/src/refs.c +++ b/src/refs.c @@ -26,8 +26,6 @@ bool git_reference__enable_symbolic_ref_target_validation = true; -GIT__USE_STRMAP - #define DEFAULT_NESTING_LEVEL 5 #define MAX_NESTING_LEVEL 10 diff --git a/src/repository.c b/src/repository.c index 4b937be20..0db481638 100644 --- a/src/repository.c +++ b/src/repository.c @@ -30,7 +30,6 @@ #include "submodule.h" #include "worktree.h" -GIT__USE_STRMAP #include "strmap.h" #ifdef GIT_WIN32 diff --git a/src/revwalk.c b/src/revwalk.c index 8c370bcc8..6d08164ba 100644 --- a/src/revwalk.c +++ b/src/revwalk.c @@ -15,8 +15,6 @@ #include "merge.h" #include "vector.h" -GIT__USE_OIDMAP - git_commit_list_node *git_revwalk__commit_lookup( git_revwalk *walk, const git_oid *oid) { @@ -25,9 +23,9 @@ git_commit_list_node *git_revwalk__commit_lookup( int ret; /* lookup and reserve space if not already present */ - pos = kh_get(oid, walk->commits, oid); - if (pos != kh_end(walk->commits)) - return kh_value(walk->commits, pos); + pos = git_oidmap_lookup_index(walk->commits, oid); + if (git_oidmap_valid_index(walk->commits, pos)) + return git_oidmap_value_at(walk->commits, pos); commit = git_commit_list_alloc_node(walk); if (commit == NULL) @@ -35,9 +33,9 @@ git_commit_list_node *git_revwalk__commit_lookup( git_oid_cpy(&commit->oid, oid); - pos = kh_put(oid, walk->commits, &commit->oid, &ret); + pos = git_oidmap_put(walk->commits, &commit->oid, &ret); assert(ret != 0); - kh_value(walk->commits, pos) = commit; + git_oidmap_set_value_at(walk->commits, pos, commit); return commit; } @@ -702,7 +700,7 @@ void git_revwalk_reset(git_revwalk *walk) assert(walk); - kh_foreach_value(walk->commits, commit, { + git_oidmap_foreach_value(walk->commits, commit, { commit->seen = 0; commit->in_degree = 0; commit->topo_delay = 0; diff --git a/src/sortedcache.c b/src/sortedcache.c index c5e338f75..cc322d478 100644 --- a/src/sortedcache.c +++ b/src/sortedcache.c @@ -1,7 +1,5 @@ #include "sortedcache.h" -GIT__USE_STRMAP - int git_sortedcache_new( git_sortedcache **out, size_t item_path_offset, @@ -294,13 +292,13 @@ int git_sortedcache_upsert(void **out, git_sortedcache *sc, const char *key) item_key = ((char *)item) + sc->item_path_offset; memcpy(item_key, key, keylen); - pos = kh_put(str, sc->map, item_key, &error); + pos = git_strmap_put(sc->map, item_key, &error); if (error < 0) goto done; if (!error) - kh_key(sc->map, pos) = item_key; - kh_val(sc->map, pos) = item; + git_strmap_set_key_at(sc->map, pos, item_key); + git_strmap_set_value_at(sc->map, pos, item); error = git_vector_insert(&sc->items, item); if (error < 0) diff --git a/src/strmap.c b/src/strmap.c index b26a13d1f..678d98344 100644 --- a/src/strmap.c +++ b/src/strmap.c @@ -7,6 +7,101 @@ #include "strmap.h" +__KHASH_IMPL(str, static kh_inline, const char *, void *, 1, kh_str_hash_func, kh_str_hash_equal) + +int git_strmap_alloc(git_strmap **map) +{ + if ((*map = kh_init(str)) == NULL) { + giterr_set_oom(); + return -1; + } + + return 0; +} + +void git_strmap__free(git_strmap *map) +{ + kh_destroy(str, map); +} + +void git_strmap_clear(git_strmap *map) +{ + kh_clear(str, map); +} + +size_t git_strmap_num_entries(git_strmap *map) +{ + return kh_size(map); +} + +size_t git_strmap_lookup_index(git_strmap *map, const char *key) +{ + return kh_get(str, map, key); +} + +int git_strmap_valid_index(git_strmap *map, size_t idx) +{ + return idx != kh_end(map); +} + +int git_strmap_exists(git_strmap *map, const char *key) +{ + return kh_get(str, map, key) != kh_end(map); +} + +int git_strmap_has_data(git_strmap *map, size_t idx) +{ + return kh_exist(map, idx); +} + +const char *git_strmap_key(git_strmap *map, size_t idx) +{ + return kh_key(map, idx); +} + +void git_strmap_set_key_at(git_strmap *map, size_t idx, char *key) +{ + kh_val(map, idx) = key; +} + +void *git_strmap_value_at(git_strmap *map, size_t idx) +{ + return kh_val(map, idx); +} + +void git_strmap_set_value_at(git_strmap *map, size_t idx, void *value) +{ + kh_val(map, idx) = value; +} + +void git_strmap_delete_at(git_strmap *map, size_t idx) +{ + kh_del(str, map, idx); +} + +int git_strmap_put(git_strmap *map, const char *key, int *err) +{ + return kh_put(str, map, key, err); +} + +void git_strmap_insert(git_strmap *map, const char *key, void *value, int *rval) +{ + khiter_t idx = kh_put(str, map, key, rval); + + if ((*rval) >= 0) { + if ((*rval) == 0) + kh_key(map, idx) = key; + kh_val(map, idx) = value; + } +} + +void git_strmap_delete(git_strmap *map, const char *key) +{ + khiter_t idx = git_strmap_lookup_index(map, key); + if (git_strmap_valid_index(map, idx)) + git_strmap_delete_at(map, idx); +} + int git_strmap_next( void **data, git_strmap_iter* iter, diff --git a/src/strmap.h b/src/strmap.h index 520984744..389702c9b 100644 --- a/src/strmap.h +++ b/src/strmap.h @@ -20,49 +20,29 @@ __KHASH_TYPE(str, const char *, void *) typedef khash_t(str) git_strmap; typedef khiter_t git_strmap_iter; -#define GIT__USE_STRMAP \ - __KHASH_IMPL(str, static kh_inline, const char *, void *, 1, kh_str_hash_func, kh_str_hash_equal) +int git_strmap_alloc(git_strmap **map); -#define git_strmap_alloc(hp) \ - ((*(hp) = kh_init(str)) == NULL) ? giterr_set_oom(), -1 : 0 +#define git_strmap_free(h) git_strmap__free(h); (h) = NULL +void git_strmap__free(git_strmap *map); +void git_strmap_clear(git_strmap *map); -#define git_strmap_free(h) kh_destroy(str, h), h = NULL -#define git_strmap_clear(h) kh_clear(str, h) +size_t git_strmap_num_entries(git_strmap *map); -#define git_strmap_num_entries(h) kh_size(h) +size_t git_strmap_lookup_index(git_strmap *map, const char *key); +int git_strmap_valid_index(git_strmap *map, size_t idx); -#define git_strmap_lookup_index(h, k) kh_get(str, h, k) -#define git_strmap_valid_index(h, idx) (idx != kh_end(h)) +int git_strmap_exists(git_strmap *map, const char *key); +int git_strmap_has_data(git_strmap *map, size_t idx); -#define git_strmap_exists(h, k) (kh_get(str, h, k) != kh_end(h)) -#define git_strmap_has_data(h, idx) kh_exist(h, idx) +const char *git_strmap_key(git_strmap *map, size_t idx); +void git_strmap_set_key_at(git_strmap *map, size_t idx, char *key); +void *git_strmap_value_at(git_strmap *map, size_t idx); +void git_strmap_set_value_at(git_strmap *map, size_t idx, void *value); +void git_strmap_delete_at(git_strmap *map, size_t idx); -#define git_strmap_key(h, idx) kh_key(h, idx) -#define git_strmap_value_at(h, idx) kh_val(h, idx) -#define git_strmap_set_value_at(h, idx, v) kh_val(h, idx) = v -#define git_strmap_delete_at(h, idx) kh_del(str, h, idx) - -#define git_strmap_insert(h, key, val, rval) do { \ - khiter_t __pos = kh_put(str, h, key, &rval); \ - if (rval >= 0) { \ - if (rval == 0) kh_key(h, __pos) = key; \ - kh_val(h, __pos) = val; \ - } } while (0) - -#define git_strmap_insert2(h, key, val, oldv, rval) do { \ - khiter_t __pos = kh_put(str, h, key, &rval); \ - if (rval >= 0) { \ - if (rval == 0) { \ - oldv = kh_val(h, __pos); \ - kh_key(h, __pos) = key; \ - } else { oldv = NULL; } \ - kh_val(h, __pos) = val; \ - } } while (0) - -#define git_strmap_delete(h, key) do { \ - khiter_t __pos = git_strmap_lookup_index(h, key); \ - if (git_strmap_valid_index(h, __pos)) \ - git_strmap_delete_at(h, __pos); } while (0) +int git_strmap_put(git_strmap *map, const char *key, int *err); +void git_strmap_insert(git_strmap *map, const char *key, void *value, int *rval); +void git_strmap_delete(git_strmap *map, const char *key); #define git_strmap_foreach kh_foreach #define git_strmap_foreach_value kh_foreach_value diff --git a/src/submodule.c b/src/submodule.c index 3007d25df..095bbb090 100644 --- a/src/submodule.c +++ b/src/submodule.c @@ -186,7 +186,7 @@ static int load_submodule_names(git_strmap *out, git_config *cfg) ldot = strrchr(entry->name, '.'); git_buf_put(&buf, fdot + 1, ldot - fdot - 1); - git_strmap_insert(out, entry->value, git_buf_detach(&buf), rval); + git_strmap_insert(out, entry->value, git_buf_detach(&buf), &rval); if (rval < 0) { giterr_set(GITERR_NOMEMORY, "error inserting submodule into hash table"); return -1; @@ -329,7 +329,7 @@ static int submodule_get_or_create(git_submodule **out, git_repository *repo, gi if ((error = submodule_alloc(&sm, repo, name)) < 0) return error; - pos = kh_put(str, map, sm->name, &error); + pos = git_strmap_put(map, sm->name, &error); /* nobody can beat us to adding it */ assert(error != 0); if (error < 0) { @@ -555,7 +555,7 @@ int git_submodule_foreach( goto done; if (!(error = git_vector_init( - &snapshot, kh_size(submodules), submodule_cmp))) { + &snapshot, git_strmap_num_entries(submodules), submodule_cmp))) { git_strmap_foreach_value(submodules, sm, { if ((error = git_vector_insert(&snapshot, sm)) < 0) @@ -1866,7 +1866,7 @@ static int submodule_load_each(const git_config_entry *entry, void *payload) goto done; } - git_strmap_insert(map, sm->name, sm, error); + git_strmap_insert(map, sm->name, sm, &error); assert(error != 0); if (error < 0) goto done; diff --git a/src/transaction.c b/src/transaction.c index 2c8a1e8bd..3d3f35a03 100644 --- a/src/transaction.c +++ b/src/transaction.c @@ -19,8 +19,6 @@ #include "git2/sys/refs.h" #include "git2/sys/refdb_backend.h" -GIT__USE_STRMAP - typedef enum { TRANSACTION_NONE, TRANSACTION_REFS, @@ -120,7 +118,7 @@ int git_transaction_lock_ref(git_transaction *tx, const char *refname) if ((error = git_refdb_lock(&node->payload, tx->db, refname)) < 0) return error; - git_strmap_insert(tx->locks, node->name, node, error); + git_strmap_insert(tx->locks, node->name, node, &error); if (error < 0) goto cleanup; @@ -323,7 +321,6 @@ static int update_target(git_refdb *db, transaction_node *node) int git_transaction_commit(git_transaction *tx) { transaction_node *node; - git_strmap_iter pos; int error = 0; assert(tx); @@ -335,11 +332,7 @@ int git_transaction_commit(git_transaction *tx) return error; } - for (pos = kh_begin(tx->locks); pos < kh_end(tx->locks); pos++) { - if (!git_strmap_has_data(tx->locks, pos)) - continue; - - node = git_strmap_value_at(tx->locks, pos); + git_strmap_foreach_value(tx->locks, node, { if (node->reflog) { if ((error = tx->db->backend->reflog_write(tx->db->backend, node->reflog)) < 0) return error; @@ -349,7 +342,7 @@ int git_transaction_commit(git_transaction *tx) if ((error = update_target(tx->db, node)) < 0) return error; } - } + }); return 0; } @@ -358,7 +351,6 @@ void git_transaction_free(git_transaction *tx) { transaction_node *node; git_pool pool; - git_strmap_iter pos; assert(tx); @@ -373,16 +365,12 @@ void git_transaction_free(git_transaction *tx) } /* start by unlocking the ones we've left hanging, if any */ - for (pos = kh_begin(tx->locks); pos < kh_end(tx->locks); pos++) { - if (!git_strmap_has_data(tx->locks, pos)) - continue; - - node = git_strmap_value_at(tx->locks, pos); + git_strmap_foreach_value(tx->locks, node, { if (node->committed) continue; git_refdb_unlock(tx->db, node->payload, false, false, NULL, NULL, NULL); - } + }); git_refdb_free(tx->db); git_strmap_free(tx->locks); diff --git a/src/tree.c b/src/tree.c index 26da296d5..dba2060c3 100644 --- a/src/tree.c +++ b/src/tree.c @@ -20,8 +20,6 @@ #define TREE_ENTRY_CHECK_NAMELEN(n) \ if (n > UINT16_MAX) { giterr_set(GITERR_INVALID, "tree entry path too long"); } -GIT__USE_STRMAP - static bool valid_filemode(const int filemode) { return (filemode == GIT_FILEMODE_TREE @@ -505,7 +503,7 @@ static int append_entry( entry->attr = (uint16_t)filemode; - git_strmap_insert(bld->map, entry->filename, entry, error); + git_strmap_insert(bld->map, entry->filename, entry, &error); if (error < 0) { git_tree_entry_free(entry); giterr_set(GITERR_TREE, "failed to append entry %s to the tree builder", filename); @@ -754,7 +752,7 @@ int git_treebuilder_insert( entry = alloc_entry(filename, strlen(filename), id); GITERR_CHECK_ALLOC(entry); - git_strmap_insert(bld->map, entry->filename, entry, error); + git_strmap_insert(bld->map, entry->filename, entry, &error); if (error < 0) { git_tree_entry_free(entry); diff --git a/tests/core/oidmap.c b/tests/core/oidmap.c index 556a6ca4a..617da5483 100644 --- a/tests/core/oidmap.c +++ b/tests/core/oidmap.c @@ -1,8 +1,6 @@ #include "clar_libgit2.h" #include "oidmap.h" -GIT__USE_OIDMAP - typedef struct { git_oid oid; size_t extra; @@ -33,23 +31,23 @@ void test_core_oidmap__basic(void) khiter_t pos; int ret; - pos = kh_get(oid, map, &items[i].oid); - cl_assert(pos == kh_end(map)); + pos = git_oidmap_lookup_index(map, &items[i].oid); + cl_assert(!git_oidmap_valid_index(map, pos)); - pos = kh_put(oid, map, &items[i].oid, &ret); + pos = git_oidmap_put(map, &items[i].oid, &ret); cl_assert(ret != 0); - kh_val(map, pos) = &items[i]; + git_oidmap_set_value_at(map, pos, &items[i]); } for (i = 0; i < NITEMS; ++i) { khiter_t pos; - pos = kh_get(oid, map, &items[i].oid); - cl_assert(pos != kh_end(map)); + pos = git_oidmap_lookup_index(map, &items[i].oid); + cl_assert(git_oidmap_valid_index(map, pos)); - cl_assert_equal_p(kh_val(map, pos), &items[i]); + cl_assert_equal_p(git_oidmap_value_at(map, pos), &items[i]); } git_oidmap_free(map); @@ -87,23 +85,23 @@ void test_core_oidmap__hash_collision(void) khiter_t pos; int ret; - pos = kh_get(oid, map, &items[i].oid); - cl_assert(pos == kh_end(map)); + pos = git_oidmap_lookup_index(map, &items[i].oid); + cl_assert(!git_oidmap_valid_index(map, pos)); - pos = kh_put(oid, map, &items[i].oid, &ret); + pos = git_oidmap_put(map, &items[i].oid, &ret); cl_assert(ret != 0); - kh_val(map, pos) = &items[i]; + git_oidmap_set_value_at(map, pos, &items[i]); } for (i = 0; i < NITEMS; ++i) { khiter_t pos; - pos = kh_get(oid, map, &items[i].oid); - cl_assert(pos != kh_end(map)); + pos = git_oidmap_lookup_index(map, &items[i].oid); + cl_assert(git_oidmap_valid_index(map, pos)); - cl_assert_equal_p(kh_val(map, pos), &items[i]); + cl_assert_equal_p(git_oidmap_value_at(map, pos), &items[i]); } git_oidmap_free(map); diff --git a/tests/core/strmap.c b/tests/core/strmap.c index 3b4276aea..2fa594d43 100644 --- a/tests/core/strmap.c +++ b/tests/core/strmap.c @@ -1,8 +1,6 @@ #include "clar_libgit2.h" #include "strmap.h" -GIT__USE_STRMAP - git_strmap *g_table; void test_core_strmap__initialize(void) @@ -36,7 +34,7 @@ static void insert_strings(git_strmap *table, int count) for (j = 0, over = i / 26; over > 0; j++, over = over / 26) str[j] = 'A' + (over % 26); - git_strmap_insert(table, str, str, err); + git_strmap_insert(table, str, str, &err); cl_assert(err >= 0); } |