summaryrefslogtreecommitdiff
path: root/packfile.c
diff options
context:
space:
mode:
authorJonathan Tan <jonathantanmy@google.com>2017-08-18 15:20:33 -0700
committerJunio C Hamano <gitster@pobox.com>2017-08-23 15:12:07 -0700
commita2551953b9619b285128c1e9cf35120fb7555d8f (patch)
tree719abecbe407fddd939f846e66c90fa657916a99 /packfile.c
parent9e0f45f5a61d9d0556e6004198dd6a650be14bd9 (diff)
downloadgit-a2551953b9619b285128c1e9cf35120fb7555d8f.tar.gz
pack: move find_pack_entry_one(), is_pack_valid()
Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'packfile.c')
-rw-r--r--packfile.c76
1 files changed, 75 insertions, 1 deletions
diff --git a/packfile.c b/packfile.c
index f251e38783..20562304b7 100644
--- a/packfile.c
+++ b/packfile.c
@@ -7,6 +7,7 @@
#include "delta.h"
#include "list.h"
#include "streaming.h"
+#include "sha1-lookup.h"
char *odb_pack_name(struct strbuf *buf,
const unsigned char *sha1,
@@ -509,7 +510,7 @@ static int open_packed_git_1(struct packed_git *p)
return 0;
}
-int open_packed_git(struct packed_git *p)
+static int open_packed_git(struct packed_git *p)
{
if (!open_packed_git_1(p))
return 0;
@@ -1700,3 +1701,76 @@ off_t nth_packed_object_offset(const struct packed_git *p, uint32_t n)
ntohl(*((uint32_t *)(index + 4)));
}
}
+
+off_t find_pack_entry_one(const unsigned char *sha1,
+ struct packed_git *p)
+{
+ const uint32_t *level1_ofs = p->index_data;
+ const unsigned char *index = p->index_data;
+ unsigned hi, lo, stride;
+ static int debug_lookup = -1;
+
+ if (debug_lookup < 0)
+ debug_lookup = !!getenv("GIT_DEBUG_LOOKUP");
+
+ if (!index) {
+ if (open_pack_index(p))
+ return 0;
+ level1_ofs = p->index_data;
+ index = p->index_data;
+ }
+ if (p->index_version > 1) {
+ level1_ofs += 2;
+ index += 8;
+ }
+ index += 4 * 256;
+ hi = ntohl(level1_ofs[*sha1]);
+ lo = ((*sha1 == 0x0) ? 0 : ntohl(level1_ofs[*sha1 - 1]));
+ if (p->index_version > 1) {
+ stride = 20;
+ } else {
+ stride = 24;
+ index += 4;
+ }
+
+ if (debug_lookup)
+ printf("%02x%02x%02x... lo %u hi %u nr %"PRIu32"\n",
+ sha1[0], sha1[1], sha1[2], lo, hi, p->num_objects);
+
+ while (lo < hi) {
+ unsigned mi = (lo + hi) / 2;
+ int cmp = hashcmp(index + mi * stride, sha1);
+
+ if (debug_lookup)
+ printf("lo %u hi %u rg %u mi %u\n",
+ lo, hi, hi - lo, mi);
+ if (!cmp)
+ return nth_packed_object_offset(p, mi);
+ if (cmp > 0)
+ hi = mi;
+ else
+ lo = mi+1;
+ }
+ return 0;
+}
+
+int is_pack_valid(struct packed_git *p)
+{
+ /* An already open pack is known to be valid. */
+ if (p->pack_fd != -1)
+ return 1;
+
+ /* If the pack has one window completely covering the
+ * file size, the pack is known to be valid even if
+ * the descriptor is not currently open.
+ */
+ if (p->windows) {
+ struct pack_window *w = p->windows;
+
+ if (!w->offset && w->len == p->pack_size)
+ return 1;
+ }
+
+ /* Force the pack to open to prove its valid. */
+ return !open_packed_git(p);
+}