34
struct object_entry *obj;
35
void *data;
36
unsigned long size;
37
+ int ref_first, ref_last;
38
+ int ofs_first, ofs_last;
39
};
40
41
/*
223
die("pack has bad object at offset %lu: %s", offset, buf);
224
}
225
226
+static struct base_data *alloc_base_data(void)
227
+{
228
+ struct base_data *base = xmalloc(sizeof(struct base_data));
229
+ memset(base, 0, sizeof(*base));
230
+ base->ref_last = -1;
231
+ base->ofs_last = -1;
232
+ return base;
233
+}
234
+
235
static void free_base_data(struct base_data *c)
236
{
237
if (c->data) {
564
nr_resolved_deltas++;
565
}
566
556
-static void find_unresolved_deltas(struct base_data *base,
557
- struct base_data *prev_base)
567
+static struct base_data *find_unresolved_deltas_1(struct base_data *base,
568
+ struct base_data *prev_base)
569
{
559
- int i, ref_first, ref_last, ofs_first, ofs_last;
560
-
561
- /*
562
- * This is a recursive function. Those brackets should help reducing
563
- * stack usage by limiting the scope of the delta_base union.
564
- */
565
- {
570
+ if (base->ref_last == -1 && base->ofs_last == -1) {
571
union delta_base base_spec;
572
573
hashcpy(base_spec.sha1, base->obj->idx.sha1);
574
find_delta_children(&base_spec,
570
- &ref_first, &ref_last, OBJ_REF_DELTA);
575
+ &base->ref_first, &base->ref_last, OBJ_REF_DELTA);
576
577
memset(&base_spec, 0, sizeof(base_spec));
578
base_spec.offset = base->obj->idx.offset;
579
find_delta_children(&base_spec,
575
- &ofs_first, &ofs_last, OBJ_OFS_DELTA);
576
- }
580
+ &base->ofs_first, &base->ofs_last, OBJ_OFS_DELTA);
581
578
- if (ref_last == -1 && ofs_last == -1) {
579
- free(base->data);
580
- return;
581
- }
582
+ if (base->ref_last == -1 && base->ofs_last == -1) {
583
+ free(base->data);
584
+ return NULL;
585
+ }
586
583
- link_base_data(prev_base, base);
587
+ link_base_data(prev_base, base);
588
+ }
589
585
- for (i = ref_first; i <= ref_last; i++) {
586
- struct object_entry *child = objects + deltas[i].obj_no;
587
- struct base_data result;
590
+ if (base->ref_first <= base->ref_last) {
591
+ struct object_entry *child = objects + deltas[base->ref_first].obj_no;
592
+ struct base_data *result = alloc_base_data();
593
594
assert(child->real_type == OBJ_REF_DELTA);
590
- resolve_delta(child, base, &result);
591
- if (i == ref_last && ofs_last == -1)
595
+ resolve_delta(child, base, result);
596
+ if (base->ref_first == base->ref_last && base->ofs_last == -1)
597
free_base_data(base);
593
- find_unresolved_deltas(&result, base);
598
+
599
+ base->ref_first++;
600
+ return result;
601
}
602
596
- for (i = ofs_first; i <= ofs_last; i++) {
597
- struct object_entry *child = objects + deltas[i].obj_no;
598
- struct base_data result;
603
+ if (base->ofs_first <= base->ofs_last) {
604
+ struct object_entry *child = objects + deltas[base->ofs_first].obj_no;
605
+ struct base_data *result = alloc_base_data();
606
607
assert(child->real_type == OBJ_OFS_DELTA);
601
- resolve_delta(child, base, &result);
602
- if (i == ofs_last)
608
+ resolve_delta(child, base, result);
609
+ if (base->ofs_first == base->ofs_last)
610
free_base_data(base);
604
- find_unresolved_deltas(&result, base);
611
+
612
+ base->ofs_first++;
613
+ return result;
614
}
615
616
unlink_base_data(base);
617
+ return NULL;
618
+}
619
+
620
+static void find_unresolved_deltas(struct base_data *base)
621
+{
622
+ struct base_data *new_base, *prev_base = NULL;
623
+ for (;;) {
624
+ new_base = find_unresolved_deltas_1(base, prev_base);
625
+
626
+ if (new_base) {
627
+ prev_base = base;
628
+ base = new_base;
629
+ } else {
630
+ free(base);
631
+ base = prev_base;
632
+ if (!base)
633
+ return;
634
+ prev_base = base->base;
635
+ }
636
+ }
637
}
638
639
static int compare_delta_entry(const void *a, const void *b)
713
progress = start_progress("Resolving deltas", nr_deltas);
714
for (i = 0; i < nr_objects; i++) {
715
struct object_entry *obj = &objects[i];
687
- struct base_data base_obj;
716
+ struct base_data *base_obj = alloc_base_data();
717
718
if (is_delta_type(obj->type))
719
continue;
691
- base_obj.obj = obj;
692
- base_obj.data = NULL;
693
- find_unresolved_deltas(&base_obj, NULL);
720
+ base_obj->obj = obj;
721
+ base_obj->data = NULL;
722
+ find_unresolved_deltas(base_obj);
723
display_progress(progress, nr_resolved_deltas);
724
}
725
}
812
for (i = 0; i < n; i++) {
813
struct delta_entry *d = sorted_by_pos[i];
814
enum object_type type;
786
- struct base_data base_obj;
815
+ struct base_data *base_obj = alloc_base_data();
816
817
if (objects[d->obj_no].real_type != OBJ_REF_DELTA)
818
continue;
790
- base_obj.data = read_sha1_file(d->base.sha1, &type, &base_obj.size);
791
- if (!base_obj.data)
819
+ base_obj->data = read_sha1_file(d->base.sha1, &type, &base_obj->size);
820
+ if (!base_obj->data)
821
continue;
822
794
- if (check_sha1_signature(d->base.sha1, base_obj.data,
795
- base_obj.size, typename(type)))
823
+ if (check_sha1_signature(d->base.sha1, base_obj->data,
824
+ base_obj->size, typename(type)))
825
die("local object %s is corrupt", sha1_to_hex(d->base.sha1));
797
- base_obj.obj = append_obj_to_pack(f, d->base.sha1,
798
- base_obj.data, base_obj.size, type);
799
- find_unresolved_deltas(&base_obj, NULL);
826
+ base_obj->obj = append_obj_to_pack(f, d->base.sha1,
827
+ base_obj->data, base_obj->size, type);
828
+ find_unresolved_deltas(base_obj);
829
display_progress(progress, nr_resolved_deltas);
830
}
831
free(sorted_by_pos);