pack: use raw oid data A packfile contains arrays of raw oid data, use a byte array to index into them.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
diff --git a/src/libgit2/pack.c b/src/libgit2/pack.c
index 7a6f6fc..16fe378 100644
--- a/src/libgit2/pack.c
+++ b/src/libgit2/pack.c
@@ -1001,13 +1001,14 @@ int get_delta_base(
base_offset = delta_obj_offset - unsigned_base_offset;
*curpos += used;
} else if (type == GIT_OBJECT_REF_DELTA) {
+ git_oid base_oid;
+ git_oid_fromraw(&base_oid, base_info);
+
/* If we have the cooperative cache, search in it first */
if (p->has_cache) {
struct git_pack_entry *entry;
- git_oid oid;
- git_oid_fromraw(&oid, base_info);
- if ((entry = git_oidmap_get(p->idx_cache, &oid)) != NULL) {
+ if ((entry = git_oidmap_get(p->idx_cache, &base_oid)) != NULL) {
if (entry->offset == 0)
return packfile_error("delta offset is zero");
@@ -1024,7 +1025,7 @@ int get_delta_base(
}
/* The base entry _must_ be in the same pack */
- if (pack_entry_find_offset(&base_offset, &unused, p, (git_oid *)base_info, GIT_OID_HEXSZ) < 0)
+ if (pack_entry_find_offset(&base_offset, &unused, p, &base_oid, GIT_OID_HEXSZ) < 0)
return packfile_error("base entry delta is not in the same pack");
*curpos += 20;
} else
@@ -1082,7 +1083,7 @@ static int packfile_open_locked(struct git_pack_file *p)
{
struct stat st;
struct git_pack_header hdr;
- git_oid sha1;
+ unsigned char sha1[GIT_OID_RAWSZ];
unsigned char *idx_sha1;
if (pack_index_open_locked(p) < 0)
@@ -1130,12 +1131,12 @@ static int packfile_open_locked(struct git_pack_file *p)
/* Verify the pack matches its index. */
if (p->num_objects != ntohl(hdr.hdr_entries) ||
- p_pread(p->mwf.fd, sha1.id, GIT_OID_RAWSZ, p->mwf.size - GIT_OID_RAWSZ) < 0)
+ p_pread(p->mwf.fd, sha1, GIT_OID_RAWSZ, p->mwf.size - GIT_OID_RAWSZ) < 0)
goto cleanup;
idx_sha1 = ((unsigned char *)p->index_map.data) + p->index_map.len - 40;
- if (git_oid__cmp(&sha1, (git_oid *)idx_sha1) != 0)
+ if (git_oid_raw_cmp(sha1, idx_sha1) != 0)
goto cleanup;
if (git_mwindow_file_register(&p->mwf) < 0)
@@ -1340,10 +1341,14 @@ int git_pack_foreach_entry(
}
git_vector_free(&offsets);
- p->oids = (git_oid **)git_vector_detach(NULL, NULL, &oids);
+ p->oids = (unsigned char **)git_vector_detach(NULL, NULL, &oids);
}
- /* We need to copy the OIDs to another array before we relinquish the lock to avoid races. */
+ /*
+ * We need to copy the OIDs to another array before we
+ * relinquish the lock to avoid races. We can also take
+ * this opportunity to put them into normal form.
+ */
git_array_init_to_size(oids, p->num_objects);
if (!oids.ptr) {
git_mutex_unlock(&p->lock);
@@ -1357,7 +1362,7 @@ int git_pack_foreach_entry(
git_array_clear(oids);
GIT_ERROR_CHECK_ALLOC(oid);
}
- git_oid_cpy(oid, p->oids[i]);
+ git_oid_fromraw(oid, p->oids[i]);
}
git_mutex_unlock(&p->lock);
@@ -1380,7 +1385,7 @@ int git_pack_foreach_entry_offset(
{
const unsigned char *index;
off64_t current_offset;
- const git_oid *current_oid;
+ git_oid current_oid;
uint32_t i;
int error = 0;
@@ -1422,8 +1427,9 @@ int git_pack_foreach_entry_offset(
current_offset = (((off64_t)ntohl(*((uint32_t *)(large_offset_ptr + 0)))) << 32) |
ntohl(*((uint32_t *)(large_offset_ptr + 4)));
}
- current_oid = (const git_oid *)(index + 20 * i);
- if ((error = cb(current_oid, current_offset, data)) != 0) {
+
+ git_oid_fromraw(¤t_oid, (index + 20 * i));
+ if ((error = cb(¤t_oid, current_offset, data)) != 0) {
error = git_error_set_after_callback(error);
goto cleanup;
}
@@ -1431,8 +1437,8 @@ int git_pack_foreach_entry_offset(
} else {
for (i = 0; i < p->num_objects; i++) {
current_offset = ntohl(*(const uint32_t *)(index + 24 * i));
- current_oid = (const git_oid *)(index + 24 * i + 4);
- if ((error = cb(current_oid, current_offset, data)) != 0) {
+ git_oid_fromraw(¤t_oid, (index + 24 * i + 4));
+ if ((error = cb(¤t_oid, current_offset, data)) != 0) {
error = git_error_set_after_callback(error);
goto cleanup;
}
@@ -1530,7 +1536,7 @@ static int pack_entry_find_offset(
if (pos < (int)p->num_objects) {
current = index + pos * stride;
- if (!git_oid_ncmp(short_oid, (const git_oid *)current, len))
+ if (!git_oid_raw_ncmp(short_oid->id, current, len))
found = 1;
}
}
@@ -1539,7 +1545,7 @@ static int pack_entry_find_offset(
/* Check for ambiguousity */
const unsigned char *next = current + stride;
- if (!git_oid_ncmp(short_oid, (const git_oid *)next, len)) {
+ if (!git_oid_raw_ncmp(short_oid->id, next, len)) {
found = 2;
}
}
diff --git a/src/libgit2/pack.h b/src/libgit2/pack.h
index bf279c6..f87249b 100644
--- a/src/libgit2/pack.h
+++ b/src/libgit2/pack.h
@@ -19,6 +19,7 @@
#include "offmap.h"
#include "oidmap.h"
#include "zstream.h"
+#include "oid.h"
/**
* Function type for callbacks from git_pack_foreach_entry_offset.
@@ -104,7 +105,7 @@ struct git_pack_file {
git_time_t mtime;
unsigned pack_local:1, pack_keep:1, has_cache:1;
git_oidmap *idx_cache;
- git_oid **oids;
+ unsigned char **oids;
git_pack_cache bases; /* delta base cache */