index-pack: restructure pack processing into three main functions
The second pass in parse_pack_objects() are split into resolve_deltas(). The final phase, fixing thin pack or just seal the pack, is now in conclude_pack() function. Main pack processing is now a sequence of these functions: - parse_pack_objects() reads through the input pack - resolve_deltas() makes sure all deltas can be resolved - conclude_pack() seals the output pack - write_idx_file() writes companion index file - final() moves the pack/index to proper place Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Nguyễn Thái Ngọc Duy committed
May 6, 2012 at 19:31 UTC
5272f75587abb4cb396059ecbf1a6130bb2e69d3
1 file changed
+75
-53
builtin/index-pack.c
+75
-53
@@ -682,19 +682,26 @@ static int compare_delta_entry(const void *a, const void *b)
682
objects[delta_b->obj_no].type);
683
}
684
685
-/* Parse all objects and return the pack content SHA1 hash */
685
+static void resolve_base(struct object_entry *obj)
686
+{
687
+ struct base_data *base_obj = alloc_base_data();
688
+ base_obj->obj = obj;
689
+ base_obj->data = NULL;
690
+ find_unresolved_deltas(base_obj);
691
+}
692
+
693
+/*
694
+ * First pass:
695
+ * - find locations of all objects;
696
+ * - calculate SHA1 of all non-delta objects;
697
+ * - remember base (SHA1 or offset) for all deltas.
698
+ */
699
static void parse_pack_objects(unsigned char *sha1)
700
{
701
int i;
702
struct delta_entry *delta = deltas;
703
struct stat st;
704
692
- /*
693
- * First pass:
694
- * - find locations of all objects;
695
- * - calculate SHA1 of all non-delta objects;
696
- * - remember base (SHA1 or offset) for all deltas.
697
- */
705
if (verbose)
706
progress = start_progress(
707
from_stdin ? "Receiving objects" : "Indexing objects",
@@ -728,6 +735,19 @@ static void parse_pack_objects(unsigned char *sha1)
735
if (S_ISREG(st.st_mode) &&
736
lseek(input_fd, 0, SEEK_CUR) - input_len != st.st_size)
737
die("pack has junk at the end");
738
+}
739
+
740
+/*
741
+ * Second pass:
742
+ * - for all non-delta objects, look if it is used as a base for
743
+ * deltas;
744
+ * - if used as a base, uncompress the object and apply all deltas,
745
+ * recursively checking if the resulting object is used as a base
746
+ * for some more deltas.
747
+ */
748
+static void resolve_deltas(void)
749
+{
750
+ int i;
751
752
if (!nr_deltas)
753
return;
@@ -736,29 +756,63 @@ static void parse_pack_objects(unsigned char *sha1)
756
qsort(deltas, nr_deltas, sizeof(struct delta_entry),
757
compare_delta_entry);
758
739
- /*
740
- * Second pass:
741
- * - for all non-delta objects, look if it is used as a base for
742
- * deltas;
743
- * - if used as a base, uncompress the object and apply all deltas,
744
- * recursively checking if the resulting object is used as a base
745
- * for some more deltas.
746
- */
759
if (verbose)
760
progress = start_progress("Resolving deltas", nr_deltas);
761
for (i = 0; i < nr_objects; i++) {
762
struct object_entry *obj = &objects[i];
751
- struct base_data *base_obj = alloc_base_data();
763
764
if (is_delta_type(obj->type))
765
continue;
755
- base_obj->obj = obj;
756
- base_obj->data = NULL;
757
- find_unresolved_deltas(base_obj);
766
+ resolve_base(obj);
767
display_progress(progress, nr_resolved_deltas);
768
}
769
}
770
771
+/*
772
+ * Third pass:
773
+ * - append objects to convert thin pack to full pack if required
774
+ * - write the final 20-byte SHA-1
775
+ */
776
+static void fix_unresolved_deltas(struct sha1file *f, int nr_unresolved);
777
+static void conclude_pack(int fix_thin_pack, const char *curr_pack, unsigned char *pack_sha1)
778
+{
779
+ if (nr_deltas == nr_resolved_deltas) {
780
+ stop_progress(&progress);
781
+ /* Flush remaining pack final 20-byte SHA1. */
782
+ flush();
783
+ return;
784
+ }
785
+
786
+ if (fix_thin_pack) {
787
+ struct sha1file *f;
788
+ unsigned char read_sha1[20], tail_sha1[20];
789
+ char msg[48];
790
+ int nr_unresolved = nr_deltas - nr_resolved_deltas;
791
+ int nr_objects_initial = nr_objects;
792
+ if (nr_unresolved <= 0)
793
+ die("confusion beyond insanity");
794
+ objects = xrealloc(objects,
795
+ (nr_objects + nr_unresolved + 1)
796
+ * sizeof(*objects));
797
+ f = sha1fd(output_fd, curr_pack);
798
+ fix_unresolved_deltas(f, nr_unresolved);
799
+ sprintf(msg, "completed with %d local objects",
800
+ nr_objects - nr_objects_initial);
801
+ stop_progress_msg(&progress, msg);
802
+ sha1close(f, tail_sha1, 0);
803
+ hashcpy(read_sha1, pack_sha1);
804
+ fixup_pack_header_footer(output_fd, pack_sha1,
805
+ curr_pack, nr_objects,
806
+ read_sha1, consumed_bytes-20);
807
+ if (hashcmp(read_sha1, tail_sha1) != 0)
808
+ die("Unexpected tail checksum for %s "
809
+ "(disk corruption?)", curr_pack);
810
+ }
811
+ if (nr_deltas != nr_resolved_deltas)
812
+ die("pack has %d unresolved deltas",
813
+ nr_deltas - nr_resolved_deltas);
814
+}
815
+
816
static int write_compressed(struct sha1file *f, void *in, unsigned int size)
817
{
818
git_zstream stream;
@@ -1196,40 +1250,8 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
1250
objects = xcalloc(nr_objects + 1, sizeof(struct object_entry));
1251
deltas = xcalloc(nr_objects, sizeof(struct delta_entry));
1252
parse_pack_objects(pack_sha1);
1199
- if (nr_deltas == nr_resolved_deltas) {
1200
- stop_progress(&progress);
1201
- /* Flush remaining pack final 20-byte SHA1. */
1202
- flush();
1203
- } else {
1204
- if (fix_thin_pack) {
1205
- struct sha1file *f;
1206
- unsigned char read_sha1[20], tail_sha1[20];
1207
- char msg[48];
1208
- int nr_unresolved = nr_deltas - nr_resolved_deltas;
1209
- int nr_objects_initial = nr_objects;
1210
- if (nr_unresolved <= 0)
1211
- die("confusion beyond insanity");
1212
- objects = xrealloc(objects,
1213
- (nr_objects + nr_unresolved + 1)
1214
- * sizeof(*objects));
1215
- f = sha1fd(output_fd, curr_pack);
1216
- fix_unresolved_deltas(f, nr_unresolved);
1217
- sprintf(msg, "completed with %d local objects",
1218
- nr_objects - nr_objects_initial);
1219
- stop_progress_msg(&progress, msg);
1220
- sha1close(f, tail_sha1, 0);
1221
- hashcpy(read_sha1, pack_sha1);
1222
- fixup_pack_header_footer(output_fd, pack_sha1,
1223
- curr_pack, nr_objects,
1224
- read_sha1, consumed_bytes-20);
1225
- if (hashcmp(read_sha1, tail_sha1) != 0)
1226
- die("Unexpected tail checksum for %s "
1227
- "(disk corruption?)", curr_pack);
1228
- }
1229
- if (nr_deltas != nr_resolved_deltas)
1230
- die("pack has %d unresolved deltas",
1231
- nr_deltas - nr_resolved_deltas);
1232
- }
1253
+ resolve_deltas();
1254
+ conclude_pack(fix_thin_pack, curr_pack, pack_sha1);
1255
free(deltas);
1256
if (strict)
1257
check_objects();