Commit d0c72a92 by Patrick Steinhardt Committed by GitHub

Merge pull request #4092 from pks-t/pks/khash-cleanups

khash cleanups
parents 021f4943 8f1ff26b
......@@ -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;
......
......@@ -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);
}
......
......@@ -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 */
}
......
......@@ -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)
......
......@@ -35,8 +35,6 @@
#include "pool.h"
#include "strmap.h"
GIT__USE_STRMAP
/* See docs/checkout-internals.md for more information */
enum {
......
......@@ -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) {
......
......@@ -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;
}
......
......@@ -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;
......
......@@ -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;
}
......
/*
* 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);
}
......@@ -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
......
......@@ -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)
......
......@@ -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);
}
......
......@@ -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) {
......
......@@ -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);
});
......
/*
* 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);
}
......@@ -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
......
/*
* 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);
}
......@@ -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
......@@ -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;
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -30,7 +30,6 @@
#include "submodule.h"
#include "worktree.h"
GIT__USE_STRMAP
#include "strmap.h"
#ifdef GIT_WIN32
......
......@@ -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;
......
#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)
......
......@@ -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,
......
......@@ -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
......
......@@ -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;
......
......@@ -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);
......
......@@ -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);
......
#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);
......
#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);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment