diff options
author | Jonathan Tan <jonathantanmy@google.com> | 2017-08-18 15:20:33 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2017-08-23 15:12:07 -0700 |
commit | a2551953b9619b285128c1e9cf35120fb7555d8f (patch) | |
tree | 719abecbe407fddd939f846e66c90fa657916a99 /packfile.c | |
parent | pack: move check_pack_index_ptr(), nth_packed_object_offset() (diff) | |
download | tgif-a2551953b9619b285128c1e9cf35120fb7555d8f.tar.xz |
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.c | 76 |
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); +} |