summaryrefslogtreecommitdiff
path: root/src/odb.c
diff options
context:
space:
mode:
authorMarc Pegon <pegon.marc@gmail.com>2011-05-27 22:46:41 +0200
committerVicent Marti <tanoku@gmail.com>2011-06-01 23:40:41 +0200
commitdd453c4dbf9a1fa38530b1f51e079852736b8f66 (patch)
tree19a16a4248757e21b700e27231fb334fe468861a /src/odb.c
parent53c0bd81a2915d6f82ef2f9c0703770783a3dc89 (diff)
downloadlibgit2-dd453c4dbf9a1fa38530b1f51e079852736b8f66.tar.gz
Added git.git sha1 lookup method to replace simple binary search in pack backend.
Implemented find_unique_short_oid for pack backend, based on git sha1 lookup method; finding an object given its full oid is just a particular case of searching the unique object matching an oid prefix (short oid). Added git_odb_read_unique_short_oid, which iterates over all the backends to find and read the unique object matching the given oid prefix. Added a git_object_lookup_short_oid method to find the unique object in the repository matching a given oid prefix : it generalizes git_object_lookup which now does nothing but calls git_object_lookup_short_oid.
Diffstat (limited to 'src/odb.c')
-rw-r--r--src/odb.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/odb.c b/src/odb.c
index c669e7c14..ed600ffab 100644
--- a/src/odb.c
+++ b/src/odb.c
@@ -488,6 +488,48 @@ int git_odb_read(git_odb_object **out, git_odb *db, const git_oid *id)
return error;
}
+int git_odb_read_unique_short_oid(git_oid *out_oid, git_odb_object **out, git_odb *db, const git_oid *short_id, unsigned int len)
+{
+ unsigned int i;
+ int error = GIT_ENOTFOUND;
+ git_rawobj raw;
+ int found = 0;
+
+ assert(out && db && id && len > 0);
+
+ if (len > GIT_OID_HEXSZ)
+ len = GIT_OID_HEXSZ;
+
+ if (len == GIT_OID_HEXSZ) {
+ *out = git_cache_get(&db->cache, short_id);
+ if (*out != NULL) {
+ git_oid_cpy(out_oid, short_id);
+ return GIT_SUCCESS;
+ }
+ }
+
+ for (i = 0; i < db->backends.length && found < 2; ++i) {
+ backend_internal *internal = git_vector_get(&db->backends, i);
+ git_odb_backend *b = internal->backend;
+
+ if (b->read != NULL) {
+ error = b->read_unique_short_oid(out_oid, &raw.data, &raw.len, &raw.type, b, short_id, len);
+ if (error == GIT_SUCCESS)
+ found++;
+ }
+ }
+
+ if (found == 1) {
+ *out = git_cache_try_store(&db->cache, new_odb_object(out_oid, &raw));
+ } else if (found > 1) {
+ return git__rethrow(GIT_EAMBIGUOUSOIDPREFIX, "Ambiguous sha1");
+ } else {
+ return git__rethrow(GIT_ENOTFOUND, "Failed to read object");
+ }
+
+ return GIT_SUCCESS;
+}
+
int git_odb_write(git_oid *oid, git_odb *db, const void *data, size_t len, git_otype type)
{
unsigned int i;