@matheusbsbs / matheus-bagliano / commits / 7218a215ef
Fork 0

index-pack: group the delta-base array entries also by type

Entries in the delta_base array are only grouped by the bytepattern in the delta_base union, some of which have 20-byte object name of the base object (i.e. base for REF_DELTA objects), while others have sizeof(off_t) bytes followed by enough NULs to fill 20-byte. The loops to iterate through a range inside this array still needs to inspect the type of the delta, and skip over false hits. Group the entries also by type to eliminate the potential of false hits. Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed Feb 2, 2011 at 10:06 UTC 7218a215efc7ae46f7ca8d82442f354e7ac06262
1 file changed +40 -21
builtin/index-pack.c
+40 -21
@@ -391,7 +391,18 @@ static void *get_data_from_pack(struct object_entry *obj)
391 return data;
392 }
393
394 -static int find_delta(const union delta_base *base)
394 +static int compare_delta_bases(const union delta_base *base1,
395 + const union delta_base *base2,
396 + enum object_type type1,
397 + enum object_type type2)
398 +{
399 + int cmp = type1 - type2;
400 + if (cmp)
401 + return cmp;
402 + return memcmp(base1, base2, UNION_BASE_SZ);
403 +}
404 +
405 +static int find_delta(const union delta_base *base, enum object_type type)
406 {
407 int first = 0, last = nr_deltas;
408
@@ -400,7 +411,8 @@ static int find_delta(const union delta_base *base)
411 struct delta_entry *delta = &deltas[next];
412 int cmp;
413
403 - cmp = memcmp(base, &delta->base, UNION_BASE_SZ);
414 + cmp = compare_delta_bases(base, &delta->base,
415 + type, objects[delta->obj_no].type);
416 if (!cmp)
417 return next;
418 if (cmp < 0) {
@@ -413,9 +425,10 @@ static int find_delta(const union delta_base *base)
425 }
426
427 static void find_delta_children(const union delta_base *base,
416 - int *first_index, int *last_index)
428 + int *first_index, int *last_index,
429 + enum object_type type)
430 {
418 - int first = find_delta(base);
431 + int first = find_delta(base, type);
432 int last = first;
433 int end = nr_deltas - 1;
434
@@ -543,11 +556,13 @@ static void find_unresolved_deltas(struct base_data *base,
556 union delta_base base_spec;
557
558 hashcpy(base_spec.sha1, base->obj->idx.sha1);
546 - find_delta_children(&base_spec, &ref_first, &ref_last);
559 + find_delta_children(&base_spec,
560 + &ref_first, &ref_last, OBJ_REF_DELTA);
561
562 memset(&base_spec, 0, sizeof(base_spec));
563 base_spec.offset = base->obj->idx.offset;
550 - find_delta_children(&base_spec, &ofs_first, &ofs_last);
564 + find_delta_children(&base_spec,
565 + &ofs_first, &ofs_last, OBJ_OFS_DELTA);
566 }
567
568 if (ref_last == -1 && ofs_last == -1) {
@@ -559,24 +574,24 @@ static void find_unresolved_deltas(struct base_data *base,
574
575 for (i = ref_first; i <= ref_last; i++) {
576 struct object_entry *child = objects + deltas[i].obj_no;
562 - if (child->real_type == OBJ_REF_DELTA) {
563 - struct base_data result;
564 - resolve_delta(child, base, &result);
565 - if (i == ref_last && ofs_last == -1)
566 - free_base_data(base);
567 - find_unresolved_deltas(&result, base);
568 - }
577 + struct base_data result;
578 +
579 + assert(child->real_type == OBJ_REF_DELTA);
580 + resolve_delta(child, base, &result);
581 + if (i == ref_last && ofs_last == -1)
582 + free_base_data(base);
583 + find_unresolved_deltas(&result, base);
584 }
585
586 for (i = ofs_first; i <= ofs_last; i++) {
587 struct object_entry *child = objects + deltas[i].obj_no;
573 - if (child->real_type == OBJ_OFS_DELTA) {
574 - struct base_data result;
575 - resolve_delta(child, base, &result);
576 - if (i == ofs_last)
577 - free_base_data(base);
578 - find_unresolved_deltas(&result, base);
579 - }
588 + struct base_data result;
589 +
590 + assert(child->real_type == OBJ_OFS_DELTA);
591 + resolve_delta(child, base, &result);
592 + if (i == ofs_last)
593 + free_base_data(base);
594 + find_unresolved_deltas(&result, base);
595 }
596
597 unlink_base_data(base);
@@ -586,7 +601,11 @@ static int compare_delta_entry(const void *a, const void *b)
601 {
602 const struct delta_entry *delta_a = a;
603 const struct delta_entry *delta_b = b;
589 - return memcmp(&delta_a->base, &delta_b->base, UNION_BASE_SZ);
604 +
605 + /* group by type (ref vs ofs) and then by value (sha-1 or offset) */
606 + return compare_delta_bases(&delta_a->base, &delta_b->base,
607 + objects[delta_a->obj_no].type,
608 + objects[delta_b->obj_no].type);
609 }
610
611 /* Parse all objects and return the pack content SHA1 hash */