Skip to content

Commit 7218a21

Browse files
committed
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 <[email protected]>
1 parent 8978166 commit 7218a21

File tree

1 file changed

+40
-21
lines changed

1 file changed

+40
-21
lines changed

builtin/index-pack.c

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,18 @@ static void *get_data_from_pack(struct object_entry *obj)
391391
return data;
392392
}
393393

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)
395406
{
396407
int first = 0, last = nr_deltas;
397408

@@ -400,7 +411,8 @@ static int find_delta(const union delta_base *base)
400411
struct delta_entry *delta = &deltas[next];
401412
int cmp;
402413

403-
cmp = memcmp(base, &delta->base, UNION_BASE_SZ);
414+
cmp = compare_delta_bases(base, &delta->base,
415+
type, objects[delta->obj_no].type);
404416
if (!cmp)
405417
return next;
406418
if (cmp < 0) {
@@ -413,9 +425,10 @@ static int find_delta(const union delta_base *base)
413425
}
414426

415427
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)
417430
{
418-
int first = find_delta(base);
431+
int first = find_delta(base, type);
419432
int last = first;
420433
int end = nr_deltas - 1;
421434

@@ -543,11 +556,13 @@ static void find_unresolved_deltas(struct base_data *base,
543556
union delta_base base_spec;
544557

545558
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);
547561

548562
memset(&base_spec, 0, sizeof(base_spec));
549563
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);
551566
}
552567

553568
if (ref_last == -1 && ofs_last == -1) {
@@ -559,24 +574,24 @@ static void find_unresolved_deltas(struct base_data *base,
559574

560575
for (i = ref_first; i <= ref_last; i++) {
561576
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);
569584
}
570585

571586
for (i = ofs_first; i <= ofs_last; i++) {
572587
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);
580595
}
581596

582597
unlink_base_data(base);
@@ -586,7 +601,11 @@ static int compare_delta_entry(const void *a, const void *b)
586601
{
587602
const struct delta_entry *delta_a = a;
588603
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);
590609
}
591610

592611
/* Parse all objects and return the pack content SHA1 hash */

0 commit comments

Comments
 (0)