diff options
author | Edward Thomson <ethomson@github.com> | 2016-03-04 00:50:35 -0500 |
---|---|---|
committer | Edward Thomson <ethomson@github.com> | 2016-03-07 16:10:25 -0500 |
commit | 6c04269c8f558c109b0cd4524feb9d95bbbb3f6b (patch) | |
tree | 2bd1b064bf2ef5be037d3f960ff51b1439a240e4 /src/odb.c | |
parent | e10144ae57e50798e43515cb469722a4e825c23c (diff) | |
download | libgit2-6c04269c8f558c109b0cd4524feb9d95bbbb3f6b.tar.gz |
git_odb_exists_many_prefixes: query odb for multiple short ids
Query the object database for multiple objects at a time, given their
object ID (which may be abbreviated) and optional type.
Diffstat (limited to 'src/odb.c')
-rw-r--r-- | src/odb.c | 80 |
1 files changed, 68 insertions, 12 deletions
@@ -18,6 +18,7 @@ #include "git2/odb_backend.h" #include "git2/oid.h" +#include "git2/oidarray.h" #define GIT_ALTERNATES_FILE "info/alternates" @@ -651,7 +652,7 @@ int git_odb_exists(git_odb *db, const git_oid *id) if ((object = git_cache_get_raw(odb_cache(db), id)) != NULL) { git_odb_object_free(object); - return (int)true; + return 1; } if (odb_exists_1(db, id, false)) @@ -716,10 +717,8 @@ int git_odb_exists_prefix( if (len < GIT_OID_MINPREFIXLEN) return git_odb__error_ambiguous("prefix length too short"); - if (len > GIT_OID_HEXSZ) - len = GIT_OID_HEXSZ; - if (len == GIT_OID_HEXSZ) { + if (len >= GIT_OID_HEXSZ) { if (git_odb_exists(db, short_id)) { if (out) git_oid_cpy(out, short_id); @@ -730,10 +729,7 @@ int git_odb_exists_prefix( } } - /* just copy valid part of short_id */ - memcpy(&key.id, short_id->id, (len + 1) / 2); - if (len & 1) - key.id[len / 2] &= 0xF0; + git_oid__cpy_prefix(&key, short_id, len); error = odb_exists_prefix_1(out, db, &key, len, false); @@ -746,6 +742,69 @@ int git_odb_exists_prefix( return error; } +int git_odb_exists_many_prefixes( + git_odb *db, + git_oid *ids, + size_t *id_lengths, + git_otype *types, + size_t cnt) +{ + size_t len, i; + int error; + + assert(db && ids && id_lengths); + + for (i = 0; i < cnt; i++) { + git_oid *actual_id = NULL, tmp; + git_otype actual_type = 0; + + /* if we were given a full object ID, simply look it up */ + if (id_lengths[i] >= GIT_OID_HEXSZ) { + error = git_odb_read_header(&len, &actual_type, db, &ids[i]); + } + + /* otherwise, resolve the short id to full, then (optionally) + * read the header. + */ + else if (id_lengths[i] >= GIT_OID_MINPREFIXLEN) { + error = odb_exists_prefix_1(&tmp, + db, &ids[i], id_lengths[i], false); + + if (!error) { + actual_id = &tmp; + + if (types && types[i] != GIT_OBJ_ANY) + error = git_odb_read_header(&len, &actual_type, db, &tmp); + else + actual_type = GIT_OBJ_ANY; + } + } + + if (error < 0 && error != GIT_ENOTFOUND && error != GIT_EAMBIGUOUS) + break; + + error = 0; + + if (types && types[i] != GIT_OBJ_ANY && types[i] != actual_type) + actual_type = 0; + + if (!actual_type) { + id_lengths[i] = 0; + memset(&ids[i], 0, sizeof(git_oid)); + } else { + id_lengths[i] = GIT_OID_HEXSZ; + + if (actual_id) + git_oid_cpy(&ids[i], actual_id); + } + } + + if (!error) + giterr_clear(); + + return error; +} + int git_odb_read_header(size_t *len_p, git_otype *type_p, git_odb *db, const git_oid *id) { int error; @@ -957,10 +1016,7 @@ int git_odb_read_prefix( return 0; } - /* just copy valid part of short_id */ - memcpy(&key.id, short_id->id, (len + 1) / 2); - if (len & 1) - key.id[len / 2] &= 0xF0; + git_oid__cpy_prefix(&key, short_id, len); error = read_prefix_1(out, db, &key, len, false); |