Signed-off-by: Yann Dirson <ydirson@xxxxxxxxxx> --- builtin/unpack-objects.c | 40 +++++++++++++++++++++++++--------------- 1 files changed, 25 insertions(+), 15 deletions(-) diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c index f63973c..6d7d113 100644 --- a/builtin/unpack-objects.c +++ b/builtin/unpack-objects.c @@ -11,6 +11,7 @@ #include "progress.h" #include "decorate.h" #include "fsck.h" +#include "sorted-array.h" static int dry_run, quiet, recover, has_errors, strict; static const char unpack_usage[] = "git unpack-objects [-n] [-q] [-r] [--strict] < pack-file"; @@ -157,7 +158,24 @@ struct obj_info { #define FLAG_OPEN (1u<<20) #define FLAG_WRITTEN (1u<<21) -static struct obj_info *obj_list; +/* + * FIXME: obj_info is a sorted array, but we read it as a whole, we + * don't need insertion features. This allows us to abuse unused + * obj_info_nr later as a means of specifying an upper bound for + * binary search. obj_info_alloc shall be eliminated by the compiler + * as unused. + */ +static int obj_info_cmp(off_t ref, struct obj_info *elem) +{ + if (ref == elem->offset) + return 0; + if (ref < elem->offset) + return -1; + return 1; +} +declare_sorted_array(static, struct obj_info, obj_list); +declare_sorted_array_search_check(static, struct obj_info, obj_list_check, + off_t, obj_list, obj_info_cmp); static unsigned nr_objects; /* @@ -356,7 +374,7 @@ static void unpack_delta_entry(enum object_type type, unsigned long delta_size, unsigned base_found = 0; unsigned char *pack, c; off_t base_offset; - unsigned lo, mid, hi; + int pos; pack = fill(1); c = *pack; @@ -380,19 +398,11 @@ static void unpack_delta_entry(enum object_type type, unsigned long delta_size, free(delta_data); return; } - lo = 0; - hi = nr; - while (lo < hi) { - mid = (lo + hi)/2; - if (base_offset < obj_list[mid].offset) { - hi = mid; - } else if (base_offset > obj_list[mid].offset) { - lo = mid + 1; - } else { - hashcpy(base_sha1, obj_list[mid].sha1); - base_found = !is_null_sha1(base_sha1); - break; - } + obj_list_nr = nr; /* kludge to bound the search */ + pos = obj_list_check(base_offset); + if (pos >= 0) { + hashcpy(base_sha1, obj_list[pos].sha1); + base_found = !is_null_sha1(base_sha1); } if (!base_found) { /* -- 1.7.2.3 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html