Signed-off-by: Jonathan Tan <jonathantanmy@xxxxxxxxxx> --- cache.h | 8 ------ pack.h | 10 ++++++-- packfile.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ sha1_file.c | 84 ------------------------------------------------------------ 4 files changed, 93 insertions(+), 94 deletions(-) diff --git a/cache.h b/cache.h index 7686ccb30..b944aca69 100644 --- a/cache.h +++ b/cache.h @@ -1618,14 +1618,6 @@ extern int odb_mkstemp(struct strbuf *template, const char *pattern); */ extern int odb_pack_keep(const char *name); -/* - * If the object named sha1 is present in the specified packfile, - * return its offset within the packfile; otherwise, return 0. - */ -extern off_t find_pack_entry_one(const unsigned char *sha1, struct packed_git *); - -extern int is_pack_valid(struct packed_git *); - /* * Iterate over the files in the loose-object parts of the object * directory "path", triggering the following callbacks: diff --git a/pack.h b/pack.h index e0e206e3c..f5bd94813 100644 --- a/pack.h +++ b/pack.h @@ -144,8 +144,6 @@ extern void close_pack_windows(struct packed_git *); extern void close_pack_index(struct packed_git *); extern void close_all_packs(void); -extern int open_packed_git(struct packed_git *p); - extern unsigned char *use_pack(struct packed_git *, struct pack_window **, off_t, unsigned long *); extern void unuse_pack(struct pack_window **); extern struct packed_git *add_packed_git(const char *path, size_t path_len, int local); @@ -212,4 +210,12 @@ extern void check_pack_index_ptr(const struct packed_git *p, const void *ptr); */ extern off_t nth_packed_object_offset(const struct packed_git *, uint32_t n); +/* + * If the object named sha1 is present in the specified packfile, + * return its offset within the packfile; otherwise, return 0. + */ +extern off_t find_pack_entry_one(const unsigned char *sha1, struct packed_git *); + +extern int is_pack_valid(struct packed_git *); + #endif diff --git a/packfile.c b/packfile.c index 94c8af991..71017d2ec 100644 --- a/packfile.c +++ b/packfile.c @@ -6,6 +6,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, @@ -1698,3 +1699,87 @@ 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 use_lookup = -1; + 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); + + if (use_lookup < 0) + use_lookup = !!getenv("GIT_USE_LOOKUP"); + if (use_lookup) { + int pos = sha1_entry_pos(index, stride, 0, + lo, hi, p->num_objects, sha1); + if (pos < 0) + return 0; + return nth_packed_object_offset(p, pos); + } + + do { + 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; + } while (lo < hi); + 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); +} diff --git a/sha1_file.c b/sha1_file.c index 0f4d68c5a..75b9ceb39 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -1073,90 +1073,6 @@ int parse_sha1_header(const char *hdr, unsigned long *sizep) return parse_sha1_header_extended(hdr, &oi, 0); } -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 use_lookup = -1; - 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); - - if (use_lookup < 0) - use_lookup = !!getenv("GIT_USE_LOOKUP"); - if (use_lookup) { - int pos = sha1_entry_pos(index, stride, 0, - lo, hi, p->num_objects, sha1); - if (pos < 0) - return 0; - return nth_packed_object_offset(p, pos); - } - - do { - 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; - } while (lo < hi); - 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); -} - static int fill_pack_entry(const unsigned char *sha1, struct pack_entry *e, struct packed_git *p) -- 2.14.0.434.g98096fd7a8-goog