Unverified Commit 4069f924 by Edward Thomson Committed by GitHub

Merge pull request #4901 from pks-t/pks/uniform-map-api

High-level map APIs
parents 75dd7f2a df42f368
...@@ -439,7 +439,6 @@ static int apply_one( ...@@ -439,7 +439,6 @@ static int apply_one(
git_filemode_t pre_filemode; git_filemode_t pre_filemode;
git_index_entry pre_entry, post_entry; git_index_entry pre_entry, post_entry;
bool skip_preimage = false; bool skip_preimage = false;
size_t pos;
int error; int error;
if ((error = git_patch_from_diff(&patch, diff, i)) < 0) if ((error = git_patch_from_diff(&patch, diff, i)) < 0)
...@@ -464,8 +463,7 @@ static int apply_one( ...@@ -464,8 +463,7 @@ static int apply_one(
*/ */
if (delta->status != GIT_DELTA_RENAMED && if (delta->status != GIT_DELTA_RENAMED &&
delta->status != GIT_DELTA_ADDED) { delta->status != GIT_DELTA_ADDED) {
pos = git_strmap_lookup_index(removed_paths, delta->old_file.path); if (git_strmap_exists(removed_paths, delta->old_file.path)) {
if (git_strmap_valid_index(removed_paths, pos)) {
error = apply_err("path '%s' has been renamed or deleted", delta->old_file.path); error = apply_err("path '%s' has been renamed or deleted", delta->old_file.path);
goto done; goto done;
} }
...@@ -549,7 +547,7 @@ static int apply_one( ...@@ -549,7 +547,7 @@ static int apply_one(
if (delta->status == GIT_DELTA_RENAMED || if (delta->status == GIT_DELTA_RENAMED ||
delta->status == GIT_DELTA_DELETED) delta->status == GIT_DELTA_DELETED)
git_strmap_insert(removed_paths, delta->old_file.path, (char *)delta->old_file.path, &error); error = git_strmap_set(removed_paths, delta->old_file.path, (char *) delta->old_file.path);
if (delta->status == GIT_DELTA_RENAMED || if (delta->status == GIT_DELTA_RENAMED ||
delta->status == GIT_DELTA_ADDED) delta->status == GIT_DELTA_ADDED)
...@@ -577,7 +575,7 @@ static int apply_deltas( ...@@ -577,7 +575,7 @@ static int apply_deltas(
size_t i; size_t i;
int error = 0; int error = 0;
if (git_strmap_alloc(&removed_paths) < 0) if (git_strmap_new(&removed_paths) < 0)
return -1; return -1;
for (i = 0; i < git_diff_num_deltas(diff); i++) { for (i = 0; i < git_diff_num_deltas(diff); i++) {
......
...@@ -215,7 +215,7 @@ int git_attr_foreach( ...@@ -215,7 +215,7 @@ int git_attr_foreach(
return -1; return -1;
if ((error = collect_attr_files(repo, NULL, flags, pathname, &files)) < 0 || if ((error = collect_attr_files(repo, NULL, flags, pathname, &files)) < 0 ||
(error = git_strmap_alloc(&seen)) < 0) (error = git_strmap_new(&seen)) < 0)
goto cleanup; goto cleanup;
git_vector_foreach(&files, i, file) { git_vector_foreach(&files, i, file) {
...@@ -227,8 +227,7 @@ int git_attr_foreach( ...@@ -227,8 +227,7 @@ int git_attr_foreach(
if (git_strmap_exists(seen, assign->name)) if (git_strmap_exists(seen, assign->name))
continue; continue;
git_strmap_insert(seen, assign->name, assign, &error); if ((error = git_strmap_set(seen, assign->name, assign)) < 0)
if (error < 0)
goto cleanup; goto cleanup;
error = callback(assign->name, assign->value, payload); error = callback(assign->name, assign->value, payload);
......
...@@ -33,12 +33,7 @@ GIT_INLINE(void) attr_cache_unlock(git_attr_cache *cache) ...@@ -33,12 +33,7 @@ GIT_INLINE(void) attr_cache_unlock(git_attr_cache *cache)
GIT_INLINE(git_attr_file_entry *) attr_cache_lookup_entry( GIT_INLINE(git_attr_file_entry *) attr_cache_lookup_entry(
git_attr_cache *cache, const char *path) git_attr_cache *cache, const char *path)
{ {
size_t pos = git_strmap_lookup_index(cache->files, path); return git_strmap_get(cache->files, path);
if (git_strmap_valid_index(cache->files, pos))
return git_strmap_value_at(cache->files, pos);
else
return NULL;
} }
int git_attr_cache__alloc_file_entry( int git_attr_cache__alloc_file_entry(
...@@ -80,18 +75,16 @@ int git_attr_cache__alloc_file_entry( ...@@ -80,18 +75,16 @@ int git_attr_cache__alloc_file_entry(
static int attr_cache_make_entry( static int attr_cache_make_entry(
git_attr_file_entry **out, git_repository *repo, const char *path) git_attr_file_entry **out, git_repository *repo, const char *path)
{ {
int error = 0;
git_attr_cache *cache = git_repository_attr_cache(repo); git_attr_cache *cache = git_repository_attr_cache(repo);
git_attr_file_entry *entry = NULL; git_attr_file_entry *entry = NULL;
int error;
error = git_attr_cache__alloc_file_entry( if ((error = git_attr_cache__alloc_file_entry(&entry, git_repository_workdir(repo),
&entry, git_repository_workdir(repo), path, &cache->pool); path, &cache->pool)) < 0)
return error;
if (!error) { if ((error = git_strmap_set(cache->files, entry->path, entry)) < 0)
git_strmap_insert(cache->files, entry->path, entry, &error); return error;
if (error > 0)
error = 0;
}
*out = entry; *out = entry;
return error; return error;
...@@ -265,19 +258,15 @@ bool git_attr_cache__is_cached( ...@@ -265,19 +258,15 @@ bool git_attr_cache__is_cached(
const char *filename) const char *filename)
{ {
git_attr_cache *cache = git_repository_attr_cache(repo); git_attr_cache *cache = git_repository_attr_cache(repo);
git_strmap *files;
size_t pos;
git_attr_file_entry *entry; git_attr_file_entry *entry;
git_strmap *files;
if (!cache || !(files = cache->files)) if (!cache || !(files = cache->files))
return false; return false;
pos = git_strmap_lookup_index(files, filename); if ((entry = git_strmap_get(files, filename)) == NULL)
if (!git_strmap_valid_index(files, pos))
return false; return false;
entry = git_strmap_value_at(files, pos);
return entry && (entry->file[source] != NULL); return entry && (entry->file[source] != NULL);
} }
...@@ -400,8 +389,8 @@ int git_attr_cache__init(git_repository *repo) ...@@ -400,8 +389,8 @@ int git_attr_cache__init(git_repository *repo)
/* allocate hashtable for attribute and ignore file contents, /* allocate hashtable for attribute and ignore file contents,
* hashtable for attribute macros, and string pool * hashtable for attribute macros, and string pool
*/ */
if ((ret = git_strmap_alloc(&cache->files)) < 0 || if ((ret = git_strmap_new(&cache->files)) < 0 ||
(ret = git_strmap_alloc(&cache->macros)) < 0) (ret = git_strmap_new(&cache->macros)) < 0)
goto cancel; goto cancel;
git_pool_init(&cache->pool, 1); git_pool_init(&cache->pool, 1);
...@@ -446,24 +435,17 @@ int git_attr_cache__insert_macro(git_repository *repo, git_attr_rule *macro) ...@@ -446,24 +435,17 @@ int git_attr_cache__insert_macro(git_repository *repo, git_attr_rule *macro)
git_error_set(GIT_ERROR_OS, "unable to get attr cache lock"); git_error_set(GIT_ERROR_OS, "unable to get attr cache lock");
error = -1; error = -1;
} else { } else {
git_strmap_insert(macros, macro->match.pattern, macro, &error); error = git_strmap_set(macros, macro->match.pattern, macro);
git_mutex_unlock(&cache->lock); git_mutex_unlock(&cache->lock);
} }
return (error < 0) ? -1 : 0; return error;
} }
git_attr_rule *git_attr_cache__lookup_macro( git_attr_rule *git_attr_cache__lookup_macro(
git_repository *repo, const char *name) git_repository *repo, const char *name)
{ {
git_strmap *macros = git_repository_attr_cache(repo)->macros; git_strmap *macros = git_repository_attr_cache(repo)->macros;
size_t pos;
pos = git_strmap_lookup_index(macros, name); return git_strmap_get(macros, name);
if (!git_strmap_valid_index(macros, pos))
return NULL;
return (git_attr_rule *)git_strmap_value_at(macros, pos);
} }
...@@ -65,12 +65,15 @@ void git_cache_dump_stats(git_cache *cache) ...@@ -65,12 +65,15 @@ void git_cache_dump_stats(git_cache *cache)
int git_cache_init(git_cache *cache) int git_cache_init(git_cache *cache)
{ {
memset(cache, 0, sizeof(*cache)); memset(cache, 0, sizeof(*cache));
cache->map = git_oidmap_alloc();
GIT_ERROR_CHECK_ALLOC(cache->map); if ((git_oidmap_new(&cache->map)) < 0)
return -1;
if (git_rwlock_init(&cache->lock)) { if (git_rwlock_init(&cache->lock)) {
git_error_set(GIT_ERROR_OS, "failed to initialize cache rwlock"); git_error_set(GIT_ERROR_OS, "failed to initialize cache rwlock");
return -1; return -1;
} }
return 0; return 0;
} }
...@@ -112,8 +115,7 @@ void git_cache_dispose(git_cache *cache) ...@@ -112,8 +115,7 @@ void git_cache_dispose(git_cache *cache)
/* Called with lock */ /* Called with lock */
static void cache_evict_entries(git_cache *cache) static void cache_evict_entries(git_cache *cache)
{ {
uint32_t seed = rand(); size_t evict_count = 8, i;
size_t evict_count = 8;
ssize_t evicted_memory = 0; ssize_t evicted_memory = 0;
/* do not infinite loop if there's not enough entries to evict */ /* do not infinite loop if there's not enough entries to evict */
...@@ -122,18 +124,19 @@ static void cache_evict_entries(git_cache *cache) ...@@ -122,18 +124,19 @@ static void cache_evict_entries(git_cache *cache)
return; return;
} }
i = 0;
while (evict_count > 0) { while (evict_count > 0) {
size_t pos = seed++ % git_oidmap_end(cache->map); git_cached_obj *evict;
const git_oid *key;
if (git_oidmap_has_data(cache->map, pos)) { if (git_oidmap_iterate((void **) &evict, cache->map, &i, &key) == GIT_ITEROVER)
git_cached_obj *evict = git_oidmap_value_at(cache->map, pos); break;
evict_count--; evict_count--;
evicted_memory += evict->size; evicted_memory += evict->size;
git_cached_obj_decref(evict); git_cached_obj_decref(evict);
git_oidmap_delete_at(cache->map, pos); git_oidmap_delete(cache->map, key);
}
} }
cache->used_memory -= evicted_memory; cache->used_memory -= evicted_memory;
...@@ -148,16 +151,12 @@ static bool cache_should_store(git_object_t object_type, size_t object_size) ...@@ -148,16 +151,12 @@ static bool cache_should_store(git_object_t object_type, size_t object_size)
static void *cache_get(git_cache *cache, const git_oid *oid, unsigned int flags) static void *cache_get(git_cache *cache, const git_oid *oid, unsigned int flags)
{ {
size_t pos; git_cached_obj *entry;
git_cached_obj *entry = NULL;
if (!git_cache__enabled || git_rwlock_rdlock(&cache->lock) < 0) if (!git_cache__enabled || git_rwlock_rdlock(&cache->lock) < 0)
return NULL; return NULL;
pos = git_oidmap_lookup_index(cache->map, oid); if ((entry = git_oidmap_get(cache->map, oid)) != NULL) {
if (git_oidmap_valid_index(cache->map, pos)) {
entry = git_oidmap_value_at(cache->map, pos);
if (flags && entry->flags != flags) { if (flags && entry->flags != flags) {
entry = NULL; entry = NULL;
} else { } else {
...@@ -172,7 +171,7 @@ static void *cache_get(git_cache *cache, const git_oid *oid, unsigned int flags) ...@@ -172,7 +171,7 @@ static void *cache_get(git_cache *cache, const git_oid *oid, unsigned int flags)
static void *cache_store(git_cache *cache, git_cached_obj *entry) static void *cache_store(git_cache *cache, git_cached_obj *entry)
{ {
size_t pos; git_cached_obj *stored_entry;
git_cached_obj_incref(entry); git_cached_obj_incref(entry);
...@@ -191,14 +190,9 @@ static void *cache_store(git_cache *cache, git_cached_obj *entry) ...@@ -191,14 +190,9 @@ static void *cache_store(git_cache *cache, git_cached_obj *entry)
if (git_cache__current_storage.val > git_cache__max_storage) if (git_cache__current_storage.val > git_cache__max_storage)
cache_evict_entries(cache); cache_evict_entries(cache);
pos = git_oidmap_lookup_index(cache->map, &entry->oid);
/* not found */ /* not found */
if (!git_oidmap_valid_index(cache->map, pos)) { if ((stored_entry = git_oidmap_get(cache->map, &entry->oid)) == NULL) {
int rval; if (git_oidmap_set(cache->map, &entry->oid, entry) == 0) {
git_oidmap_insert(cache->map, &entry->oid, entry, &rval);
if (rval >= 0) {
git_cached_obj_incref(entry); git_cached_obj_incref(entry);
cache->used_memory += entry->size; cache->used_memory += entry->size;
git_atomic_ssize_add(&git_cache__current_storage, (ssize_t)entry->size); git_atomic_ssize_add(&git_cache__current_storage, (ssize_t)entry->size);
...@@ -206,19 +200,16 @@ static void *cache_store(git_cache *cache, git_cached_obj *entry) ...@@ -206,19 +200,16 @@ static void *cache_store(git_cache *cache, git_cached_obj *entry)
} }
/* found */ /* found */
else { else {
git_cached_obj *stored_entry = git_oidmap_value_at(cache->map, pos);
if (stored_entry->flags == entry->flags) { if (stored_entry->flags == entry->flags) {
git_cached_obj_decref(entry); git_cached_obj_decref(entry);
git_cached_obj_incref(stored_entry); git_cached_obj_incref(stored_entry);
entry = stored_entry; entry = stored_entry;
} else if (stored_entry->flags == GIT_CACHE_STORE_RAW && } else if (stored_entry->flags == GIT_CACHE_STORE_RAW &&
entry->flags == GIT_CACHE_STORE_PARSED) { entry->flags == GIT_CACHE_STORE_PARSED) {
git_cached_obj_decref(stored_entry); git_cached_obj_decref(stored_entry);
git_cached_obj_incref(entry); git_cached_obj_incref(entry);
git_oidmap_set_key_at(cache->map, pos, &entry->oid); git_oidmap_set(cache->map, &entry->oid, entry);
git_oidmap_set_value_at(cache->map, pos, entry);
} else { } else {
/* NO OP */ /* NO OP */
} }
......
...@@ -2518,11 +2518,11 @@ static int checkout_data_init( ...@@ -2518,11 +2518,11 @@ static int checkout_data_init(
git_pool_init(&data->pool, 1); git_pool_init(&data->pool, 1);
if ((error = git_vector_init(&data->removes, 0, git__strcmp_cb)) < 0 || if ((error = git_vector_init(&data->removes, 0, git__strcmp_cb)) < 0 ||
(error = git_vector_init(&data->remove_conflicts, 0, NULL)) < 0 || (error = git_vector_init(&data->remove_conflicts, 0, NULL)) < 0 ||
(error = git_vector_init(&data->update_conflicts, 0, NULL)) < 0 || (error = git_vector_init(&data->update_conflicts, 0, NULL)) < 0 ||
(error = git_buf_puts(&data->target_path, data->opts.target_directory)) < 0 || (error = git_buf_puts(&data->target_path, data->opts.target_directory)) < 0 ||
(error = git_path_to_dir(&data->target_path)) < 0 || (error = git_path_to_dir(&data->target_path)) < 0 ||
(error = git_strmap_alloc(&data->mkdir_map)) < 0) (error = git_strmap_new(&data->mkdir_map)) < 0)
goto cleanup; goto cleanup;
data->target_len = git_buf_len(&data->target_path); data->target_len = git_buf_len(&data->target_path);
......
...@@ -59,7 +59,7 @@ int git_config_entries_new(git_config_entries **out) ...@@ -59,7 +59,7 @@ int git_config_entries_new(git_config_entries **out)
GIT_ERROR_CHECK_ALLOC(entries); GIT_ERROR_CHECK_ALLOC(entries);
GIT_REFCOUNT_INC(entries); GIT_REFCOUNT_INC(entries);
if ((error = git_strmap_alloc(&entries->map)) < 0) if ((error = git_strmap_new(&entries->map)) < 0)
git__free(entries); git__free(entries);
else else
*out = entries; *out = entries;
...@@ -133,14 +133,12 @@ int git_config_entries_append(git_config_entries *entries, git_config_entry *ent ...@@ -133,14 +133,12 @@ int git_config_entries_append(git_config_entries *entries, git_config_entry *ent
{ {
config_entry_list *existing, *var; config_entry_list *existing, *var;
int error = 0; int error = 0;
size_t pos;
var = git__calloc(1, sizeof(config_entry_list)); var = git__calloc(1, sizeof(config_entry_list));
GIT_ERROR_CHECK_ALLOC(var); GIT_ERROR_CHECK_ALLOC(var);
var->entry = entry; var->entry = entry;
pos = git_strmap_lookup_index(entries->map, entry->name); if ((existing = git_strmap_get(entries->map, entry->name)) == NULL) {
if (!git_strmap_valid_index(entries->map, pos)) {
/* /*
* We only ever inspect `last` from the first config * We only ever inspect `last` from the first config
* entry in a multivar. In case where this new entry is * entry in a multivar. In case where this new entry is
...@@ -152,12 +150,8 @@ int git_config_entries_append(git_config_entries *entries, git_config_entry *ent ...@@ -152,12 +150,8 @@ int git_config_entries_append(git_config_entries *entries, git_config_entry *ent
*/ */
var->last = var; var->last = var;
git_strmap_insert(entries->map, entry->name, var, &error); error = git_strmap_set(entries->map, entry->name, var);
if (error > 0)
error = 0;
} else { } else {
existing = git_strmap_value_at(entries->map, pos);
config_entry_list_append(&existing, var); config_entry_list_append(&existing, var);
} }
...@@ -171,15 +165,12 @@ int git_config_entries_append(git_config_entries *entries, git_config_entry *ent ...@@ -171,15 +165,12 @@ int git_config_entries_append(git_config_entries *entries, git_config_entry *ent
int config_entry_get(config_entry_list **out, git_config_entries *entries, const char *key) int config_entry_get(config_entry_list **out, git_config_entries *entries, const char *key)
{ {
size_t pos; config_entry_list *list;
pos = git_strmap_lookup_index(entries->map, key);
/* no error message; the config system will write one */ if ((list = git_strmap_get(entries->map, key)) == NULL)
if (!git_strmap_valid_index(entries->map, pos))
return GIT_ENOTFOUND; return GIT_ENOTFOUND;
*out = git_strmap_value_at(entries->map, pos); *out = list;
return 0; return 0;
} }
......
...@@ -36,12 +36,7 @@ struct commit_name { ...@@ -36,12 +36,7 @@ struct commit_name {
static void *oidmap_value_bykey(git_oidmap *map, const git_oid *key) static void *oidmap_value_bykey(git_oidmap *map, const git_oid *key)
{ {
size_t pos = git_oidmap_lookup_index(map, key); return git_oidmap_get(map, key);
if (!git_oidmap_valid_index(map, pos))
return NULL;
return git_oidmap_value_at(map, pos);
} }
static struct commit_name *find_commit_name( static struct commit_name *find_commit_name(
...@@ -124,13 +119,8 @@ static int add_to_known_names( ...@@ -124,13 +119,8 @@ static int add_to_known_names(
e->path = git__strdup(path); e->path = git__strdup(path);
git_oid_cpy(&e->peeled, peeled); git_oid_cpy(&e->peeled, peeled);
if (!found) { if (!found && git_oidmap_set(names, &e->peeled, e) < 0)
int ret; return -1;
git_oidmap_insert(names, &e->peeled, e, &ret);
if (ret < 0)
return -1;
}
} }
else else
git_tag_free(tag); git_tag_free(tag);
...@@ -681,8 +671,8 @@ int git_describe_commit( ...@@ -681,8 +671,8 @@ int git_describe_commit(
"git_describe_options"); "git_describe_options");
data.opts = &normalized; data.opts = &normalized;
data.names = git_oidmap_alloc(); if ((error = git_oidmap_new(&data.names)) < 0)
GIT_ERROR_CHECK_ALLOC(data.names); return error;
/** TODO: contains to be implemented */ /** TODO: contains to be implemented */
......
...@@ -63,7 +63,7 @@ git_diff_driver_registry *git_diff_driver_registry_new(void) ...@@ -63,7 +63,7 @@ git_diff_driver_registry *git_diff_driver_registry_new(void)
if (!reg) if (!reg)
return NULL; return NULL;
if (git_strmap_alloc(&reg->drivers) < 0) { if (git_strmap_new(&reg->drivers) < 0) {
git_diff_driver_registry_free(reg); git_diff_driver_registry_free(reg);
return NULL; return NULL;
} }
...@@ -183,9 +183,9 @@ static int git_diff_driver_builtin( ...@@ -183,9 +183,9 @@ static int git_diff_driver_builtin(
git_diff_driver_registry *reg, git_diff_driver_registry *reg,
const char *driver_name) const char *driver_name)
{ {
int error = 0;
git_diff_driver_definition *ddef = NULL; git_diff_driver_definition *ddef = NULL;
git_diff_driver *drv = NULL; git_diff_driver *drv = NULL;
int error = 0;
size_t idx; size_t idx;
for (idx = 0; idx < ARRAY_SIZE(builtin_defs); ++idx) { for (idx = 0; idx < ARRAY_SIZE(builtin_defs); ++idx) {
...@@ -215,9 +215,8 @@ static int git_diff_driver_builtin( ...@@ -215,9 +215,8 @@ static int git_diff_driver_builtin(
goto done; goto done;
} }
git_strmap_insert(reg->drivers, drv->name, drv, &error); if ((error = git_strmap_set(reg->drivers, drv->name, drv)) < 0)
if (error > 0) goto done;
error = 0;
done: done:
if (error && drv) if (error && drv)
...@@ -233,8 +232,8 @@ static int git_diff_driver_load( ...@@ -233,8 +232,8 @@ static int git_diff_driver_load(
{ {
int error = 0; int error = 0;
git_diff_driver_registry *reg; git_diff_driver_registry *reg;
git_diff_driver *drv = NULL; git_diff_driver *drv;
size_t namelen, pos; size_t namelen;
git_config *cfg = NULL; git_config *cfg = NULL;
git_buf name = GIT_BUF_INIT; git_buf name = GIT_BUF_INIT;
git_config_entry *ce = NULL; git_config_entry *ce = NULL;
...@@ -243,9 +242,8 @@ static int git_diff_driver_load( ...@@ -243,9 +242,8 @@ static int git_diff_driver_load(
if ((reg = git_repository_driver_registry(repo)) == NULL) if ((reg = git_repository_driver_registry(repo)) == NULL)
return -1; return -1;
pos = git_strmap_lookup_index(reg->drivers, driver_name); if ((drv = git_strmap_get(reg->drivers, driver_name)) != NULL) {
if (git_strmap_valid_index(reg->drivers, pos)) { *out = drv;
*out = git_strmap_value_at(reg->drivers, pos);
return 0; return 0;
} }
...@@ -328,10 +326,8 @@ static int git_diff_driver_load( ...@@ -328,10 +326,8 @@ static int git_diff_driver_load(
goto done; goto done;
/* store driver in registry */ /* store driver in registry */
git_strmap_insert(reg->drivers, drv->name, drv, &error); if ((error = git_strmap_set(reg->drivers, drv->name, drv)) < 0)
if (error < 0)
goto done; goto done;
error = 0;
*out = drv; *out = drv;
......
...@@ -640,8 +640,7 @@ retry_lstat: ...@@ -640,8 +640,7 @@ retry_lstat:
memcpy(cache_path, make_path.ptr, make_path.size + 1); memcpy(cache_path, make_path.ptr, make_path.size + 1);
git_strmap_insert(opts->dir_map, cache_path, cache_path, &error); if ((error = git_strmap_set(opts->dir_map, cache_path, cache_path)) < 0)
if (error < 0)
goto done; goto done;
} }
} }
......
...@@ -32,122 +32,146 @@ static kh_inline khint_t idxentry_hash(const git_index_entry *e) ...@@ -32,122 +32,146 @@ static kh_inline khint_t idxentry_hash(const git_index_entry *e)
__KHASH_IMPL(idx, static kh_inline, const git_index_entry *, git_index_entry *, 1, idxentry_hash, idxentry_equal) __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) __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) int git_idxmap_new(git_idxmap **out)
{ {
if ((*map = kh_init(idx)) == NULL) { *out = kh_init(idx);
git_error_set_oom(); GIT_ERROR_CHECK_ALLOC(*out);
return -1;
}
return 0; return 0;
} }
int git_idxmap_icase_alloc(git_idxmap_icase **map) int git_idxmap_icase_new(git_idxmap_icase **out)
{ {
if ((*map = kh_init(idxicase)) == NULL) { *out = kh_init(idxicase);
git_error_set_oom(); GIT_ERROR_CHECK_ALLOC(*out);
return -1;
}
return 0; return 0;
} }
void git_idxmap_insert(git_idxmap *map, const git_index_entry *key, void *value, int *rval) void git_idxmap_free(git_idxmap *map)
{ {
khiter_t idx = kh_put(idx, map, key, rval); kh_destroy(idx, map);
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) void git_idxmap_icase_free(git_idxmap_icase *map)
{ {
khiter_t idx = kh_put(idxicase, map, key, rval); kh_destroy(idxicase, map);
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) void git_idxmap_clear(git_idxmap *map)
{ {
return kh_get(idx, map, key); kh_clear(idx, map);
} }
size_t git_idxmap_icase_lookup_index(git_idxmap_icase *map, const git_index_entry *key) void git_idxmap_icase_clear(git_idxmap_icase *map)
{ {
return kh_get(idxicase, map, key); kh_clear(idxicase, map);
} }
void *git_idxmap_value_at(git_idxmap *map, size_t idx) int git_idxmap_resize(git_idxmap *map, size_t size)
{ {
return kh_val(map, idx); if (kh_resize(idx, map, size) < 0) {
git_error_set_oom();
return -1;
}
return 0;
} }
int git_idxmap_valid_index(git_idxmap *map, size_t idx) int git_idxmap_icase_resize(git_idxmap_icase *map, size_t size)
{ {
return idx != kh_end(map); if (kh_resize(idxicase, map, size) < 0) {
git_error_set_oom();
return -1;
}
return 0;
} }
int git_idxmap_has_data(git_idxmap *map, size_t idx) void *git_idxmap_get(git_idxmap *map, const git_index_entry *key)
{ {
return kh_exist(map, idx); size_t idx = kh_get(idx, map, key);
if (idx == kh_end(map) || !kh_exist(map, idx))
return NULL;
return kh_val(map, idx);
} }
void git_idxmap_resize(git_idxmap *map, size_t size) int git_idxmap_set(git_idxmap *map, const git_index_entry *key, void *value)
{ {
kh_resize(idx, map, size); size_t idx;
} int rval;
void git_idxmap_icase_resize(git_idxmap_icase *map, size_t size) idx = kh_put(idx, map, key, &rval);
{ if (rval < 0)
kh_resize(idxicase, map, size); return -1;
if (rval == 0)
kh_key(map, idx) = key;
kh_val(map, idx) = value;
return 0;
} }
void git_idxmap_free(git_idxmap *map) int git_idxmap_icase_set(git_idxmap_icase *map, const git_index_entry *key, void *value)
{ {
kh_destroy(idx, map); size_t idx;
int rval;
idx = kh_put(idxicase, map, key, &rval);
if (rval < 0)
return -1;
if (rval == 0)
kh_key(map, idx) = key;
kh_val(map, idx) = value;
return 0;
} }
void git_idxmap_icase_free(git_idxmap_icase *map) void *git_idxmap_icase_get(git_idxmap_icase *map, const git_index_entry *key)
{ {
kh_destroy(idxicase, map); size_t idx = kh_get(idxicase, map, key);
if (idx == kh_end(map) || !kh_exist(map, idx))
return NULL;
return kh_val(map, idx);
} }
void git_idxmap_clear(git_idxmap *map) void git_idxmap_insert(git_idxmap *map, const git_index_entry *key, void *value, int *rval)
{ {
kh_clear(idx, map); 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_clear(git_idxmap_icase *map) void git_idxmap_icase_insert(git_idxmap_icase *map, const git_index_entry *key, void *value, int *rval)
{ {
kh_clear(idxicase, map); 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;
}
} }
void git_idxmap_delete_at(git_idxmap *map, size_t idx) int git_idxmap_delete(git_idxmap *map, const git_index_entry *key)
{ {
khiter_t idx = kh_get(idx, map, key);
if (idx == kh_end(map))
return GIT_ENOTFOUND;
kh_del(idx, map, idx); kh_del(idx, map, idx);
return 0;
} }
void git_idxmap_icase_delete_at(git_idxmap_icase *map, size_t idx) int git_idxmap_icase_delete(git_idxmap_icase *map, const git_index_entry *key)
{ {
khiter_t idx = kh_get(idxicase, map, key);
if (idx == kh_end(map))
return GIT_ENOTFOUND;
kh_del(idxicase, map, idx); kh_del(idxicase, map, idx);
} return 0;
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);
} }
...@@ -11,31 +11,167 @@ ...@@ -11,31 +11,167 @@
#include "git2/index.h" #include "git2/index.h"
/** A map with `git_index_entry`s as key. */
typedef struct kh_idx_s git_idxmap; typedef struct kh_idx_s git_idxmap;
/** A map with case-insensitive `git_index_entry`s as key */
typedef struct kh_idxicase_s git_idxmap_icase; typedef struct kh_idxicase_s git_idxmap_icase;
int git_idxmap_alloc(git_idxmap **map); /**
int git_idxmap_icase_alloc(git_idxmap_icase **map); * Allocate a new index entry 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); * @param out Pointer to the map that shall be allocated.
* @return 0 on success, an error code if allocation has failed.
*/
int git_idxmap_new(git_idxmap **out);
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); * Allocate a new case-insensitive index entry map.
void *git_idxmap_value_at(git_idxmap *map, size_t idx); *
int git_idxmap_valid_index(git_idxmap *map, size_t idx); * @param out Pointer to the map that shall be allocated.
int git_idxmap_has_data(git_idxmap *map, size_t idx); * @return 0 on success, an error code if allocation has failed.
*/
int git_idxmap_icase_new(git_idxmap_icase **out);
void git_idxmap_resize(git_idxmap *map, size_t size); /**
void git_idxmap_icase_resize(git_idxmap_icase *map, size_t size); * Free memory associated with the map.
*
* Note that this function will _not_ free values added to this
* map.
*
* @param map Pointer to the map that is to be free'd. May be
* `NULL`.
*/
void git_idxmap_free(git_idxmap *map); void git_idxmap_free(git_idxmap *map);
/**
* Free memory associated with the map.
*
* Note that this function will _not_ free values added to this
* map.
*
* @param map Pointer to the map that is to be free'd. May be
* `NULL`.
*/
void git_idxmap_icase_free(git_idxmap_icase *map); void git_idxmap_icase_free(git_idxmap_icase *map);
/**
* Clear all entries from the map.
*
* This function will remove all entries from the associated map.
* Memory associated with it will not be released, though.
*
* @param map Pointer to the map that shall be cleared. May be
* `NULL`.
*/
void git_idxmap_clear(git_idxmap *map); void git_idxmap_clear(git_idxmap *map);
/**
* Clear all entries from the map.
*
* This function will remove all entries from the associated map.
* Memory associated with it will not be released, though.
*
* @param map Pointer to the map that shall be cleared. May be
* `NULL`.
*/
void git_idxmap_icase_clear(git_idxmap_icase *map); void git_idxmap_icase_clear(git_idxmap_icase *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); * Resize the map by allocating more memory.
*
* @param map map that shall be resized
* @param size count of entries that the map shall hold
* @return `0` if the map was successfully resized, a negative
* error code otherwise
*/
int git_idxmap_resize(git_idxmap *map, size_t size);
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); * Resize the map by allocating more memory.
*
* @param map map that shall be resized
* @param size count of entries that the map shall hold
* @return `0` if the map was successfully resized, a negative
* error code otherwise
*/
int git_idxmap_icase_resize(git_idxmap_icase *map, size_t size);
/**
* Return value associated with the given key.
*
* @param map map to search key in
* @param key key to search for; the index entry will be searched
* for by its case-sensitive path
* @return value associated with the given key or NULL if the key was not found
*/
void *git_idxmap_get(git_idxmap *map, const git_index_entry *key);
/**
* Return value associated with the given key.
*
* @param map map to search key in
* @param key key to search for; the index entry will be searched
* for by its case-insensitive path
* @return value associated with the given key or NULL if the key was not found
*/
void *git_idxmap_icase_get(git_idxmap_icase *map, const git_index_entry *key);
/**
* Set the entry for key to value.
*
* If the map has no corresponding entry for the given key, a new
* entry will be created with the given value. If an entry exists
* already, its value will be updated to match the given value.
*
* @param map map to create new entry in
* @param key key to set
* @param value value to associate the key with; may be NULL
* @return zero if the key was successfully set, a negative error
* code otherwise
*/
int git_idxmap_set(git_idxmap *map, const git_index_entry *key, void *value);
/**
* Set the entry for key to value.
*
* If the map has no corresponding entry for the given key, a new
* entry will be created with the given value. If an entry exists
* already, its value will be updated to match the given value.
*
* @param map map to create new entry in
* @param key key to set
* @param value value to associate the key with; may be NULL
* @return zero if the key was successfully set, a negative error
* code otherwise
*/
int git_idxmap_icase_set(git_idxmap_icase *map, const git_index_entry *key, void *value);
/**
* Delete an entry from the map.
*
* Delete the given key and its value from the map. If no such
* key exists, this will do nothing.
*
* @param map map to delete key in
* @param key key to delete
* @return `0` if the key has been deleted, GIT_ENOTFOUND if no
* such key was found, a negative code in case of an
* error
*/
int git_idxmap_delete(git_idxmap *map, const git_index_entry *key);
/**
* Delete an entry from the map.
*
* Delete the given key and its value from the map. If no such
* key exists, this will do nothing.
*
* @param map map to delete key in
* @param key key to delete
* @return `0` if the key has been deleted, GIT_ENOTFOUND if no
* such key was found, a negative code in case of an
* error
*/
int git_idxmap_icase_delete(git_idxmap_icase *map, const git_index_entry *key);
#endif #endif
...@@ -29,18 +29,18 @@ ...@@ -29,18 +29,18 @@
#define INSERT_IN_MAP_EX(idx, map, e, err) do { \ #define INSERT_IN_MAP_EX(idx, map, e, err) do { \
if ((idx)->ignore_case) \ if ((idx)->ignore_case) \
git_idxmap_icase_insert((git_idxmap_icase *) (map), (e), (e), (err)); \ (err) = git_idxmap_icase_set((git_idxmap_icase *) (map), (e), (e)); \
else \ else \
git_idxmap_insert((map), (e), (e), (err)); \ (err) = git_idxmap_set((map), (e), (e)); \
} while (0) } while (0)
#define INSERT_IN_MAP(idx, e, err) INSERT_IN_MAP_EX(idx, (idx)->entries_map, e, err) #define INSERT_IN_MAP(idx, e, err) INSERT_IN_MAP_EX(idx, (idx)->entries_map, e, err)
#define LOOKUP_IN_MAP(p, idx, k) do { \ #define LOOKUP_IN_MAP(v, idx, k) do { \
if ((idx)->ignore_case) \ if ((idx)->ignore_case) \
(p) = git_idxmap_icase_lookup_index((git_idxmap_icase *) index->entries_map, (k)); \ (v) = git_idxmap_icase_get((git_idxmap_icase *) index->entries_map, (k)); \
else \ else \
(p) = git_idxmap_lookup_index(index->entries_map, (k)); \ (v) = git_idxmap_get(index->entries_map, (k)); \
} while (0) } while (0)
#define DELETE_IN_MAP(idx, e) do { \ #define DELETE_IN_MAP(idx, e) do { \
...@@ -423,10 +423,10 @@ int git_index_open(git_index **index_out, const char *index_path) ...@@ -423,10 +423,10 @@ int git_index_open(git_index **index_out, const char *index_path)
} }
if (git_vector_init(&index->entries, 32, git_index_entry_cmp) < 0 || if (git_vector_init(&index->entries, 32, git_index_entry_cmp) < 0 ||
git_idxmap_alloc(&index->entries_map) < 0 || git_idxmap_new(&index->entries_map) < 0 ||
git_vector_init(&index->names, 8, conflict_name_cmp) < 0 || git_vector_init(&index->names, 8, conflict_name_cmp) < 0 ||
git_vector_init(&index->reuc, 8, reuc_cmp) < 0 || git_vector_init(&index->reuc, 8, reuc_cmp) < 0 ||
git_vector_init(&index->deleted, 8, git_index_entry_cmp) < 0) git_vector_init(&index->deleted, 8, git_index_entry_cmp) < 0)
goto fail; goto fail;
index->entries_cmp_path = git__strcmp_cb; index->entries_cmp_path = git__strcmp_cb;
...@@ -852,20 +852,21 @@ const git_index_entry *git_index_get_bypath( ...@@ -852,20 +852,21 @@ const git_index_entry *git_index_get_bypath(
git_index *index, const char *path, int stage) git_index *index, const char *path, int stage)
{ {
git_index_entry key = {{ 0 }}; git_index_entry key = {{ 0 }};
size_t pos; git_index_entry *value;
assert(index); assert(index);
key.path = path; key.path = path;
GIT_INDEX_ENTRY_STAGE_SET(&key, stage); GIT_INDEX_ENTRY_STAGE_SET(&key, stage);
LOOKUP_IN_MAP(pos, index, &key); LOOKUP_IN_MAP(value, index, &key);
if (git_idxmap_valid_index(index->entries_map, pos)) if (!value) {
return git_idxmap_value_at(index->entries_map, pos); git_error_set(GIT_ERROR_INDEX, "index does not contain '%s'", path);
return NULL;
}
git_error_set(GIT_ERROR_INDEX, "index does not contain '%s'", path); return value;
return NULL;
} }
void git_index_entry__init_from_stat( void git_index_entry__init_from_stat(
...@@ -1401,7 +1402,7 @@ static int index_insert( ...@@ -1401,7 +1402,7 @@ static int index_insert(
if ((error = git_vector_insert_sorted(&index->entries, entry, index_no_dups)) < 0) if ((error = git_vector_insert_sorted(&index->entries, entry, index_no_dups)) < 0)
goto out; goto out;
INSERT_IN_MAP(index, entry, &error); INSERT_IN_MAP(index, entry, error);
} }
index->dirty = 1; index->dirty = 1;
...@@ -1618,8 +1619,9 @@ int git_index__fill(git_index *index, const git_vector *source_entries) ...@@ -1618,8 +1619,9 @@ int git_index__fill(git_index *index, const git_vector *source_entries)
if (!source_entries->length) if (!source_entries->length)
return 0; return 0;
git_vector_size_hint(&index->entries, source_entries->length); if (git_vector_size_hint(&index->entries, source_entries->length) < 0 ||
git_idxmap_resize(index->entries_map, (size_t)(source_entries->length * 1.3)); git_idxmap_resize(index->entries_map, (size_t)(source_entries->length * 1.3)) < 0)
return -1;
git_vector_foreach(source_entries, i, source_entry) { git_vector_foreach(source_entries, i, source_entry) {
git_index_entry *entry = NULL; git_index_entry *entry = NULL;
...@@ -1634,7 +1636,7 @@ int git_index__fill(git_index *index, const git_vector *source_entries) ...@@ -1634,7 +1636,7 @@ int git_index__fill(git_index *index, const git_vector *source_entries)
if ((ret = git_vector_insert(&index->entries, entry)) < 0) if ((ret = git_vector_insert(&index->entries, entry)) < 0)
break; break;
INSERT_IN_MAP(index, entry, &ret); INSERT_IN_MAP(index, entry, ret);
if (ret < 0) if (ret < 0)
break; break;
...@@ -2607,10 +2609,12 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size) ...@@ -2607,10 +2609,12 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
assert(!index->entries.length); assert(!index->entries.length);
if (index->ignore_case) if (index->ignore_case &&
git_idxmap_icase_resize((git_idxmap_icase *) index->entries_map, header.entry_count); (error = git_idxmap_icase_resize((git_idxmap_icase *) index->entries_map,
else header.entry_count)) < 0)
git_idxmap_resize(index->entries_map, header.entry_count); return error;
else if ((error = git_idxmap_resize(index->entries_map, header.entry_count)) < 0)
return error;
/* Parse all the entries */ /* Parse all the entries */
for (i = 0; i < header.entry_count && buffer_size > INDEX_FOOTER_SIZE; ++i) { for (i = 0; i < header.entry_count && buffer_size > INDEX_FOOTER_SIZE; ++i) {
...@@ -2627,7 +2631,7 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size) ...@@ -2627,7 +2631,7 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
goto done; goto done;
} }
INSERT_IN_MAP(index, entry, &error); INSERT_IN_MAP(index, entry, error);
if (error < 0) { if (error < 0) {
index_entry_free(entry); index_entry_free(entry);
...@@ -3106,7 +3110,7 @@ int git_index_read_tree(git_index *index, const git_tree *tree) ...@@ -3106,7 +3110,7 @@ int git_index_read_tree(git_index *index, const git_tree *tree)
size_t i; size_t i;
git_index_entry *e; git_index_entry *e;
if (git_idxmap_alloc(&entries_map) < 0) if (git_idxmap_new(&entries_map) < 0)
return -1; return -1;
git_vector_set_cmp(&entries, index->entries._cmp); /* match sort */ git_vector_set_cmp(&entries, index->entries._cmp); /* match sort */
...@@ -3124,13 +3128,15 @@ int git_index_read_tree(git_index *index, const git_tree *tree) ...@@ -3124,13 +3128,15 @@ int git_index_read_tree(git_index *index, const git_tree *tree)
if ((error = git_tree_walk(tree, GIT_TREEWALK_POST, read_tree_cb, &data)) < 0) if ((error = git_tree_walk(tree, GIT_TREEWALK_POST, read_tree_cb, &data)) < 0)
goto cleanup; goto cleanup;
if (index->ignore_case) if (index->ignore_case &&
git_idxmap_icase_resize((git_idxmap_icase *) entries_map, entries.length); (error = git_idxmap_icase_resize((git_idxmap_icase *) entries_map,
else entries.length)) < 0)
git_idxmap_resize(entries_map, entries.length); goto cleanup;
else if ((error = git_idxmap_resize(entries_map, entries.length)) < 0)
goto cleanup;
git_vector_foreach(&entries, i, e) { 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) { if (error < 0) {
git_error_set(GIT_ERROR_INDEX, "failed to insert entry into map"); git_error_set(GIT_ERROR_INDEX, "failed to insert entry into map");
...@@ -3180,14 +3186,17 @@ static int git_index_read_iterator( ...@@ -3180,14 +3186,17 @@ static int git_index_read_iterator(
assert((new_iterator->flags & GIT_ITERATOR_DONT_IGNORE_CASE)); assert((new_iterator->flags & GIT_ITERATOR_DONT_IGNORE_CASE));
if ((error = git_vector_init(&new_entries, new_length_hint, index->entries._cmp)) < 0 || if ((error = git_vector_init(&new_entries, new_length_hint, index->entries._cmp)) < 0 ||
(error = git_vector_init(&remove_entries, index->entries.length, NULL)) < 0 || (error = git_vector_init(&remove_entries, index->entries.length, NULL)) < 0 ||
(error = git_idxmap_alloc(&new_entries_map)) < 0) (error = git_idxmap_new(&new_entries_map)) < 0)
goto done; goto done;
if (index->ignore_case && new_length_hint) if (index->ignore_case && new_length_hint &&
git_idxmap_icase_resize((git_idxmap_icase *) new_entries_map, new_length_hint); (error = git_idxmap_icase_resize((git_idxmap_icase *) new_entries_map,
else if (new_length_hint) new_length_hint)) < 0)
git_idxmap_resize(new_entries_map, new_length_hint); goto done;
else if (new_length_hint &&
(error = git_idxmap_resize(new_entries_map, new_length_hint)) < 0)
goto done;
opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE | opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE |
GIT_ITERATOR_INCLUDE_CONFLICTS; GIT_ITERATOR_INCLUDE_CONFLICTS;
...@@ -3251,7 +3260,7 @@ static int git_index_read_iterator( ...@@ -3251,7 +3260,7 @@ static int git_index_read_iterator(
if (add_entry) { if (add_entry) {
if ((error = git_vector_insert(&new_entries, add_entry)) == 0) 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) if (remove_entry && error >= 0)
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "pack.h" #include "pack.h"
#include "filebuf.h" #include "filebuf.h"
#include "oid.h" #include "oid.h"
#include "oidarray.h"
#include "oidmap.h" #include "oidmap.h"
#include "zstream.h" #include "zstream.h"
#include "object.h" #include "object.h"
...@@ -147,8 +148,9 @@ int git_indexer_new( ...@@ -147,8 +148,9 @@ int git_indexer_new(
git_hash_ctx_init(&idx->hash_ctx); git_hash_ctx_init(&idx->hash_ctx);
git_hash_ctx_init(&idx->trailer); git_hash_ctx_init(&idx->trailer);
git_buf_init(&idx->entry_data, 0); git_buf_init(&idx->entry_data, 0);
idx->expected_oids = git_oidmap_alloc();
GIT_ERROR_CHECK_ALLOC(idx->expected_oids); if ((error = git_oidmap_new(&idx->expected_oids)) < 0)
goto cleanup;
idx->do_verify = opts.verify; idx->do_verify = opts.verify;
...@@ -308,10 +310,8 @@ static int crc_object(uint32_t *crc_out, git_mwindow_file *mwf, git_off_t start, ...@@ -308,10 +310,8 @@ static int crc_object(uint32_t *crc_out, git_mwindow_file *mwf, git_off_t start,
return 0; return 0;
} }
static void add_expected_oid(git_indexer *idx, const git_oid *oid) static int add_expected_oid(git_indexer *idx, const git_oid *oid)
{ {
int ret;
/* /*
* If we know about that object because it is stored in our ODB or * If we know about that object because it is stored in our ODB or
* because we have already processed it as part of our pack file, we do * because we have already processed it as part of our pack file, we do
...@@ -322,14 +322,16 @@ static void add_expected_oid(git_indexer *idx, const git_oid *oid) ...@@ -322,14 +322,16 @@ static void add_expected_oid(git_indexer *idx, const git_oid *oid)
!git_oidmap_exists(idx->expected_oids, oid)) { !git_oidmap_exists(idx->expected_oids, oid)) {
git_oid *dup = git__malloc(sizeof(*oid)); git_oid *dup = git__malloc(sizeof(*oid));
git_oid_cpy(dup, oid); git_oid_cpy(dup, oid);
git_oidmap_put(idx->expected_oids, dup, &ret); return git_oidmap_set(idx->expected_oids, dup, dup);
} }
return 0;
} }
static int check_object_connectivity(git_indexer *idx, const git_rawobj *obj) static int check_object_connectivity(git_indexer *idx, const git_rawobj *obj)
{ {
git_object *object; git_object *object;
size_t keyidx; git_oid *expected;
int error; int error;
if (obj->type != GIT_OBJECT_BLOB && if (obj->type != GIT_OBJECT_BLOB &&
...@@ -341,11 +343,9 @@ static int check_object_connectivity(git_indexer *idx, const git_rawobj *obj) ...@@ -341,11 +343,9 @@ static int check_object_connectivity(git_indexer *idx, const git_rawobj *obj)
if ((error = git_object__from_raw(&object, obj->data, obj->len, obj->type)) < 0) if ((error = git_object__from_raw(&object, obj->data, obj->len, obj->type)) < 0)
goto out; goto out;
keyidx = git_oidmap_lookup_index(idx->expected_oids, &object->cached.oid); if ((expected = git_oidmap_get(idx->expected_oids, &object->cached.oid)) != NULL) {
if (git_oidmap_valid_index(idx->expected_oids, keyidx)) { git_oidmap_delete(idx->expected_oids, &object->cached.oid);
const git_oid *key = git_oidmap_key(idx->expected_oids, keyidx); git__free(expected);
git__free((git_oid *) key);
git_oidmap_delete_at(idx->expected_oids, keyidx);
} }
/* /*
...@@ -363,7 +363,8 @@ static int check_object_connectivity(git_indexer *idx, const git_rawobj *obj) ...@@ -363,7 +363,8 @@ static int check_object_connectivity(git_indexer *idx, const git_rawobj *obj)
size_t i; size_t i;
git_array_foreach(tree->entries, i, entry) git_array_foreach(tree->entries, i, entry)
add_expected_oid(idx, entry->oid); if (add_expected_oid(idx, entry->oid) < 0)
goto out;
break; break;
} }
...@@ -374,9 +375,11 @@ static int check_object_connectivity(git_indexer *idx, const git_rawobj *obj) ...@@ -374,9 +375,11 @@ static int check_object_connectivity(git_indexer *idx, const git_rawobj *obj)
size_t i; size_t i;
git_array_foreach(commit->parent_ids, i, parent_oid) git_array_foreach(commit->parent_ids, i, parent_oid)
add_expected_oid(idx, parent_oid); if (add_expected_oid(idx, parent_oid) < 0)
goto out;
add_expected_oid(idx, &commit->tree_id); if (add_expected_oid(idx, &commit->tree_id) < 0)
goto out;
break; break;
} }
...@@ -384,7 +387,8 @@ static int check_object_connectivity(git_indexer *idx, const git_rawobj *obj) ...@@ -384,7 +387,8 @@ static int check_object_connectivity(git_indexer *idx, const git_rawobj *obj)
{ {
git_tag *tag = (git_tag *) object; git_tag *tag = (git_tag *) object;
add_expected_oid(idx, &tag->target); if (add_expected_oid(idx, &tag->target) < 0)
goto out;
break; break;
} }
...@@ -402,7 +406,6 @@ out: ...@@ -402,7 +406,6 @@ out:
static int store_object(git_indexer *idx) static int store_object(git_indexer *idx)
{ {
int i, error; int i, error;
size_t k;
git_oid oid; git_oid oid;
struct entry *entry; struct entry *entry;
git_off_t entry_size; git_off_t entry_size;
...@@ -438,22 +441,18 @@ static int store_object(git_indexer *idx) ...@@ -438,22 +441,18 @@ static int store_object(git_indexer *idx)
git_oid_cpy(&pentry->sha1, &oid); git_oid_cpy(&pentry->sha1, &oid);
pentry->offset = entry_start; pentry->offset = entry_start;
k = git_oidmap_put(idx->pack->idx_cache, &pentry->sha1, &error); if (git_oidmap_exists(idx->pack->idx_cache, &pentry->sha1)) {
if (error == -1) { git_error_set(GIT_ERROR_INDEXER, "duplicate object %s found in pack", git_oid_tostr_s(&pentry->sha1));
git__free(pentry); git__free(pentry);
git_error_set_oom();
goto on_error; goto on_error;
} }
if (error == 0) { if ((error = git_oidmap_set(idx->pack->idx_cache, &pentry->sha1, pentry)) < 0) {
git_error_set(GIT_ERROR_INDEXER, "duplicate object %s found in pack", git_oid_tostr_s(&pentry->sha1));
git__free(pentry); git__free(pentry);
git_error_set_oom();
goto on_error; goto on_error;
} }
git_oidmap_set_value_at(idx->pack->idx_cache, k, pentry);
git_oid_cpy(&entry->oid, &oid); git_oid_cpy(&entry->oid, &oid);
if (crc_object(&entry->crc, &idx->pack->mwf, entry_start, entry_size) < 0) if (crc_object(&entry->crc, &idx->pack->mwf, entry_start, entry_size) < 0)
...@@ -482,8 +481,7 @@ GIT_INLINE(bool) has_entry(git_indexer *idx, git_oid *id) ...@@ -482,8 +481,7 @@ GIT_INLINE(bool) has_entry(git_indexer *idx, git_oid *id)
static int save_entry(git_indexer *idx, struct entry *entry, struct git_pack_entry *pentry, git_off_t entry_start) static int save_entry(git_indexer *idx, struct entry *entry, struct git_pack_entry *pentry, git_off_t entry_start)
{ {
int i, error; int i;
size_t k;
if (entry_start > UINT31_MAX) { if (entry_start > UINT31_MAX) {
entry->offset = UINT32_MAX; entry->offset = UINT32_MAX;
...@@ -493,15 +491,13 @@ static int save_entry(git_indexer *idx, struct entry *entry, struct git_pack_ent ...@@ -493,15 +491,13 @@ static int save_entry(git_indexer *idx, struct entry *entry, struct git_pack_ent
} }
pentry->offset = entry_start; pentry->offset = entry_start;
k = git_oidmap_put(idx->pack->idx_cache, &pentry->sha1, &error);
if (error <= 0) { if (git_oidmap_exists(idx->pack->idx_cache, &pentry->sha1) ||
git_oidmap_set(idx->pack->idx_cache, &pentry->sha1, pentry) < 0) {
git_error_set(GIT_ERROR_INDEXER, "cannot insert object into pack"); git_error_set(GIT_ERROR_INDEXER, "cannot insert object into pack");
return -1; return -1;
} }
git_oidmap_set_value_at(idx->pack->idx_cache, k, pentry);
/* Add the object to the list */ /* Add the object to the list */
if (git_vector_insert(&idx->objects, entry) < 0) if (git_vector_insert(&idx->objects, entry) < 0)
return -1; return -1;
...@@ -781,8 +777,8 @@ int git_indexer_append(git_indexer *idx, const void *data, size_t size, git_tran ...@@ -781,8 +777,8 @@ int git_indexer_append(git_indexer *idx, const void *data, size_t size, git_tran
return -1; return -1;
} }
idx->pack->idx_cache = git_oidmap_alloc(); if (git_oidmap_new(&idx->pack->idx_cache) < 0)
GIT_ERROR_CHECK_ALLOC(idx->pack->idx_cache); return -1;
idx->pack->has_cache = 1; idx->pack->has_cache = 1;
if (git_vector_init(&idx->objects, total_objects, objects_cmp) < 0) if (git_vector_init(&idx->objects, total_objects, objects_cmp) < 0)
...@@ -1292,7 +1288,9 @@ on_error: ...@@ -1292,7 +1288,9 @@ on_error:
void git_indexer_free(git_indexer *idx) void git_indexer_free(git_indexer *idx)
{ {
size_t pos; const git_oid *key;
git_oid *value;
size_t iter;
if (idx == NULL) if (idx == NULL)
return; return;
...@@ -1321,14 +1319,9 @@ void git_indexer_free(git_indexer *idx) ...@@ -1321,14 +1319,9 @@ void git_indexer_free(git_indexer *idx)
git_mutex_unlock(&git__mwindow_mutex); git_mutex_unlock(&git__mwindow_mutex);
} }
for (pos = git_oidmap_begin(idx->expected_oids); iter = 0;
pos != git_oidmap_end(idx->expected_oids); pos++) while (git_oidmap_iterate((void **) &value, idx->expected_oids, &iter, &key) == 0)
{ git__free(value);
if (git_oidmap_has_data(idx->expected_oids, pos)) {
git__free((git_oid *) git_oidmap_key(idx->expected_oids, pos));
git_oidmap_delete_at(idx->expected_oids, pos);
}
}
git_hash_ctx_cleanup(&idx->trailer); git_hash_ctx_cleanup(&idx->trailer);
git_hash_ctx_cleanup(&idx->hash_ctx); git_hash_ctx_cleanup(&idx->hash_ctx);
......
...@@ -1104,14 +1104,12 @@ static void deletes_by_oid_free(git_oidmap *map) { ...@@ -1104,14 +1104,12 @@ static void deletes_by_oid_free(git_oidmap *map) {
git_oidmap_free(map); git_oidmap_free(map);
} }
static int deletes_by_oid_enqueue(git_oidmap *map, git_pool* pool, const git_oid *id, size_t idx) { static int deletes_by_oid_enqueue(git_oidmap *map, git_pool* pool, const git_oid *id, size_t idx)
size_t pos; {
deletes_by_oid_queue *queue; deletes_by_oid_queue *queue;
size_t *array_entry; size_t *array_entry;
int error;
pos = git_oidmap_lookup_index(map, id); if ((queue = git_oidmap_get(map, id)) == NULL) {
if (!git_oidmap_valid_index(map, pos)) {
queue = git_pool_malloc(pool, sizeof(deletes_by_oid_queue)); queue = git_pool_malloc(pool, sizeof(deletes_by_oid_queue));
GIT_ERROR_CHECK_ALLOC(queue); GIT_ERROR_CHECK_ALLOC(queue);
...@@ -1119,11 +1117,9 @@ static int deletes_by_oid_enqueue(git_oidmap *map, git_pool* pool, const git_oid ...@@ -1119,11 +1117,9 @@ static int deletes_by_oid_enqueue(git_oidmap *map, git_pool* pool, const git_oid
queue->next_pos = 0; queue->next_pos = 0;
queue->first_entry = idx; queue->first_entry = idx;
git_oidmap_insert(map, id, queue, &error); if (git_oidmap_set(map, id, queue) < 0)
if (error < 0)
return -1; return -1;
} else { } else {
queue = git_oidmap_value_at(map, pos);
array_entry = git_array_alloc(queue->arr); array_entry = git_array_alloc(queue->arr);
GIT_ERROR_CHECK_ALLOC(array_entry); GIT_ERROR_CHECK_ALLOC(array_entry);
*array_entry = idx; *array_entry = idx;
...@@ -1132,18 +1128,14 @@ static int deletes_by_oid_enqueue(git_oidmap *map, git_pool* pool, const git_oid ...@@ -1132,18 +1128,14 @@ static int deletes_by_oid_enqueue(git_oidmap *map, git_pool* pool, const git_oid
return 0; return 0;
} }
static int deletes_by_oid_dequeue(size_t *idx, git_oidmap *map, const git_oid *id) { static int deletes_by_oid_dequeue(size_t *idx, git_oidmap *map, const git_oid *id)
size_t pos; {
deletes_by_oid_queue *queue; deletes_by_oid_queue *queue;
size_t *array_entry; size_t *array_entry;
pos = git_oidmap_lookup_index(map, id); if ((queue = git_oidmap_get(map, id)) == NULL)
if (!git_oidmap_valid_index(map, pos))
return GIT_ENOTFOUND; return GIT_ENOTFOUND;
queue = git_oidmap_value_at(map, pos);
if (queue->next_pos == 0) { if (queue->next_pos == 0) {
*idx = queue->first_entry; *idx = queue->first_entry;
} else { } else {
...@@ -1168,8 +1160,8 @@ static int merge_diff_mark_similarity_exact( ...@@ -1168,8 +1160,8 @@ static int merge_diff_mark_similarity_exact(
git_oidmap *ours_deletes_by_oid = NULL, *theirs_deletes_by_oid = NULL; git_oidmap *ours_deletes_by_oid = NULL, *theirs_deletes_by_oid = NULL;
int error = 0; int error = 0;
if (!(ours_deletes_by_oid = git_oidmap_alloc()) || if (git_oidmap_new(&ours_deletes_by_oid) < 0 ||
!(theirs_deletes_by_oid = git_oidmap_alloc())) { git_oidmap_new(&theirs_deletes_by_oid) < 0) {
error = -1; error = -1;
goto done; goto done;
} }
......
...@@ -44,15 +44,14 @@ int git_mwindow_global_init(void) ...@@ -44,15 +44,14 @@ int git_mwindow_global_init(void)
assert(!git__pack_cache); assert(!git__pack_cache);
git__on_shutdown(git_mwindow_files_free); git__on_shutdown(git_mwindow_files_free);
return git_strmap_alloc(&git__pack_cache); return git_strmap_new(&git__pack_cache);
} }
int git_mwindow_get_pack(struct git_pack_file **out, const char *path) int git_mwindow_get_pack(struct git_pack_file **out, const char *path)
{ {
int error;
char *packname;
size_t pos;
struct git_pack_file *pack; struct git_pack_file *pack;
char *packname;
int error;
if ((error = git_packfile__name(&packname, path)) < 0) if ((error = git_packfile__name(&packname, path)) < 0)
return error; return error;
...@@ -62,13 +61,11 @@ int git_mwindow_get_pack(struct git_pack_file **out, const char *path) ...@@ -62,13 +61,11 @@ int git_mwindow_get_pack(struct git_pack_file **out, const char *path)
return -1; return -1;
} }
pos = git_strmap_lookup_index(git__pack_cache, packname); pack = git_strmap_get(git__pack_cache, packname);
git__free(packname); git__free(packname);
if (git_strmap_valid_index(git__pack_cache, pos)) { if (pack != NULL) {
pack = git_strmap_value_at(git__pack_cache, pos);
git_atomic_inc(&pack->refcount); git_atomic_inc(&pack->refcount);
git_mutex_unlock(&git__mwindow_mutex); git_mutex_unlock(&git__mwindow_mutex);
*out = pack; *out = pack;
return 0; return 0;
...@@ -82,7 +79,7 @@ int git_mwindow_get_pack(struct git_pack_file **out, const char *path) ...@@ -82,7 +79,7 @@ int git_mwindow_get_pack(struct git_pack_file **out, const char *path)
git_atomic_inc(&pack->refcount); git_atomic_inc(&pack->refcount);
git_strmap_insert(git__pack_cache, pack->pack_name, pack, &error); error = git_strmap_set(git__pack_cache, pack->pack_name, pack);
git_mutex_unlock(&git__mwindow_mutex); git_mutex_unlock(&git__mwindow_mutex);
if (error < 0) { if (error < 0) {
...@@ -97,7 +94,6 @@ int git_mwindow_get_pack(struct git_pack_file **out, const char *path) ...@@ -97,7 +94,6 @@ int git_mwindow_get_pack(struct git_pack_file **out, const char *path)
void git_mwindow_put_pack(struct git_pack_file *pack) void git_mwindow_put_pack(struct git_pack_file *pack)
{ {
int count; int count;
size_t pos;
if (git_mutex_lock(&git__mwindow_mutex) < 0) if (git_mutex_lock(&git__mwindow_mutex) < 0)
return; return;
...@@ -105,13 +101,12 @@ void git_mwindow_put_pack(struct git_pack_file *pack) ...@@ -105,13 +101,12 @@ void git_mwindow_put_pack(struct git_pack_file *pack)
/* put before get would be a corrupted state */ /* put before get would be a corrupted state */
assert(git__pack_cache); assert(git__pack_cache);
pos = git_strmap_lookup_index(git__pack_cache, pack->pack_name);
/* if we cannot find it, the state is corrupted */ /* if we cannot find it, the state is corrupted */
assert(git_strmap_valid_index(git__pack_cache, pos)); assert(git_strmap_exists(git__pack_cache, pack->pack_name));
count = git_atomic_dec(&pack->refcount); count = git_atomic_dec(&pack->refcount);
if (count == 0) { if (count == 0) {
git_strmap_delete_at(git__pack_cache, pos); git_strmap_delete(git__pack_cache, pack->pack_name);
git_packfile_free(pack); git_packfile_free(pack);
} }
......
...@@ -37,15 +37,9 @@ static int impl__write(git_odb_backend *_backend, const git_oid *oid, const void ...@@ -37,15 +37,9 @@ static int impl__write(git_odb_backend *_backend, const git_oid *oid, const void
{ {
struct memory_packer_db *db = (struct memory_packer_db *)_backend; struct memory_packer_db *db = (struct memory_packer_db *)_backend;
struct memobject *obj = NULL; struct memobject *obj = NULL;
size_t pos;
size_t alloc_len; size_t alloc_len;
int rval;
pos = git_oidmap_put(db->objects, oid, &rval); if (git_oidmap_exists(db->objects, oid))
if (rval < 0)
return -1;
if (rval == 0)
return 0; return 0;
GIT_ERROR_CHECK_ALLOC_ADD(&alloc_len, sizeof(struct memobject), len); GIT_ERROR_CHECK_ALLOC_ADD(&alloc_len, sizeof(struct memobject), len);
...@@ -57,8 +51,8 @@ static int impl__write(git_odb_backend *_backend, const git_oid *oid, const void ...@@ -57,8 +51,8 @@ static int impl__write(git_odb_backend *_backend, const git_oid *oid, const void
obj->len = len; obj->len = len;
obj->type = type; obj->type = type;
git_oidmap_set_key_at(db->objects, pos, &obj->oid); if (git_oidmap_set(db->objects, &obj->oid, obj) < 0)
git_oidmap_set_value_at(db->objects, pos, obj); return -1;
if (type == GIT_OBJECT_COMMIT) { if (type == GIT_OBJECT_COMMIT) {
struct memobject **store = git_array_alloc(db->commits); struct memobject **store = git_array_alloc(db->commits);
...@@ -79,15 +73,11 @@ static int impl__exists(git_odb_backend *backend, const git_oid *oid) ...@@ -79,15 +73,11 @@ static int impl__exists(git_odb_backend *backend, const git_oid *oid)
static int impl__read(void **buffer_p, size_t *len_p, git_object_t *type_p, git_odb_backend *backend, const git_oid *oid) static int impl__read(void **buffer_p, size_t *len_p, git_object_t *type_p, git_odb_backend *backend, const git_oid *oid)
{ {
struct memory_packer_db *db = (struct memory_packer_db *)backend; struct memory_packer_db *db = (struct memory_packer_db *)backend;
struct memobject *obj = NULL; struct memobject *obj;
size_t pos;
pos = git_oidmap_lookup_index(db->objects, oid); if ((obj = git_oidmap_get(db->objects, oid)) == NULL)
if (!git_oidmap_valid_index(db->objects, pos))
return GIT_ENOTFOUND; return GIT_ENOTFOUND;
obj = git_oidmap_value_at(db->objects, pos);
*len_p = obj->len; *len_p = obj->len;
*type_p = obj->type; *type_p = obj->type;
*buffer_p = git__malloc(obj->len); *buffer_p = git__malloc(obj->len);
...@@ -100,15 +90,11 @@ static int impl__read(void **buffer_p, size_t *len_p, git_object_t *type_p, git_ ...@@ -100,15 +90,11 @@ static int impl__read(void **buffer_p, size_t *len_p, git_object_t *type_p, git_
static int impl__read_header(size_t *len_p, git_object_t *type_p, git_odb_backend *backend, const git_oid *oid) static int impl__read_header(size_t *len_p, git_object_t *type_p, git_odb_backend *backend, const git_oid *oid)
{ {
struct memory_packer_db *db = (struct memory_packer_db *)backend; struct memory_packer_db *db = (struct memory_packer_db *)backend;
struct memobject *obj = NULL; struct memobject *obj;
size_t pos;
pos = git_oidmap_lookup_index(db->objects, oid); if ((obj = git_oidmap_get(db->objects, oid)) == NULL)
if (!git_oidmap_valid_index(db->objects, pos))
return GIT_ENOTFOUND; return GIT_ENOTFOUND;
obj = git_oidmap_value_at(db->objects, pos);
*len_p = obj->len; *len_p = obj->len;
*type_p = obj->type; *type_p = obj->type;
return 0; return 0;
...@@ -171,7 +157,8 @@ int git_mempack_new(git_odb_backend **out) ...@@ -171,7 +157,8 @@ int git_mempack_new(git_odb_backend **out)
db = git__calloc(1, sizeof(struct memory_packer_db)); db = git__calloc(1, sizeof(struct memory_packer_db));
GIT_ERROR_CHECK_ALLOC(db); GIT_ERROR_CHECK_ALLOC(db);
db->objects = git_oidmap_alloc(); if (git_oidmap_new(&db->objects) < 0)
return -1;
db->parent.version = GIT_ODB_BACKEND_VERSION; db->parent.version = GIT_ODB_BACKEND_VERSION;
db->parent.read = &impl__read; db->parent.read = &impl__read;
......
...@@ -18,9 +18,13 @@ __KHASH_TYPE(off, git_off_t, void *) ...@@ -18,9 +18,13 @@ __KHASH_TYPE(off, git_off_t, void *)
__KHASH_IMPL(off, static kh_inline, git_off_t, void *, 1, kh_int64_hash_func, kh_int64_hash_equal) __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)
int git_offmap_new(git_offmap **out)
{ {
return kh_init(off); *out = kh_init(off);
GIT_ERROR_CHECK_ALLOC(*out);
return 0;
} }
void git_offmap_free(git_offmap *map) void git_offmap_free(git_offmap *map)
...@@ -33,81 +37,65 @@ void git_offmap_clear(git_offmap *map) ...@@ -33,81 +37,65 @@ void git_offmap_clear(git_offmap *map)
kh_clear(off, map); kh_clear(off, map);
} }
size_t git_offmap_num_entries(git_offmap *map) size_t git_offmap_size(git_offmap *map)
{ {
return kh_size(map); return kh_size(map);
} }
size_t git_offmap_lookup_index(git_offmap *map, const git_off_t key) void *git_offmap_get(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); size_t idx = kh_get(off, map, key);
if (idx == kh_end(map) || !kh_exist(map, idx))
return NULL;
return kh_val(map, idx);
} }
int git_offmap_has_data(git_offmap *map, size_t idx) int git_offmap_set(git_offmap *map, const git_off_t key, void *value)
{ {
return kh_exist(map, idx); size_t idx;
} int rval;
git_off_t git_offmap_key_at(git_offmap *map, size_t idx) idx = kh_put(off, map, key, &rval);
{ if (rval < 0)
return kh_key(map, idx); return -1;
}
void *git_offmap_value_at(git_offmap *map, size_t idx) if (rval == 0)
{ kh_key(map, idx) = key;
return kh_val(map, idx);
}
void git_offmap_set_value_at(git_offmap *map, size_t idx, void *value)
{
kh_val(map, idx) = value; kh_val(map, idx) = value;
return 0;
} }
void git_offmap_delete_at(git_offmap *map, size_t idx) int git_offmap_delete(git_offmap *map, const git_off_t key)
{ {
khiter_t idx = kh_get(off, map, key);
if (idx == kh_end(map))
return GIT_ENOTFOUND;
kh_del(off, map, idx); kh_del(off, map, idx);
return 0;
} }
int git_offmap_put(git_offmap *map, const git_off_t key, int *err) int git_offmap_exists(git_offmap *map, const git_off_t key)
{ {
return kh_put(off, map, key, err); return kh_get(off, map, key) != kh_end(map);
} }
void git_offmap_insert(git_offmap *map, const git_off_t key, void *value, int *rval) int git_offmap_iterate(void **value, git_offmap *map, size_t *iter, git_off_t *key)
{ {
khiter_t idx = kh_put(off, map, key, rval); size_t i = *iter;
if ((*rval) >= 0) { while (i < map->n_buckets && !kh_exist(map, i))
if ((*rval) == 0) i++;
kh_key(map, idx) = key;
kh_val(map, idx) = value;
}
}
void git_offmap_delete(git_offmap *map, const git_off_t key) if (i >= map->n_buckets)
{ return GIT_ITEROVER;
khiter_t idx = git_offmap_lookup_index(map, key);
if (git_offmap_valid_index(map, idx))
git_offmap_delete_at(map, idx);
}
size_t git_offmap_begin(git_offmap *map) if (key)
{ *key = kh_key(map, i);
GIT_UNUSED(map); if (value)
return 0; *value = kh_value(map, i);
} *iter = ++i;
size_t git_offmap_end(git_offmap *map) return 0;
{
return map->n_buckets;
} }
...@@ -11,44 +11,122 @@ ...@@ -11,44 +11,122 @@
#include "git2/types.h" #include "git2/types.h"
/** A map with `git_off_t`s as key. */
typedef struct kh_off_s git_offmap; typedef struct kh_off_s git_offmap;
git_offmap *git_offmap_alloc(void); /**
* Allocate a new `git_off_t` map.
*
* @param out Pointer to the map that shall be allocated.
* @return 0 on success, an error code if allocation has failed.
*/
int git_offmap_new(git_offmap **out);
/**
* Free memory associated with the map.
*
* Note that this function will _not_ free values added to this
* map.
*
* @param map Pointer to the map that is to be free'd. May be
* `NULL`.
*/
void git_offmap_free(git_offmap *map); void git_offmap_free(git_offmap *map);
/**
* Clear all entries from the map.
*
* This function will remove all entries from the associated map.
* Memory associated with it will not be released, though.
*
* @param map Pointer to the map that shall be cleared. May be
* `NULL`.
*/
void git_offmap_clear(git_offmap *map); void git_offmap_clear(git_offmap *map);
size_t git_offmap_num_entries(git_offmap *map); /**
* Return the number of elements in the map.
*
* @parameter map map containing the elements
* @return number of elements in the map
*/
size_t git_offmap_size(git_offmap *map);
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); * Return value associated with the given key.
*
* @param map map to search key in
* @param key key to search for
* @return value associated with the given key or NULL if the key was not found
*/
void *git_offmap_get(git_offmap *map, const git_off_t key);
int git_offmap_exists(git_offmap *map, const git_off_t key); /**
int git_offmap_has_data(git_offmap *map, size_t idx); * Set the entry for key to value.
*
* If the map has no corresponding entry for the given key, a new
* entry will be created with the given value. If an entry exists
* already, its value will be updated to match the given value.
*
* @param map map to create new entry in
* @param key key to set
* @param value value to associate the key with; may be NULL
* @return zero if the key was successfully set, a negative error
* code otherwise
*/
int git_offmap_set(git_offmap *map, const git_off_t key, void *value);
git_off_t git_offmap_key_at(git_offmap *map, size_t idx); /**
void *git_offmap_value_at(git_offmap *map, size_t idx); * Delete an entry from the map.
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); * Delete the given key and its value from the map. If no such
* key exists, this will do nothing.
*
* @param map map to delete key in
* @param key key to delete
* @return `0` if the key has been deleted, GIT_ENOTFOUND if no
* such key was found, a negative code in case of an
* error
*/
int git_offmap_delete(git_offmap *map, const git_off_t key);
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); * Check whether a key exists in the given map.
void git_offmap_delete(git_offmap *map, const git_off_t key); *
* @param map map to query for the key
* @param key key to search for
* @return 0 if the key has not been found, 1 otherwise
*/
int git_offmap_exists(git_offmap *map, const git_off_t key);
size_t git_offmap_begin(git_offmap *map); /**
size_t git_offmap_end(git_offmap *map); * Iterate over entries of the map.
*
* This functions allows to iterate over all key-value entries of
* the map. The current position is stored in the `iter` variable
* and should be initialized to `0` before the first call to this
* function.
*
* @param map map to iterate over
* @param value pointer to the variable where to store the current
* value. May be NULL.
* @param iter iterator storing the current position. Initialize
* with zero previous to the first call.
* @param key pointer to the variable where to store the current
* key. May be NULL.
* @return `0` if the next entry was correctly retrieved.
* GIT_ITEROVER if no entries are left. A negative error
* code otherwise.
*/
int git_offmap_iterate(void **value, git_offmap *map, size_t *iter, git_off_t *key);
#define git_offmap_foreach(h, kvar, vvar, code) { size_t __i; \ #define git_offmap_foreach(h, kvar, vvar, code) { size_t __i = 0; \
for (__i = git_offmap_begin(h); __i != git_offmap_end(h); ++__i) { \ while (git_offmap_iterate((void **) &(vvar), h, &__i, &(kvar)) == 0) { \
if (!git_offmap_has_data(h,__i)) continue; \
(kvar) = git_offmap_key_at(h,__i); \
(vvar) = git_offmap_value_at(h,__i); \
code; \ code; \
} } } }
#define git_offmap_foreach_value(h, vvar, code) { size_t __i; \ #define git_offmap_foreach_value(h, vvar, code) { size_t __i = 0; \
for (__i = git_offmap_begin(h); __i != git_offmap_end(h); ++__i) { \ while (git_offmap_iterate((void **) &(vvar), h, &__i, NULL) == 0) { \
if (!git_offmap_has_data(h,__i)) continue; \
(vvar) = git_offmap_value_at(h,__i); \
code; \ code; \
} } } }
......
...@@ -25,9 +25,12 @@ GIT_INLINE(khint_t) git_oidmap_hash(const git_oid *oid) ...@@ -25,9 +25,12 @@ GIT_INLINE(khint_t) git_oidmap_hash(const git_oid *oid)
__KHASH_IMPL(oid, static kh_inline, const git_oid *, void *, 1, git_oidmap_hash, git_oid_equal) __KHASH_IMPL(oid, static kh_inline, const git_oid *, void *, 1, git_oidmap_hash, git_oid_equal)
git_oidmap *git_oidmap_alloc() int git_oidmap_new(git_oidmap **out)
{ {
return kh_init(oid); *out = kh_init(oid);
GIT_ERROR_CHECK_ALLOC(*out);
return 0;
} }
void git_oidmap_free(git_oidmap *map) void git_oidmap_free(git_oidmap *map)
...@@ -45,81 +48,60 @@ size_t git_oidmap_size(git_oidmap *map) ...@@ -45,81 +48,60 @@ size_t git_oidmap_size(git_oidmap *map)
return kh_size(map); return kh_size(map);
} }
size_t git_oidmap_lookup_index(git_oidmap *map, const git_oid *key) void *git_oidmap_get(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); size_t idx = kh_get(oid, map, key);
} if (idx == kh_end(map) || !kh_exist(map, idx))
return NULL;
int git_oidmap_has_data(git_oidmap *map, size_t idx) return kh_val(map, idx);
{
return kh_exist(map, idx);
} }
const git_oid *git_oidmap_key(git_oidmap *map, size_t idx) int git_oidmap_set(git_oidmap *map, const git_oid *key, void *value)
{ {
return kh_key(map, idx); size_t idx;
} int rval;
void git_oidmap_set_key_at(git_oidmap *map, size_t idx, git_oid *key) idx = kh_put(oid, map, key, &rval);
{ if (rval < 0)
kh_key(map, idx) = key; return -1;
}
void *git_oidmap_value_at(git_oidmap *map, size_t idx) if (rval == 0)
{ kh_key(map, idx) = key;
return kh_val(map, idx);
}
void git_oidmap_set_value_at(git_oidmap *map, size_t idx, void *value)
{
kh_val(map, idx) = value; kh_val(map, idx) = value;
return 0;
} }
void git_oidmap_delete_at(git_oidmap *map, size_t idx) int git_oidmap_delete(git_oidmap *map, const git_oid *key)
{ {
khiter_t idx = kh_get(oid, map, key);
if (idx == kh_end(map))
return GIT_ENOTFOUND;
kh_del(oid, map, idx); kh_del(oid, map, idx);
return 0;
} }
int git_oidmap_put(git_oidmap *map, const git_oid *key, int *err) int git_oidmap_exists(git_oidmap *map, const git_oid *key)
{ {
return kh_put(oid, map, key, err); return kh_get(oid, map, key) != kh_end(map);
} }
void git_oidmap_insert(git_oidmap *map, const git_oid *key, void *value, int *rval) int git_oidmap_iterate(void **value, git_oidmap *map, size_t *iter, const git_oid **key)
{ {
khiter_t idx = kh_put(oid, map, key, rval); size_t i = *iter;
if ((*rval) >= 0) { while (i < map->n_buckets && !kh_exist(map, i))
if ((*rval) == 0) i++;
kh_key(map, idx) = key;
kh_val(map, idx) = value;
}
}
void git_oidmap_delete(git_oidmap *map, const git_oid *key) if (i >= map->n_buckets)
{ return GIT_ITEROVER;
khiter_t idx = git_oidmap_lookup_index(map, key);
if (git_oidmap_valid_index(map, idx))
git_oidmap_delete_at(map, idx);
}
size_t git_oidmap_begin(git_oidmap *map) if (key)
{ *key = kh_key(map, i);
GIT_UNUSED(map); if (value)
return 0; *value = kh_value(map, i);
} *iter = ++i;
size_t git_oidmap_end(git_oidmap *map) return 0;
{
return map->n_buckets;
} }
...@@ -11,37 +11,117 @@ ...@@ -11,37 +11,117 @@
#include "git2/oid.h" #include "git2/oid.h"
/** A map with `git_oid`s as key. */
typedef struct kh_oid_s git_oidmap; typedef struct kh_oid_s git_oidmap;
git_oidmap *git_oidmap_alloc(void); /**
* Allocate a new OID map.
*
* @param out Pointer to the map that shall be allocated.
* @return 0 on success, an error code if allocation has failed.
*/
int git_oidmap_new(git_oidmap **out);
/**
* Free memory associated with the map.
*
* Note that this function will _not_ free values added to this
* map.
*
* @param map Pointer to the map that is to be free'd. May be
* `NULL`.
*/
void git_oidmap_free(git_oidmap *map); void git_oidmap_free(git_oidmap *map);
/**
* Clear all entries from the map.
*
* This function will remove all entries from the associated map.
* Memory associated with it will not be released, though.
*
* @param map Pointer to the map that shall be cleared. May be
* `NULL`.
*/
void git_oidmap_clear(git_oidmap *map); void git_oidmap_clear(git_oidmap *map);
/**
* Return the number of elements in the map.
*
* @parameter map map containing the elements
* @return number of elements in the map
*/
size_t git_oidmap_size(git_oidmap *map); size_t git_oidmap_size(git_oidmap *map);
size_t git_oidmap_lookup_index(git_oidmap *map, const git_oid *key); /**
int git_oidmap_valid_index(git_oidmap *map, size_t idx); * Return value associated with the given key.
*
* @param map map to search key in
* @param key key to search for
* @return value associated with the given key or NULL if the key was not found
*/
void *git_oidmap_get(git_oidmap *map, const git_oid *key);
int git_oidmap_exists(git_oidmap *map, const git_oid *key); /**
int git_oidmap_has_data(git_oidmap *map, size_t idx); * Set the entry for key to value.
*
* If the map has no corresponding entry for the given key, a new
* entry will be created with the given value. If an entry exists
* already, its value will be updated to match the given value.
*
* @param map map to create new entry in
* @param key key to set
* @param value value to associate the key with; may be NULL
* @return zero if the key was successfully set, a negative error
* code otherwise
*/
int git_oidmap_set(git_oidmap *map, const git_oid *key, void *value);
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); * Delete an entry from the map.
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); * Delete the given key and its value from the map. If no such
void git_oidmap_delete_at(git_oidmap *map, size_t idx); * key exists, this will do nothing.
*
* @param map map to delete key in
* @param key key to delete
* @return `0` if the key has been deleted, GIT_ENOTFOUND if no
* such key was found, a negative code in case of an
* error
*/
int git_oidmap_delete(git_oidmap *map, const git_oid *key);
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); * Check whether a key exists in the given map.
void git_oidmap_delete(git_oidmap *map, const git_oid *key); *
* @param map map to query for the key
* @param key key to search for
* @return 0 if the key has not been found, 1 otherwise
*/
int git_oidmap_exists(git_oidmap *map, const git_oid *key);
size_t git_oidmap_begin(git_oidmap *map); /**
size_t git_oidmap_end(git_oidmap *map); * Iterate over entries of the map.
*
* This functions allows to iterate over all key-value entries of
* the map. The current position is stored in the `iter` variable
* and should be initialized to `0` before the first call to this
* function.
*
* @param map map to iterate over
* @param value pointer to the variable where to store the current
* value. May be NULL.
* @param iter iterator storing the current position. Initialize
* with zero previous to the first call.
* @param key pointer to the variable where to store the current
* key. May be NULL.
* @return `0` if the next entry was correctly retrieved.
* GIT_ITEROVER if no entries are left. A negative error
* code otherwise.
*/
int git_oidmap_iterate(void **value, git_oidmap *map, size_t *iter, const git_oid **key);
#define git_oidmap_foreach_value(h, vvar, code) { size_t __i; \ #define git_oidmap_foreach_value(h, vvar, code) { size_t __i = 0; \
for (__i = git_oidmap_begin(h); __i != git_oidmap_end(h); ++__i) { \ while (git_oidmap_iterate((void **) &(vvar), h, &__i, NULL) == 0) { \
if (!git_oidmap_has_data(h,__i)) continue; \
(vvar) = git_oidmap_value_at(h,__i); \
code; \ code; \
} } } }
......
...@@ -141,12 +141,10 @@ int git_packbuilder_new(git_packbuilder **out, git_repository *repo) ...@@ -141,12 +141,10 @@ int git_packbuilder_new(git_packbuilder **out, git_repository *repo)
pb = git__calloc(1, sizeof(*pb)); pb = git__calloc(1, sizeof(*pb));
GIT_ERROR_CHECK_ALLOC(pb); GIT_ERROR_CHECK_ALLOC(pb);
pb->object_ix = git_oidmap_alloc(); if (git_oidmap_new(&pb->object_ix) < 0)
if (!pb->object_ix)
goto on_error; goto on_error;
pb->walk_objects = git_oidmap_alloc(); if (git_oidmap_new(&pb->walk_objects) < 0)
if (!pb->walk_objects)
goto on_error; goto on_error;
git_pool_init(&pb->object_pool, sizeof(struct walk_object)); git_pool_init(&pb->object_pool, sizeof(struct walk_object));
...@@ -194,24 +192,26 @@ unsigned int git_packbuilder_set_threads(git_packbuilder *pb, unsigned int n) ...@@ -194,24 +192,26 @@ unsigned int git_packbuilder_set_threads(git_packbuilder *pb, unsigned int n)
return pb->nr_threads; return pb->nr_threads;
} }
static void rehash(git_packbuilder *pb) static int rehash(git_packbuilder *pb)
{ {
git_pobject *po; git_pobject *po;
size_t pos, i; size_t i;
int ret;
git_oidmap_clear(pb->object_ix); git_oidmap_clear(pb->object_ix);
for (i = 0, po = pb->object_list; i < pb->nr_objects; i++, po++) { for (i = 0, po = pb->object_list; i < pb->nr_objects; i++, po++) {
pos = git_oidmap_put(pb->object_ix, &po->id, &ret); if (git_oidmap_set(pb->object_ix, &po->id, po) < 0)
git_oidmap_set_value_at(pb->object_ix, pos, po); return -1;
} }
return 0;
} }
int git_packbuilder_insert(git_packbuilder *pb, const git_oid *oid, int git_packbuilder_insert(git_packbuilder *pb, const git_oid *oid,
const char *name) const char *name)
{ {
git_pobject *po; git_pobject *po;
size_t newsize, pos; size_t newsize;
int ret; int ret;
assert(pb && oid); assert(pb && oid);
...@@ -235,7 +235,9 @@ int git_packbuilder_insert(git_packbuilder *pb, const git_oid *oid, ...@@ -235,7 +235,9 @@ int git_packbuilder_insert(git_packbuilder *pb, const git_oid *oid,
pb->object_list = git__reallocarray(pb->object_list, pb->object_list = git__reallocarray(pb->object_list,
pb->nr_alloc, sizeof(*po)); pb->nr_alloc, sizeof(*po));
GIT_ERROR_CHECK_ALLOC(pb->object_list); GIT_ERROR_CHECK_ALLOC(pb->object_list);
rehash(pb);
if (rehash(pb) < 0)
return -1;
} }
po = pb->object_list + pb->nr_objects; po = pb->object_list + pb->nr_objects;
...@@ -248,13 +250,10 @@ int git_packbuilder_insert(git_packbuilder *pb, const git_oid *oid, ...@@ -248,13 +250,10 @@ int git_packbuilder_insert(git_packbuilder *pb, const git_oid *oid,
git_oid_cpy(&po->id, oid); git_oid_cpy(&po->id, oid);
po->hash = name_hash(name); po->hash = name_hash(name);
pos = git_oidmap_put(pb->object_ix, &po->id, &ret); if (git_oidmap_set(pb->object_ix, &po->id, po) < 0) {
if (ret < 0) {
git_error_set_oom(); git_error_set_oom();
return ret; return -1;
} }
assert(ret != 0);
git_oidmap_set_value_at(pb->object_ix, pos, po);
pb->done = false; pb->done = false;
...@@ -514,15 +513,12 @@ static int cb_tag_foreach(const char *name, git_oid *oid, void *data) ...@@ -514,15 +513,12 @@ static int cb_tag_foreach(const char *name, git_oid *oid, void *data)
{ {
git_packbuilder *pb = data; git_packbuilder *pb = data;
git_pobject *po; git_pobject *po;
size_t pos;
GIT_UNUSED(name); GIT_UNUSED(name);
pos = git_oidmap_lookup_index(pb->object_ix, oid); if ((po = git_oidmap_get(pb->object_ix, oid)) == NULL)
if (!git_oidmap_valid_index(pb->object_ix, pos))
return 0; return 0;
po = git_oidmap_value_at(pb->object_ix, pos);
po->tagged = 1; po->tagged = 1;
/* TODO: peel objects */ /* TODO: peel objects */
...@@ -1539,18 +1535,15 @@ static int lookup_walk_object(struct walk_object **out, git_packbuilder *pb, con ...@@ -1539,18 +1535,15 @@ static int lookup_walk_object(struct walk_object **out, git_packbuilder *pb, con
static int retrieve_object(struct walk_object **out, git_packbuilder *pb, const git_oid *id) static int retrieve_object(struct walk_object **out, git_packbuilder *pb, const git_oid *id)
{ {
int error;
size_t pos;
struct walk_object *obj; struct walk_object *obj;
int error;
pos = git_oidmap_lookup_index(pb->walk_objects, id); if ((obj = git_oidmap_get(pb->walk_objects, id)) == NULL) {
if (git_oidmap_valid_index(pb->walk_objects, pos)) {
obj = git_oidmap_value_at(pb->walk_objects, pos);
} else {
if ((error = lookup_walk_object(&obj, pb, id)) < 0) if ((error = lookup_walk_object(&obj, pb, id)) < 0)
return error; return error;
git_oidmap_insert(pb->walk_objects, &obj->id, obj, &error); if ((error = git_oidmap_set(pb->walk_objects, &obj->id, obj)) < 0)
return error;
} }
*out = obj; *out = obj;
......
...@@ -92,8 +92,8 @@ static void cache_free(git_pack_cache *cache) ...@@ -92,8 +92,8 @@ static void cache_free(git_pack_cache *cache)
static int cache_init(git_pack_cache *cache) static int cache_init(git_pack_cache *cache)
{ {
cache->entries = git_offmap_alloc(); if (git_offmap_new(&cache->entries) < 0)
GIT_ERROR_CHECK_ALLOC(cache->entries); return -1;
cache->memory_limit = GIT_PACK_CACHE_MEMORY_LIMIT; cache->memory_limit = GIT_PACK_CACHE_MEMORY_LIMIT;
...@@ -111,15 +111,12 @@ static int cache_init(git_pack_cache *cache) ...@@ -111,15 +111,12 @@ static int cache_init(git_pack_cache *cache)
static git_pack_cache_entry *cache_get(git_pack_cache *cache, git_off_t offset) static git_pack_cache_entry *cache_get(git_pack_cache *cache, git_off_t offset)
{ {
git_pack_cache_entry *entry = NULL; git_pack_cache_entry *entry;
size_t k;
if (git_mutex_lock(&cache->lock) < 0) if (git_mutex_lock(&cache->lock) < 0)
return NULL; return NULL;
k = git_offmap_lookup_index(cache->entries, offset); if ((entry = git_offmap_get(cache->entries, offset)) != NULL) {
if (git_offmap_valid_index(cache->entries, k)) { /* found it */
entry = git_offmap_value_at(cache->entries, k);
git_atomic_inc(&entry->refcount); git_atomic_inc(&entry->refcount);
entry->last_usage = cache->use_ctr++; entry->last_usage = cache->use_ctr++;
} }
...@@ -150,8 +147,7 @@ static int cache_add( ...@@ -150,8 +147,7 @@ static int cache_add(
git_off_t offset) git_off_t offset)
{ {
git_pack_cache_entry *entry; git_pack_cache_entry *entry;
int error, exists = 0; int exists;
size_t k;
if (base->len > GIT_PACK_CACHE_SIZE_LIMIT) if (base->len > GIT_PACK_CACHE_SIZE_LIMIT)
return -1; return -1;
...@@ -169,9 +165,7 @@ static int cache_add( ...@@ -169,9 +165,7 @@ static int cache_add(
while (cache->memory_used + base->len > cache->memory_limit) while (cache->memory_used + base->len > cache->memory_limit)
free_lowest_entry(cache); free_lowest_entry(cache);
k = git_offmap_put(cache->entries, offset, &error); git_offmap_set(cache->entries, offset, entry);
assert(error != 0);
git_offmap_set_value_at(cache->entries, k, entry);
cache->memory_used += entry->raw.len; cache->memory_used += entry->raw.len;
*cached_out = entry; *cached_out = entry;
...@@ -957,14 +951,13 @@ git_off_t get_delta_base( ...@@ -957,14 +951,13 @@ git_off_t get_delta_base(
} else if (type == GIT_OBJECT_REF_DELTA) { } else if (type == GIT_OBJECT_REF_DELTA) {
/* If we have the cooperative cache, search in it first */ /* If we have the cooperative cache, search in it first */
if (p->has_cache) { if (p->has_cache) {
struct git_pack_entry *entry;
git_oid oid; git_oid oid;
size_t k;
git_oid_fromraw(&oid, base_info); git_oid_fromraw(&oid, base_info);
k = git_oidmap_lookup_index(p->idx_cache, &oid); if ((entry = git_oidmap_get(p->idx_cache, &oid)) != NULL) {
if (git_oidmap_valid_index(p->idx_cache, k)) {
*curpos += 20; *curpos += 20;
return ((struct git_pack_entry *)git_oidmap_value_at(p->idx_cache, k))->offset; return entry->offset;
} else { } else {
/* If we're building an index, don't try to find the pack /* If we're building an index, don't try to find the pack
* entry; we just haven't seen it yet. We'll make * entry; we just haven't seen it yet. We'll make
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "map.h" #include "map.h"
#include "mwindow.h" #include "mwindow.h"
#include "odb.h" #include "odb.h"
#include "offmap.h"
#include "oidmap.h" #include "oidmap.h"
#include "array.h" #include "array.h"
...@@ -71,9 +72,6 @@ struct pack_chain_elem { ...@@ -71,9 +72,6 @@ struct pack_chain_elem {
typedef git_array_t(struct pack_chain_elem) git_dependency_chain; typedef git_array_t(struct pack_chain_elem) git_dependency_chain;
#include "offmap.h"
#include "oidmap.h"
#define GIT_PACK_CACHE_MEMORY_LIMIT 16 * 1024 * 1024 #define GIT_PACK_CACHE_MEMORY_LIMIT 16 * 1024 * 1024
#define GIT_PACK_CACHE_SIZE_LIMIT 1024 * 1024 /* don't bother caching anything over 1MB */ #define GIT_PACK_CACHE_SIZE_LIMIT 1024 * 1024 /* don't bother caching anything over 1MB */
......
...@@ -2916,7 +2916,7 @@ int git_repository_submodule_cache_all(git_repository *repo) ...@@ -2916,7 +2916,7 @@ int git_repository_submodule_cache_all(git_repository *repo)
assert(repo); assert(repo);
if ((error = git_strmap_alloc(&repo->submodule_cache))) if ((error = git_strmap_new(&repo->submodule_cache)))
return error; return error;
error = git_submodule__map(repo, repo->submodule_cache); error = git_submodule__map(repo, repo->submodule_cache);
......
...@@ -21,13 +21,10 @@ git_commit_list_node *git_revwalk__commit_lookup( ...@@ -21,13 +21,10 @@ git_commit_list_node *git_revwalk__commit_lookup(
git_revwalk *walk, const git_oid *oid) git_revwalk *walk, const git_oid *oid)
{ {
git_commit_list_node *commit; git_commit_list_node *commit;
size_t pos;
int ret;
/* lookup and reserve space if not already present */ /* lookup and reserve space if not already present */
pos = git_oidmap_lookup_index(walk->commits, oid); if ((commit = git_oidmap_get(walk->commits, oid)) != NULL)
if (git_oidmap_valid_index(walk->commits, pos)) return commit;
return git_oidmap_value_at(walk->commits, pos);
commit = git_commit_list_alloc_node(walk); commit = git_commit_list_alloc_node(walk);
if (commit == NULL) if (commit == NULL)
...@@ -35,9 +32,8 @@ git_commit_list_node *git_revwalk__commit_lookup( ...@@ -35,9 +32,8 @@ git_commit_list_node *git_revwalk__commit_lookup(
git_oid_cpy(&commit->oid, oid); git_oid_cpy(&commit->oid, oid);
pos = git_oidmap_put(walk->commits, &commit->oid, &ret); if ((git_oidmap_set(walk->commits, &commit->oid, commit)) < 0)
assert(ret != 0); return NULL;
git_oidmap_set_value_at(walk->commits, pos, commit);
return commit; return commit;
} }
...@@ -626,8 +622,8 @@ int git_revwalk_new(git_revwalk **revwalk_out, git_repository *repo) ...@@ -626,8 +622,8 @@ int git_revwalk_new(git_revwalk **revwalk_out, git_repository *repo)
git_revwalk *walk = git__calloc(1, sizeof(git_revwalk)); git_revwalk *walk = git__calloc(1, sizeof(git_revwalk));
GIT_ERROR_CHECK_ALLOC(walk); GIT_ERROR_CHECK_ALLOC(walk);
walk->commits = git_oidmap_alloc(); if (git_oidmap_new(&walk->commits) < 0)
GIT_ERROR_CHECK_ALLOC(walk->commits); return -1;
if (git_pqueue_init(&walk->iterator_time, 0, 8, git_commit_list_time_cmp) < 0) if (git_pqueue_init(&walk->iterator_time, 0, 8, git_commit_list_time_cmp) < 0)
return -1; return -1;
......
...@@ -28,7 +28,7 @@ int git_sortedcache_new( ...@@ -28,7 +28,7 @@ int git_sortedcache_new(
git_pool_init(&sc->pool, 1); git_pool_init(&sc->pool, 1);
if (git_vector_init(&sc->items, 4, item_cmp) < 0 || if (git_vector_init(&sc->items, 4, item_cmp) < 0 ||
git_strmap_alloc(&sc->map) < 0) git_strmap_new(&sc->map) < 0)
goto fail; goto fail;
if (git_rwlock_init(&sc->lock)) { if (git_rwlock_init(&sc->lock)) {
...@@ -270,17 +270,13 @@ int git_sortedcache_clear(git_sortedcache *sc, bool wlock) ...@@ -270,17 +270,13 @@ int git_sortedcache_clear(git_sortedcache *sc, bool wlock)
/* find and/or insert item, returning pointer to item data */ /* find and/or insert item, returning pointer to item data */
int git_sortedcache_upsert(void **out, git_sortedcache *sc, const char *key) int git_sortedcache_upsert(void **out, git_sortedcache *sc, const char *key)
{ {
size_t pos;
int error = 0;
void *item;
size_t keylen, itemlen; size_t keylen, itemlen;
int error = 0;
char *item_key; char *item_key;
void *item;
pos = git_strmap_lookup_index(sc->map, key); if ((item = git_strmap_get(sc->map, key)) != NULL)
if (git_strmap_valid_index(sc->map, pos)) {
item = git_strmap_value_at(sc->map, pos);
goto done; goto done;
}
keylen = strlen(key); keylen = strlen(key);
itemlen = sc->item_path_offset + keylen + 1; itemlen = sc->item_path_offset + keylen + 1;
...@@ -299,17 +295,11 @@ int git_sortedcache_upsert(void **out, git_sortedcache *sc, const char *key) ...@@ -299,17 +295,11 @@ int git_sortedcache_upsert(void **out, git_sortedcache *sc, const char *key)
item_key = ((char *)item) + sc->item_path_offset; item_key = ((char *)item) + sc->item_path_offset;
memcpy(item_key, key, keylen); memcpy(item_key, key, keylen);
pos = git_strmap_put(sc->map, item_key, &error); if ((error = git_strmap_set(sc->map, item_key, item)) < 0)
if (error < 0)
goto done; goto done;
if (!error) if ((error = git_vector_insert(&sc->items, item)) < 0)
git_strmap_set_key_at(sc->map, pos, item_key); git_strmap_delete(sc->map, item_key);
git_strmap_set_value_at(sc->map, pos, item);
error = git_vector_insert(&sc->items, item);
if (error < 0)
git_strmap_delete_at(sc->map, pos);
done: done:
if (out) if (out)
...@@ -320,10 +310,7 @@ done: ...@@ -320,10 +310,7 @@ done:
/* lookup item by key */ /* lookup item by key */
void *git_sortedcache_lookup(const git_sortedcache *sc, const char *key) void *git_sortedcache_lookup(const git_sortedcache *sc, const char *key)
{ {
size_t pos = git_strmap_lookup_index(sc->map, key); return git_strmap_get(sc->map, key);
if (git_strmap_valid_index(sc->map, pos))
return git_strmap_value_at(sc->map, pos);
return NULL;
} }
/* find out how many items are in the cache */ /* find out how many items are in the cache */
...@@ -371,9 +358,9 @@ int git_sortedcache_lookup_index( ...@@ -371,9 +358,9 @@ int git_sortedcache_lookup_index(
int git_sortedcache_remove(git_sortedcache *sc, size_t pos) int git_sortedcache_remove(git_sortedcache *sc, size_t pos)
{ {
char *item; char *item;
size_t mappos;
/* because of pool allocation, this can't actually remove the item, /*
* Because of pool allocation, this can't actually remove the item,
* but we can remove it from the items vector and the hash table. * but we can remove it from the items vector and the hash table.
*/ */
...@@ -384,8 +371,7 @@ int git_sortedcache_remove(git_sortedcache *sc, size_t pos) ...@@ -384,8 +371,7 @@ int git_sortedcache_remove(git_sortedcache *sc, size_t pos)
(void)git_vector_remove(&sc->items, pos); (void)git_vector_remove(&sc->items, pos);
mappos = git_strmap_lookup_index(sc->map, item + sc->item_path_offset); git_strmap_delete(sc->map, item + sc->item_path_offset);
git_strmap_delete_at(sc->map, mappos);
if (sc->free_item) if (sc->free_item)
sc->free_item(sc->free_item_payload, item); sc->free_item(sc->free_item_payload, item);
......
...@@ -18,12 +18,10 @@ __KHASH_TYPE(str, const char *, void *) ...@@ -18,12 +18,10 @@ __KHASH_TYPE(str, const char *, void *)
__KHASH_IMPL(str, static kh_inline, const char *, void *, 1, kh_str_hash_func, kh_str_hash_equal) __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) int git_strmap_new(git_strmap **out)
{ {
if ((*map = kh_init(str)) == NULL) { *out = kh_init(str);
git_error_set_oom(); GIT_ERROR_CHECK_ALLOC(*out);
return -1;
}
return 0; return 0;
} }
...@@ -38,110 +36,65 @@ void git_strmap_clear(git_strmap *map) ...@@ -38,110 +36,65 @@ void git_strmap_clear(git_strmap *map)
kh_clear(str, map); kh_clear(str, map);
} }
size_t git_strmap_num_entries(git_strmap *map) size_t git_strmap_size(git_strmap *map)
{ {
return kh_size(map); return kh_size(map);
} }
size_t git_strmap_lookup_index(git_strmap *map, const char *key) void *git_strmap_get(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)
{ {
size_t idx = kh_get(str, map, key);
if (idx == kh_end(map) || !kh_exist(map, idx))
return NULL;
return kh_val(map, idx); return kh_val(map, idx);
} }
void git_strmap_set_value_at(git_strmap *map, size_t idx, void *value) int git_strmap_set(git_strmap *map, const char *key, void *value)
{
kh_val(map, idx) = value;
}
void git_strmap_delete_at(git_strmap *map, size_t idx)
{ {
kh_del(str, map, idx); size_t idx;
} int rval;
int git_strmap_put(git_strmap *map, const char *key, int *err) idx = kh_put(str, map, key, &rval);
{ if (rval < 0)
return kh_put(str, map, key, err); return -1;
}
void git_strmap_insert(git_strmap *map, const char *key, void *value, int *rval) if (rval == 0)
{ kh_key(map, idx) = key;
khiter_t idx = kh_put(str, map, key, rval);
if ((*rval) >= 0) { kh_val(map, idx) = value;
if ((*rval) == 0)
kh_key(map, idx) = key;
kh_val(map, idx) = value;
}
}
void git_strmap_delete(git_strmap *map, const char *key) return 0;
{
khiter_t idx = git_strmap_lookup_index(map, key);
if (git_strmap_valid_index(map, idx))
git_strmap_delete_at(map, idx);
} }
size_t git_strmap_begin(git_strmap *map) int git_strmap_delete(git_strmap *map, const char *key)
{ {
GIT_UNUSED(map); khiter_t idx = kh_get(str, map, key);
if (idx == kh_end(map))
return GIT_ENOTFOUND;
kh_del(str, map, idx);
return 0; return 0;
} }
size_t git_strmap_end(git_strmap *map) int git_strmap_exists(git_strmap *map, const char *key)
{ {
return map->n_buckets; return kh_get(str, map, key) != kh_end(map);
} }
int git_strmap_next( int git_strmap_iterate(void **value, git_strmap *map, size_t *iter, const char **key)
void **data,
size_t* iter,
git_strmap *map)
{ {
if (!map) size_t i = *iter;
return GIT_ERROR;
while (*iter != git_strmap_end(map)) { while (i < map->n_buckets && !kh_exist(map, i))
if (!(git_strmap_has_data(map, *iter))) { i++;
++(*iter);
continue;
}
*data = git_strmap_value_at(map, *iter); if (i >= map->n_buckets)
return GIT_ITEROVER;
++(*iter); if (key)
*key = kh_key(map, i);
if (value)
*value = kh_val(map, i);
*iter = ++i;
return GIT_OK; return 0;
}
return GIT_ITEROVER;
} }
...@@ -9,51 +9,123 @@ ...@@ -9,51 +9,123 @@
#include "common.h" #include "common.h"
/** A map with C strings as key. */
typedef struct kh_str_s git_strmap; typedef struct kh_str_s git_strmap;
int git_strmap_alloc(git_strmap **map); /**
* Allocate a new string map.
*
* @param out Pointer to the map that shall be allocated.
* @return 0 on success, an error code if allocation has failed.
*/
int git_strmap_new(git_strmap **out);
/**
* Free memory associated with the map.
*
* Note that this function will _not_ free keys or values added
* to this map.
*
* @param map Pointer to the map that is to be free'd. May be
* `NULL`.
*/
void git_strmap_free(git_strmap *map); void git_strmap_free(git_strmap *map);
/**
* Clear all entries from the map.
*
* This function will remove all entries from the associated map.
* Memory associated with it will not be released, though.
*
* @param map Pointer to the map that shall be cleared. May be
* `NULL`.
*/
void git_strmap_clear(git_strmap *map); void git_strmap_clear(git_strmap *map);
size_t git_strmap_num_entries(git_strmap *map); /**
* Return the number of elements in the map.
*
* @parameter map map containing the elements
* @return number of elements in the map
*/
size_t git_strmap_size(git_strmap *map);
size_t git_strmap_lookup_index(git_strmap *map, const char *key); /**
int git_strmap_valid_index(git_strmap *map, size_t idx); * Return value associated with the given key.
*
* @param map map to search key in
* @param key key to search for
* @return value associated with the given key or NULL if the key was not found
*/
void *git_strmap_get(git_strmap *map, const char *key);
/**
* Set the entry for key to value.
*
* If the map has no corresponding entry for the given key, a new
* entry will be created with the given value. If an entry exists
* already, its value will be updated to match the given value.
*
* @param map map to create new entry in
* @param key key to set
* @param value value to associate the key with; may be NULL
* @return zero if the key was successfully set, a negative error
* code otherwise
*/
int git_strmap_set(git_strmap *map, const char *key, void *value);
/**
* Delete an entry from the map.
*
* Delete the given key and its value from the map. If no such
* key exists, this will do nothing.
*
* @param map map to delete key in
* @param key key to delete
* @return `0` if the key has been deleted, GIT_ENOTFOUND if no
* such key was found, a negative code in case of an
* error
*/
int git_strmap_delete(git_strmap *map, const char *key);
/**
* Check whether a key exists in the given map.
*
* @param map map to query for the key
* @param key key to search for
* @return 0 if the key has not been found, 1 otherwise
*/
int git_strmap_exists(git_strmap *map, const char *key); int git_strmap_exists(git_strmap *map, const char *key);
int git_strmap_has_data(git_strmap *map, size_t idx);
/**
const char *git_strmap_key(git_strmap *map, size_t idx); * Iterate over entries of the map.
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); * This functions allows to iterate over all key-value entries of
void git_strmap_set_value_at(git_strmap *map, size_t idx, void *value); * the map. The current position is stored in the `iter` variable
void git_strmap_delete_at(git_strmap *map, size_t idx); * and should be initialized to `0` before the first call to this
* function.
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); * @param map map to iterate over
void git_strmap_delete(git_strmap *map, const char *key); * @param value pointer to the variable where to store the current
* value. May be NULL.
#define git_strmap_foreach(h, kvar, vvar, code) { size_t __i; \ * @param iter iterator storing the current position. Initialize
for (__i = git_strmap_begin(h); __i != git_strmap_end(h); ++__i) { \ * with zero previous to the first call.
if (!git_strmap_has_data(h,__i)) continue; \ * @param key pointer to the variable where to store the current
(kvar) = git_strmap_key(h,__i); \ * key. May be NULL.
(vvar) = git_strmap_value_at(h,__i); \ * @return `0` if the next entry was correctly retrieved.
* GIT_ITEROVER if no entries are left. A negative error
* code otherwise.
*/
int git_strmap_iterate(void **value, git_strmap *map, size_t *iter, const char **key);
#define git_strmap_foreach(h, kvar, vvar, code) { size_t __i = 0; \
while (git_strmap_iterate((void **) &(vvar), h, &__i, &(kvar)) == 0) { \
code; \ code; \
} } } }
#define git_strmap_foreach_value(h, vvar, code) { size_t __i; \ #define git_strmap_foreach_value(h, vvar, code) { size_t __i = 0; \
for (__i = git_strmap_begin(h); __i != git_strmap_end(h); ++__i) { \ while (git_strmap_iterate((void **) &(vvar), h, &__i, NULL) == 0) { \
if (!git_strmap_has_data(h,__i)) continue; \
(vvar) = git_strmap_value_at(h,__i); \
code; \ code; \
} } } }
size_t git_strmap_begin(git_strmap *map);
size_t git_strmap_end(git_strmap *map);
int git_strmap_next(
void **data,
size_t *iter,
git_strmap *map);
#endif #endif
...@@ -197,12 +197,11 @@ static int load_submodule_names(git_strmap **out, git_repository *repo, git_conf ...@@ -197,12 +197,11 @@ static int load_submodule_names(git_strmap **out, git_repository *repo, git_conf
git_config_entry *entry; git_config_entry *entry;
git_buf buf = GIT_BUF_INIT; git_buf buf = GIT_BUF_INIT;
git_strmap *names; git_strmap *names;
int rval, isvalid; int isvalid, error;
int error = 0;
*out = NULL; *out = NULL;
if ((error = git_strmap_alloc(&names)) < 0) if ((error = git_strmap_new(&names)) < 0)
goto out; goto out;
if ((error = git_config_iterator_glob_new(&iter, cfg, key)) < 0) if ((error = git_config_iterator_glob_new(&iter, cfg, key)) < 0)
...@@ -230,8 +229,7 @@ static int load_submodule_names(git_strmap **out, git_repository *repo, git_conf ...@@ -230,8 +229,7 @@ static int load_submodule_names(git_strmap **out, git_repository *repo, git_conf
if (!isvalid) if (!isvalid)
continue; continue;
git_strmap_insert(names, git__strdup(entry->value), git_buf_detach(&buf), &rval); if ((error = git_strmap_set(names, git__strdup(entry->value), git_buf_detach(&buf))) < 0) {
if (rval < 0) {
git_error_set(GIT_ERROR_NOMEMORY, "error inserting submodule into hash table"); git_error_set(GIT_ERROR_NOMEMORY, "error inserting submodule into hash table");
error = -1; error = -1;
goto out; goto out;
...@@ -267,10 +265,9 @@ int git_submodule_lookup( ...@@ -267,10 +265,9 @@ int git_submodule_lookup(
} }
if (repo->submodule_cache != NULL) { if (repo->submodule_cache != NULL) {
size_t pos = git_strmap_lookup_index(repo->submodule_cache, name); if ((sm = git_strmap_get(repo->submodule_cache, name)) != NULL) {
if (git_strmap_valid_index(repo->submodule_cache, pos)) {
if (out) { if (out) {
*out = git_strmap_value_at(repo->submodule_cache, pos); *out = sm;
GIT_REFCOUNT_INC(*out); GIT_REFCOUNT_INC(*out);
} }
return 0; return 0;
...@@ -395,30 +392,21 @@ static void submodule_free_dup(void *sm) ...@@ -395,30 +392,21 @@ static void submodule_free_dup(void *sm)
static int submodule_get_or_create(git_submodule **out, git_repository *repo, git_strmap *map, const char *name) static int submodule_get_or_create(git_submodule **out, git_repository *repo, git_strmap *map, const char *name)
{ {
int error = 0;
size_t pos;
git_submodule *sm = NULL; git_submodule *sm = NULL;
int error;
pos = git_strmap_lookup_index(map, name); if ((sm = git_strmap_get(map, name)) != NULL)
if (git_strmap_valid_index(map, pos)) {
sm = git_strmap_value_at(map, pos);
goto done; goto done;
}
/* if the submodule doesn't exist yet in the map, create it */ /* if the submodule doesn't exist yet in the map, create it */
if ((error = submodule_alloc(&sm, repo, name)) < 0) if ((error = submodule_alloc(&sm, repo, name)) < 0)
return error; return error;
pos = git_strmap_put(map, sm->name, &error); if ((error = git_strmap_set(map, sm->name, sm)) < 0) {
/* nobody can beat us to adding it */
assert(error != 0);
if (error < 0) {
git_submodule_free(sm); git_submodule_free(sm);
return error; return error;
} }
git_strmap_set_value_at(map, pos, sm);
done: done:
GIT_REFCOUNT_INC(sm); GIT_REFCOUNT_INC(sm);
*out = sm; *out = sm;
...@@ -439,26 +427,18 @@ static int submodules_from_index(git_strmap *map, git_index *idx, git_config *cf ...@@ -439,26 +427,18 @@ static int submodules_from_index(git_strmap *map, git_index *idx, git_config *cf
goto done; goto done;
while (!(error = git_iterator_advance(&entry, i))) { while (!(error = git_iterator_advance(&entry, i))) {
size_t pos = git_strmap_lookup_index(map, entry->path);
git_submodule *sm; git_submodule *sm;
if (git_strmap_valid_index(map, pos)) { if ((sm = git_strmap_get(map, entry->path)) != NULL) {
sm = git_strmap_value_at(map, pos);
if (S_ISGITLINK(entry->mode)) if (S_ISGITLINK(entry->mode))
submodule_update_from_index_entry(sm, entry); submodule_update_from_index_entry(sm, entry);
else else
sm->flags |= GIT_SUBMODULE_STATUS__INDEX_NOT_SUBMODULE; sm->flags |= GIT_SUBMODULE_STATUS__INDEX_NOT_SUBMODULE;
} else if (S_ISGITLINK(entry->mode)) { } else if (S_ISGITLINK(entry->mode)) {
size_t name_pos;
const char *name; const char *name;
name_pos = git_strmap_lookup_index(names, entry->path); if ((name = git_strmap_get(names, entry->path)) == NULL)
if (git_strmap_valid_index(names, name_pos)) {
name = git_strmap_value_at(names, name_pos);
} else {
name = entry->path; name = entry->path;
}
if (!submodule_get_or_create(&sm, git_index_owner(idx), map, name)) { if (!submodule_get_or_create(&sm, git_index_owner(idx), map, name)) {
submodule_update_from_index_entry(sm, entry); submodule_update_from_index_entry(sm, entry);
...@@ -491,26 +471,18 @@ static int submodules_from_head(git_strmap *map, git_tree *head, git_config *cfg ...@@ -491,26 +471,18 @@ static int submodules_from_head(git_strmap *map, git_tree *head, git_config *cfg
goto done; goto done;
while (!(error = git_iterator_advance(&entry, i))) { while (!(error = git_iterator_advance(&entry, i))) {
size_t pos = git_strmap_lookup_index(map, entry->path);
git_submodule *sm; git_submodule *sm;
if (git_strmap_valid_index(map, pos)) { if ((sm = git_strmap_get(map, entry->path)) != NULL) {
sm = git_strmap_value_at(map, pos);
if (S_ISGITLINK(entry->mode)) if (S_ISGITLINK(entry->mode))
submodule_update_from_head_data(sm, entry->mode, &entry->id); submodule_update_from_head_data(sm, entry->mode, &entry->id);
else else
sm->flags |= GIT_SUBMODULE_STATUS__HEAD_NOT_SUBMODULE; sm->flags |= GIT_SUBMODULE_STATUS__HEAD_NOT_SUBMODULE;
} else if (S_ISGITLINK(entry->mode)) { } else if (S_ISGITLINK(entry->mode)) {
size_t name_pos;
const char *name; const char *name;
name_pos = git_strmap_lookup_index(names, entry->path); if ((name = git_strmap_get(names, entry->path)) == NULL)
if (git_strmap_valid_index(names, name_pos)) {
name = git_strmap_value_at(names, name_pos);
} else {
name = entry->path; name = entry->path;
}
if (!submodule_get_or_create(&sm, git_tree_owner(head), map, name)) { if (!submodule_get_or_create(&sm, git_tree_owner(head), map, name)) {
submodule_update_from_head_data( submodule_update_from_head_data(
...@@ -618,14 +590,14 @@ int git_submodule_foreach( ...@@ -618,14 +590,14 @@ int git_submodule_foreach(
return -1; return -1;
} }
if ((error = git_strmap_alloc(&submodules)) < 0) if ((error = git_strmap_new(&submodules)) < 0)
return error; return error;
if ((error = git_submodule__map(repo, submodules)) < 0) if ((error = git_submodule__map(repo, submodules)) < 0)
goto done; goto done;
if (!(error = git_vector_init( if (!(error = git_vector_init(
&snapshot, git_strmap_num_entries(submodules), submodule_cmp))) { &snapshot, git_strmap_size(submodules), submodule_cmp))) {
git_strmap_foreach_value(submodules, sm, { git_strmap_foreach_value(submodules, sm, {
if ((error = git_vector_insert(&snapshot, sm)) < 0) if ((error = git_vector_insert(&snapshot, sm)) < 0)
...@@ -1935,7 +1907,6 @@ static int submodule_load_each(const git_config_entry *entry, void *payload) ...@@ -1935,7 +1907,6 @@ static int submodule_load_each(const git_config_entry *entry, void *payload)
{ {
lfc_data *data = payload; lfc_data *data = payload;
const char *namestart, *property; const char *namestart, *property;
size_t pos;
git_strmap *map = data->map; git_strmap *map = data->map;
git_buf name = GIT_BUF_INIT; git_buf name = GIT_BUF_INIT;
git_submodule *sm; git_submodule *sm;
...@@ -1967,8 +1938,7 @@ static int submodule_load_each(const git_config_entry *entry, void *payload) ...@@ -1967,8 +1938,7 @@ static int submodule_load_each(const git_config_entry *entry, void *payload)
* a new submodule, load the config and insert it. If it's * a new submodule, load the config and insert it. If it's
* already inserted, we've already loaded it, so we skip. * already inserted, we've already loaded it, so we skip.
*/ */
pos = git_strmap_lookup_index(map, name.ptr); if (git_strmap_exists(map, name.ptr)) {
if (git_strmap_valid_index(map, pos)) {
error = 0; error = 0;
goto done; goto done;
} }
...@@ -1981,9 +1951,7 @@ static int submodule_load_each(const git_config_entry *entry, void *payload) ...@@ -1981,9 +1951,7 @@ static int submodule_load_each(const git_config_entry *entry, void *payload)
goto done; goto done;
} }
git_strmap_insert(map, sm->name, sm, &error); if ((error = git_strmap_set(map, sm->name, sm)) < 0)
assert(error != 0);
if (error < 0)
goto done; goto done;
error = 0; error = 0;
......
...@@ -84,7 +84,7 @@ int git_transaction_new(git_transaction **out, git_repository *repo) ...@@ -84,7 +84,7 @@ int git_transaction_new(git_transaction **out, git_repository *repo)
goto on_error; goto on_error;
} }
if ((error = git_strmap_alloc(&tx->locks)) < 0) { if ((error = git_strmap_new(&tx->locks)) < 0) {
error = -1; error = -1;
goto on_error; goto on_error;
} }
...@@ -119,8 +119,7 @@ int git_transaction_lock_ref(git_transaction *tx, const char *refname) ...@@ -119,8 +119,7 @@ int git_transaction_lock_ref(git_transaction *tx, const char *refname)
if ((error = git_refdb_lock(&node->payload, tx->db, refname)) < 0) if ((error = git_refdb_lock(&node->payload, tx->db, refname)) < 0)
return error; return error;
git_strmap_insert(tx->locks, node->name, node, &error); if ((error = git_strmap_set(tx->locks, node->name, node)) < 0)
if (error < 0)
goto cleanup; goto cleanup;
return 0; return 0;
...@@ -134,16 +133,12 @@ cleanup: ...@@ -134,16 +133,12 @@ cleanup:
static int find_locked(transaction_node **out, git_transaction *tx, const char *refname) static int find_locked(transaction_node **out, git_transaction *tx, const char *refname)
{ {
transaction_node *node; transaction_node *node;
size_t pos;
pos = git_strmap_lookup_index(tx->locks, refname); if ((node = git_strmap_get(tx->locks, refname)) == NULL) {
if (!git_strmap_valid_index(tx->locks, pos)) {
git_error_set(GIT_ERROR_REFERENCE, "the specified reference is not locked"); git_error_set(GIT_ERROR_REFERENCE, "the specified reference is not locked");
return GIT_ENOTFOUND; return GIT_ENOTFOUND;
} }
node = git_strmap_value_at(tx->locks, pos);
*out = node; *out = node;
return 0; return 0;
} }
......
...@@ -344,7 +344,7 @@ unsigned int git_treebuilder_entrycount(git_treebuilder *bld) ...@@ -344,7 +344,7 @@ unsigned int git_treebuilder_entrycount(git_treebuilder *bld)
{ {
assert(bld); assert(bld);
return git_strmap_num_entries(bld->map); return git_strmap_size(bld->map);
} }
static int tree_error(const char *str, const char *path) static int tree_error(const char *str, const char *path)
...@@ -507,8 +507,7 @@ static int append_entry( ...@@ -507,8 +507,7 @@ static int append_entry(
entry->attr = (uint16_t)filemode; entry->attr = (uint16_t)filemode;
git_strmap_insert(bld->map, entry->filename, entry, &error); if ((error = git_strmap_set(bld->map, entry->filename, entry)) < 0) {
if (error < 0) {
git_tree_entry_free(entry); git_tree_entry_free(entry);
git_error_set(GIT_ERROR_TREE, "failed to append entry %s to the tree builder", filename); git_error_set(GIT_ERROR_TREE, "failed to append entry %s to the tree builder", filename);
return -1; return -1;
...@@ -688,7 +687,7 @@ int git_treebuilder_new( ...@@ -688,7 +687,7 @@ int git_treebuilder_new(
bld->repo = repo; bld->repo = repo;
if (git_strmap_alloc(&bld->map) < 0) { if (git_strmap_new(&bld->map) < 0) {
git__free(bld); git__free(bld);
return -1; return -1;
} }
...@@ -723,24 +722,19 @@ int git_treebuilder_insert( ...@@ -723,24 +722,19 @@ int git_treebuilder_insert(
{ {
git_tree_entry *entry; git_tree_entry *entry;
int error; int error;
size_t pos;
assert(bld && id && filename); assert(bld && id && filename);
if ((error = check_entry(bld->repo, filename, id, filemode)) < 0) if ((error = check_entry(bld->repo, filename, id, filemode)) < 0)
return error; return error;
pos = git_strmap_lookup_index(bld->map, filename); if ((entry = git_strmap_get(bld->map, filename)) != NULL) {
if (git_strmap_valid_index(bld->map, pos)) {
entry = git_strmap_value_at(bld->map, pos);
git_oid_cpy((git_oid *) entry->oid, id); git_oid_cpy((git_oid *) entry->oid, id);
} else { } else {
entry = alloc_entry(filename, strlen(filename), id); entry = alloc_entry(filename, strlen(filename), id);
GIT_ERROR_CHECK_ALLOC(entry); GIT_ERROR_CHECK_ALLOC(entry);
git_strmap_insert(bld->map, entry->filename, entry, &error); if ((error = git_strmap_set(bld->map, entry->filename, entry)) < 0) {
if (error < 0) {
git_tree_entry_free(entry); git_tree_entry_free(entry);
git_error_set(GIT_ERROR_TREE, "failed to insert %s", filename); git_error_set(GIT_ERROR_TREE, "failed to insert %s", filename);
return -1; return -1;
...@@ -757,16 +751,8 @@ int git_treebuilder_insert( ...@@ -757,16 +751,8 @@ int git_treebuilder_insert(
static git_tree_entry *treebuilder_get(git_treebuilder *bld, const char *filename) static git_tree_entry *treebuilder_get(git_treebuilder *bld, const char *filename)
{ {
git_tree_entry *entry = NULL;
size_t pos;
assert(bld && filename); assert(bld && filename);
return git_strmap_get(bld->map, filename);
pos = git_strmap_lookup_index(bld->map, filename);
if (git_strmap_valid_index(bld->map, pos))
entry = git_strmap_value_at(bld->map, pos);
return entry;
} }
const git_tree_entry *git_treebuilder_get(git_treebuilder *bld, const char *filename) const git_tree_entry *git_treebuilder_get(git_treebuilder *bld, const char *filename)
...@@ -811,7 +797,7 @@ int git_treebuilder_write_with_buffer(git_oid *oid, git_treebuilder *bld, git_bu ...@@ -811,7 +797,7 @@ int git_treebuilder_write_with_buffer(git_oid *oid, git_treebuilder *bld, git_bu
git_buf_clear(tree); git_buf_clear(tree);
entrycount = git_strmap_num_entries(bld->map); entrycount = git_strmap_size(bld->map);
if ((error = git_vector_init(&entries, entrycount, entry_sort_cmp)) < 0) if ((error = git_vector_init(&entries, entrycount, entry_sort_cmp)) < 0)
goto out; goto out;
......
#include "clar_libgit2.h" #include "clar_libgit2.h"
#include "oidmap.h" #include "oidmap.h"
typedef struct { static struct {
git_oid oid; git_oid oid;
size_t extra; size_t extra;
} oidmap_item; } test_oids[0x0FFF];
#define NITEMS 0x0fff static git_oidmap *g_map;
void test_core_oidmap__basic(void) void test_core_oidmap__initialize(void)
{ {
git_oidmap *map;
oidmap_item items[NITEMS];
uint32_t i, j; uint32_t i, j;
for (i = 0; i < ARRAY_SIZE(test_oids); ++i) {
uint32_t segment = i / 8;
int modi = i - (segment * 8);
test_oids[i].extra = i;
for (i = 0; i < NITEMS; ++i) {
items[i].extra = i;
for (j = 0; j < GIT_OID_RAWSZ / 4; ++j) { for (j = 0; j < GIT_OID_RAWSZ / 4; ++j) {
items[i].oid.id[j * 4 ] = (unsigned char)i; test_oids[i].oid.id[j * 4 ] = (unsigned char)modi;
items[i].oid.id[j * 4 + 1] = (unsigned char)(i >> 8); test_oids[i].oid.id[j * 4 + 1] = (unsigned char)(modi >> 8);
items[i].oid.id[j * 4 + 2] = (unsigned char)(i >> 16); test_oids[i].oid.id[j * 4 + 2] = (unsigned char)(modi >> 16);
items[i].oid.id[j * 4 + 3] = (unsigned char)(i >> 24); test_oids[i].oid.id[j * 4 + 3] = (unsigned char)(modi >> 24);
} }
}
map = git_oidmap_alloc();
cl_assert(map != NULL);
for (i = 0; i < NITEMS; ++i) {
size_t pos;
int ret;
pos = git_oidmap_lookup_index(map, &items[i].oid);
cl_assert(!git_oidmap_valid_index(map, pos));
pos = git_oidmap_put(map, &items[i].oid, &ret);
cl_assert(ret != 0);
git_oidmap_set_value_at(map, pos, &items[i]); test_oids[i].oid.id[ 8] = (unsigned char)i;
test_oids[i].oid.id[ 9] = (unsigned char)(i >> 8);
test_oids[i].oid.id[10] = (unsigned char)(i >> 16);
test_oids[i].oid.id[11] = (unsigned char)(i >> 24);
} }
cl_git_pass(git_oidmap_new(&g_map));
}
for (i = 0; i < NITEMS; ++i) { void test_core_oidmap__cleanup(void)
size_t pos; {
git_oidmap_free(g_map);
}
pos = git_oidmap_lookup_index(map, &items[i].oid); void test_core_oidmap__basic(void)
cl_assert(git_oidmap_valid_index(map, pos)); {
size_t i;
cl_assert_equal_p(git_oidmap_value_at(map, pos), &items[i]); for (i = 0; i < ARRAY_SIZE(test_oids); ++i) {
cl_assert(!git_oidmap_exists(g_map, &test_oids[i].oid));
cl_git_pass(git_oidmap_set(g_map, &test_oids[i].oid, &test_oids[i]));
} }
git_oidmap_free(map); for (i = 0; i < ARRAY_SIZE(test_oids); ++i) {
cl_assert(git_oidmap_exists(g_map, &test_oids[i].oid));
cl_assert_equal_p(git_oidmap_get(g_map, &test_oids[i].oid), &test_oids[i]);
}
} }
void test_core_oidmap__hash_collision(void) void test_core_oidmap__hash_collision(void)
{ {
git_oidmap *map; size_t i;
oidmap_item items[NITEMS];
uint32_t i, j;
for (i = 0; i < NITEMS; ++i) {
uint32_t segment = i / 8;
int modi = i - (segment * 8);
items[i].extra = i;
for (j = 0; j < GIT_OID_RAWSZ / 4; ++j) { for (i = 0; i < ARRAY_SIZE(test_oids); ++i) {
items[i].oid.id[j * 4 ] = (unsigned char)modi; cl_assert(!git_oidmap_exists(g_map, &test_oids[i].oid));
items[i].oid.id[j * 4 + 1] = (unsigned char)(modi >> 8); cl_git_pass(git_oidmap_set(g_map, &test_oids[i].oid, &test_oids[i]));
items[i].oid.id[j * 4 + 2] = (unsigned char)(modi >> 16); }
items[i].oid.id[j * 4 + 3] = (unsigned char)(modi >> 24);
}
items[i].oid.id[ 8] = (unsigned char)i; for (i = 0; i < ARRAY_SIZE(test_oids); ++i) {
items[i].oid.id[ 9] = (unsigned char)(i >> 8); cl_assert(git_oidmap_exists(g_map, &test_oids[i].oid));
items[i].oid.id[10] = (unsigned char)(i >> 16); cl_assert_equal_p(git_oidmap_get(g_map, &test_oids[i].oid), &test_oids[i]);
items[i].oid.id[11] = (unsigned char)(i >> 24);
} }
}
map = git_oidmap_alloc(); void test_core_oidmap__get_succeeds_with_existing_keys(void)
cl_assert(map != NULL); {
size_t i;
for (i = 0; i < NITEMS; ++i) { for (i = 0; i < ARRAY_SIZE(test_oids); ++i)
size_t pos; cl_git_pass(git_oidmap_set(g_map, &test_oids[i].oid, &test_oids[i]));
int ret;
pos = git_oidmap_lookup_index(map, &items[i].oid); for (i = 0; i < ARRAY_SIZE(test_oids); ++i)
cl_assert(!git_oidmap_valid_index(map, pos)); cl_assert_equal_p(git_oidmap_get(g_map, &test_oids[i].oid), &test_oids[i]);
}
pos = git_oidmap_put(map, &items[i].oid, &ret); void test_core_oidmap__get_fails_with_nonexisting_key(void)
cl_assert(ret != 0); {
size_t i;
git_oidmap_set_value_at(map, pos, &items[i]); /* Do _not_ add last OID to verify that we cannot look it up */
} for (i = 0; i < ARRAY_SIZE(test_oids) - 1; ++i)
cl_git_pass(git_oidmap_set(g_map, &test_oids[i].oid, &test_oids[i]));
cl_assert_equal_p(git_oidmap_get(g_map, &test_oids[ARRAY_SIZE(test_oids) - 1].oid), NULL);
}
void test_core_oidmap__setting_oid_persists(void)
{
git_oid oids[] = {
{{ 0x01 }},
{{ 0x02 }},
{{ 0x03 }}
};
cl_git_pass(git_oidmap_set(g_map, &oids[0], "one"));
cl_git_pass(git_oidmap_set(g_map, &oids[1], "two"));
cl_git_pass(git_oidmap_set(g_map, &oids[2], "three"));
cl_assert_equal_s(git_oidmap_get(g_map, &oids[0]), "one");
cl_assert_equal_s(git_oidmap_get(g_map, &oids[1]), "two");
cl_assert_equal_s(git_oidmap_get(g_map, &oids[2]), "three");
}
for (i = 0; i < NITEMS; ++i) { void test_core_oidmap__setting_existing_key_updates(void)
size_t pos; {
git_oid oids[] = {
{{ 0x01 }},
{{ 0x02 }},
{{ 0x03 }}
};
pos = git_oidmap_lookup_index(map, &items[i].oid); cl_git_pass(git_oidmap_set(g_map, &oids[0], "one"));
cl_assert(git_oidmap_valid_index(map, pos)); cl_git_pass(git_oidmap_set(g_map, &oids[1], "two"));
cl_git_pass(git_oidmap_set(g_map, &oids[2], "three"));
cl_assert_equal_i(git_oidmap_size(g_map), 3);
cl_assert_equal_p(git_oidmap_value_at(map, pos), &items[i]); cl_git_pass(git_oidmap_set(g_map, &oids[1], "other"));
} cl_assert_equal_i(git_oidmap_size(g_map), 3);
git_oidmap_free(map); cl_assert_equal_s(git_oidmap_get(g_map, &oids[1]), "other");
} }
#include "clar_libgit2.h" #include "clar_libgit2.h"
#include "strmap.h" #include "strmap.h"
git_strmap *g_table; static git_strmap *g_table;
void test_core_strmap__initialize(void) void test_core_strmap__initialize(void)
{ {
cl_git_pass(git_strmap_alloc(&g_table)); cl_git_pass(git_strmap_new(&g_table));
cl_assert(g_table != NULL); cl_assert(g_table != NULL);
} }
...@@ -16,12 +16,12 @@ void test_core_strmap__cleanup(void) ...@@ -16,12 +16,12 @@ void test_core_strmap__cleanup(void)
void test_core_strmap__0(void) void test_core_strmap__0(void)
{ {
cl_assert(git_strmap_num_entries(g_table) == 0); cl_assert(git_strmap_size(g_table) == 0);
} }
static void insert_strings(git_strmap *table, int count) static void insert_strings(git_strmap *table, size_t count)
{ {
int i, j, over, err; size_t i, j, over;
char *str; char *str;
for (i = 0; i < count; ++i) { for (i = 0; i < count; ++i) {
...@@ -34,17 +34,16 @@ static void insert_strings(git_strmap *table, int count) ...@@ -34,17 +34,16 @@ static void insert_strings(git_strmap *table, int count)
for (j = 0, over = i / 26; over > 0; j++, over = over / 26) for (j = 0, over = i / 26; over > 0; j++, over = over / 26)
str[j] = 'A' + (over % 26); str[j] = 'A' + (over % 26);
git_strmap_insert(table, str, str, &err); cl_git_pass(git_strmap_set(table, str, str));
cl_assert(err >= 0);
} }
cl_assert((int)git_strmap_num_entries(table) == count); cl_assert_equal_i(git_strmap_size(table), count);
} }
void test_core_strmap__1(void) void test_core_strmap__inserted_strings_can_be_retrieved(void)
{ {
int i;
char *str; char *str;
int i;
insert_strings(g_table, 20); insert_strings(g_table, 20);
...@@ -58,41 +57,134 @@ void test_core_strmap__1(void) ...@@ -58,41 +57,134 @@ void test_core_strmap__1(void)
cl_assert(i == 20); cl_assert(i == 20);
} }
void test_core_strmap__2(void) void test_core_strmap__deleted_entry_cannot_be_retrieved(void)
{ {
size_t pos;
int i;
char *str; char *str;
int i;
insert_strings(g_table, 20); insert_strings(g_table, 20);
cl_assert(git_strmap_exists(g_table, "aaaaaaaaa"));
cl_assert(git_strmap_exists(g_table, "ggggggggg"));
cl_assert(!git_strmap_exists(g_table, "aaaaaaaab"));
cl_assert(!git_strmap_exists(g_table, "abcdefghi"));
cl_assert(git_strmap_exists(g_table, "bbbbbbbbb")); cl_assert(git_strmap_exists(g_table, "bbbbbbbbb"));
pos = git_strmap_lookup_index(g_table, "bbbbbbbbb"); str = git_strmap_get(g_table, "bbbbbbbbb");
cl_assert(git_strmap_valid_index(g_table, pos)); cl_assert_equal_s(str, "bbbbbbbbb");
cl_assert_equal_s(git_strmap_value_at(g_table, pos), "bbbbbbbbb"); cl_git_pass(git_strmap_delete(g_table, "bbbbbbbbb"));
free(git_strmap_value_at(g_table, pos)); free(str);
git_strmap_delete_at(g_table, pos);
cl_assert(!git_strmap_exists(g_table, "bbbbbbbbb")); cl_assert(!git_strmap_exists(g_table, "bbbbbbbbb"));
i = 0; i = 0;
git_strmap_foreach_value(g_table, str, { i++; free(str); }); git_strmap_foreach_value(g_table, str, { i++; free(str); });
cl_assert(i == 19); cl_assert_equal_i(i, 19);
} }
void test_core_strmap__3(void) void test_core_strmap__inserting_many_keys_succeeds(void)
{ {
int i;
char *str; char *str;
int i;
insert_strings(g_table, 10000); insert_strings(g_table, 10000);
i = 0; i = 0;
git_strmap_foreach_value(g_table, str, { i++; free(str); }); git_strmap_foreach_value(g_table, str, { i++; free(str); });
cl_assert(i == 10000); cl_assert_equal_i(i, 10000);
}
void test_core_strmap__get_succeeds_with_existing_entries(void)
{
const char *keys[] = { "foo", "bar", "gobble" };
char *values[] = { "oof", "rab", "elbbog" };
size_t i;
for (i = 0; i < ARRAY_SIZE(keys); i++)
cl_git_pass(git_strmap_set(g_table, keys[i], values[i]));
cl_assert_equal_s(git_strmap_get(g_table, "foo"), "oof");
cl_assert_equal_s(git_strmap_get(g_table, "bar"), "rab");
cl_assert_equal_s(git_strmap_get(g_table, "gobble"), "elbbog");
}
void test_core_strmap__get_returns_null_on_nonexisting_key(void)
{
const char *keys[] = { "foo", "bar", "gobble" };
char *values[] = { "oof", "rab", "elbbog" };
size_t i;
for (i = 0; i < ARRAY_SIZE(keys); i++)
cl_git_pass(git_strmap_set(g_table, keys[i], values[i]));
cl_assert_equal_p(git_strmap_get(g_table, "other"), NULL);
}
void test_core_strmap__set_persists_key(void)
{
cl_git_pass(git_strmap_set(g_table, "foo", "oof"));
cl_assert_equal_s(git_strmap_get(g_table, "foo"), "oof");
}
void test_core_strmap__set_persists_multpile_keys(void)
{
cl_git_pass(git_strmap_set(g_table, "foo", "oof"));
cl_git_pass(git_strmap_set(g_table, "bar", "rab"));
cl_assert_equal_s(git_strmap_get(g_table, "foo"), "oof");
cl_assert_equal_s(git_strmap_get(g_table, "bar"), "rab");
}
void test_core_strmap__set_updates_existing_key(void)
{
cl_git_pass(git_strmap_set(g_table, "foo", "oof"));
cl_git_pass(git_strmap_set(g_table, "bar", "rab"));
cl_git_pass(git_strmap_set(g_table, "gobble", "elbbog"));
cl_assert_equal_i(git_strmap_size(g_table), 3);
cl_git_pass(git_strmap_set(g_table, "foo", "other"));
cl_assert_equal_i(git_strmap_size(g_table), 3);
cl_assert_equal_s(git_strmap_get(g_table, "foo"), "other");
}
void test_core_strmap__iteration(void)
{
struct {
char *key;
char *value;
int seen;
} entries[] = {
{ "foo", "oof" },
{ "bar", "rab" },
{ "gobble", "elbbog" },
};
const char *key, *value;
size_t i, n;
for (i = 0; i < ARRAY_SIZE(entries); i++)
cl_git_pass(git_strmap_set(g_table, entries[i].key, entries[i].value));
i = 0, n = 0;
while (git_strmap_iterate((void **) &value, g_table, &i, &key) == 0) {
size_t j;
for (j = 0; j < ARRAY_SIZE(entries); j++) {
if (strcmp(entries[j].key, key))
continue;
cl_assert_equal_i(entries[j].seen, 0);
cl_assert_equal_s(entries[j].value, value);
entries[j].seen++;
break;
}
n++;
}
for (i = 0; i < ARRAY_SIZE(entries); i++)
cl_assert_equal_i(entries[i].seen, 1);
cl_assert_equal_i(n, ARRAY_SIZE(entries));
}
void test_core_strmap__iterating_empty_map_stops_immediately(void)
{
size_t i = 0;
cl_git_fail_with(git_strmap_iterate(NULL, g_table, &i, NULL), GIT_ITEROVER);
} }
...@@ -24,13 +24,13 @@ void test_pack_sharing__open_two_repos(void) ...@@ -24,13 +24,13 @@ void test_pack_sharing__open_two_repos(void)
cl_git_pass(git_object_lookup(&obj2, repo2, &id, GIT_OBJECT_ANY)); cl_git_pass(git_object_lookup(&obj2, repo2, &id, GIT_OBJECT_ANY));
pos = 0; pos = 0;
while ((error = git_strmap_next(&data, &pos, git__pack_cache)) == 0) { while ((error = git_strmap_iterate(&data, git__pack_cache, &pos, NULL)) == 0) {
struct git_pack_file *pack = (struct git_pack_file *) data; struct git_pack_file *pack = (struct git_pack_file *) data;
cl_assert_equal_i(2, pack->refcount.val); cl_assert_equal_i(2, pack->refcount.val);
} }
cl_assert_equal_i(3, git_strmap_num_entries(git__pack_cache)); cl_assert_equal_i(3, git_strmap_size(git__pack_cache));
git_object_free(obj1); git_object_free(obj1);
git_object_free(obj2); git_object_free(obj2);
...@@ -38,5 +38,5 @@ void test_pack_sharing__open_two_repos(void) ...@@ -38,5 +38,5 @@ void test_pack_sharing__open_two_repos(void)
git_repository_free(repo2); git_repository_free(repo2);
/* we don't want to keep the packs open after the repos go away */ /* we don't want to keep the packs open after the repos go away */
cl_assert_equal_i(0, git_strmap_num_entries(git__pack_cache)); cl_assert_equal_i(0, git_strmap_size(git__pack_cache));
} }
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