summaryrefslogtreecommitdiff
path: root/src/refs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/refs.c')
-rw-r--r--src/refs.c72
1 files changed, 45 insertions, 27 deletions
diff --git a/src/refs.c b/src/refs.c
index 447f3a7b6..7050b4af9 100644
--- a/src/refs.c
+++ b/src/refs.c
@@ -15,6 +15,8 @@
#include <git2/tag.h>
#include <git2/object.h>
+GIT_KHASH_STR__IMPLEMENTATION;
+
#define DEFAULT_NESTING_LEVEL 5
#define MAX_NESTING_LEVEL 10
@@ -30,8 +32,6 @@ struct packref {
char name[GIT_FLEX_ARRAY];
};
-static const int default_table_size = 32;
-
static int reference_read(
git_buf *file_content,
time_t *mtime,
@@ -423,9 +423,7 @@ static int packed_load(git_repository *repo)
/* First we make sure we have allocated the hash table */
if (ref_cache->packfile == NULL) {
- ref_cache->packfile = git_hashtable_alloc(
- default_table_size, git_hash__strhash_cb, git_hash__strcmp_cb);
-
+ ref_cache->packfile = git_khash_str_alloc();
GITERR_CHECK_ALLOC(ref_cache->packfile);
}
@@ -440,7 +438,7 @@ static int packed_load(git_repository *repo)
* refresh the packed refs.
*/
if (result == GIT_ENOTFOUND) {
- git_hashtable_clear(ref_cache->packfile);
+ git_khash_str_clear(ref_cache->packfile);
return 0;
}
@@ -454,7 +452,7 @@ static int packed_load(git_repository *repo)
* At this point, we want to refresh the packed refs. We already
* have the contents in our buffer.
*/
- git_hashtable_clear(ref_cache->packfile);
+ git_khash_str_clear(ref_cache->packfile);
buffer_start = (const char *)packfile.ptr;
buffer_end = (const char *)(buffer_start) + packfile.size;
@@ -468,6 +466,7 @@ static int packed_load(git_repository *repo)
}
while (buffer_start < buffer_end) {
+ int err;
struct packref *ref = NULL;
if (packed_parse_oid(&ref, &buffer_start, buffer_end) < 0)
@@ -478,15 +477,16 @@ static int packed_load(git_repository *repo)
goto parse_failed;
}
- if (git_hashtable_insert(ref_cache->packfile, ref->name, ref) < 0)
- return -1;
+ git_khash_str_insert(ref_cache->packfile, ref->name, ref, err);
+ if (err < 0)
+ goto parse_failed;
}
git_buf_free(&packfile);
return 0;
parse_failed:
- git_hashtable_free(ref_cache->packfile);
+ git_khash_str_free(ref_cache->packfile);
ref_cache->packfile = NULL;
git_buf_free(&packfile);
return -1;
@@ -512,7 +512,7 @@ static int _dirent_loose_listall(void *_data, git_buf *full_path)
/* do not add twice a reference that exists already in the packfile */
if ((data->list_flags & GIT_REF_PACKED) != 0 &&
- git_hashtable_lookup(data->repo->references.packfile, file_path) != NULL)
+ git_khash_str_exists(data->repo->references.packfile, file_path))
return 0;
if (data->list_flags != GIT_REF_LISTALL) {
@@ -529,6 +529,7 @@ static int _dirent_loose_load(void *data, git_buf *full_path)
void *old_ref = NULL;
struct packref *ref;
const char *file_path;
+ int err;
if (git_path_isdir(full_path->ptr) == true)
return git_path_direach(full_path, _dirent_loose_load, repository);
@@ -538,8 +539,9 @@ static int _dirent_loose_load(void *data, git_buf *full_path)
if (loose_lookup_to_packfile(&ref, repository, file_path) < 0)
return -1;
- if (git_hashtable_insert2(repository->references.packfile,
- ref->name, ref, &old_ref) < 0) {
+ git_khash_str_insert2(
+ repository->references.packfile, ref->name, ref, old_ref, err);
+ if (err < 0) {
git__free(ref);
return -1;
}
@@ -734,7 +736,8 @@ static int packed_write(git_repository *repo)
assert(repo && repo->references.packfile);
- total_refs = (unsigned int)repo->references.packfile->key_count;
+ total_refs =
+ (unsigned int)git_khash_str_num_entries(repo->references.packfile);
if (git_vector_init(&packing_list, total_refs, packed_sort) < 0)
return -1;
@@ -743,10 +746,10 @@ static int packed_write(git_repository *repo)
{
struct packref *reference;
- GIT_HASHTABLE_FOREACH_VALUE(repo->references.packfile, reference,
- /* cannot fail: vector already has the right size */
+ /* cannot fail: vector already has the right size */
+ git_khash_str_foreach_value(repo->references.packfile, reference, {
git_vector_insert(&packing_list, reference);
- );
+ });
}
/* sort the vector so the entries appear sorted on the packfile */
@@ -870,7 +873,8 @@ static int reference_exists(int *exists, git_repository *repo, const char *ref_n
return -1;
if (git_path_isfile(ref_path.ptr) == true ||
- git_hashtable_lookup(repo->references.packfile, ref_path.ptr) != NULL) {
+ git_khash_str_exists(repo->references.packfile, ref_path.ptr))
+ {
*exists = 1;
} else {
*exists = 0;
@@ -936,6 +940,8 @@ static int reference_can_write(
static int packed_lookup(git_reference *ref)
{
struct packref *pack_ref = NULL;
+ git_khash_str *packfile_refs;
+ khiter_t pos;
if (packed_load(ref->owner) < 0)
return -1;
@@ -952,12 +958,15 @@ static int packed_lookup(git_reference *ref)
}
/* Look up on the packfile */
- pack_ref = git_hashtable_lookup(ref->owner->references.packfile, ref->name);
- if (pack_ref == NULL) {
+ packfile_refs = ref->owner->references.packfile;
+ pos = git_khash_str_lookup_index(packfile_refs, ref->name);
+ if (!git_khash_str_valid_index(packfile_refs, pos)) {
giterr_set(GITERR_REFERENCE, "Reference '%s' not found", ref->name);
return GIT_ENOTFOUND;
}
+ pack_ref = git_khash_str_value_at(packfile_refs, pos);
+
ref->flags = GIT_REF_OID | GIT_REF_PACKED;
ref->mtime = ref->owner->references.packfile_time;
git_oid_cpy(&ref->target.oid, &pack_ref->oid);
@@ -1002,18 +1011,25 @@ static int reference_delete(git_reference *ref)
* We need to reload the packfile, remove the reference from the
* packing list, and repack */
if (ref->flags & GIT_REF_PACKED) {
+ git_khash_str *packfile_refs;
struct packref *packref;
+ khiter_t pos;
+
/* load the existing packfile */
if (packed_load(ref->owner) < 0)
return -1;
- if (git_hashtable_remove2(ref->owner->references.packfile,
- ref->name, (void **) &packref) < 0) {
+ packfile_refs = ref->owner->references.packfile;
+ pos = git_khash_str_lookup_index(packfile_refs, ref->name);
+ if (!git_khash_str_valid_index(packfile_refs, pos)) {
giterr_set(GITERR_REFERENCE,
"Reference %s stopped existing in the packfile", ref->name);
return -1;
}
+ packref = git_khash_str_value_at(packfile_refs, pos);
+ git_khash_str_delete_at(packfile_refs, pos);
+
git__free(packref);
if (packed_write(ref->owner) < 0)
return -1;
@@ -1467,14 +1483,15 @@ int git_reference_foreach(
/* list all the packed references first */
if (list_flags & GIT_REF_PACKED) {
const char *ref_name;
+ void *ref;
if (packed_load(repo) < 0)
return -1;
- GIT_HASHTABLE_FOREACH_KEY(repo->references.packfile, ref_name,
+ git_khash_str_foreach(repo->references.packfile, ref_name, ref, {
if (callback(ref_name, payload) < 0)
return 0;
- );
+ });
}
/* now list the loose references, trying not to
@@ -1538,10 +1555,11 @@ void git_repository__refcache_free(git_refcache *refs)
if (refs->packfile) {
struct packref *reference;
- GIT_HASHTABLE_FOREACH_VALUE(
- refs->packfile, reference, git__free(reference));
+ git_khash_str_foreach_value(refs->packfile, reference, {
+ git__free(reference);
+ });
- git_hashtable_free(refs->packfile);
+ git_khash_str_free(refs->packfile);
}
}