commit-graph: create write_commit_graph_context

The write_commit_graph() method is too large and complex. To simplify it, we should extract several helper functions. However, we will risk repeating a lot of declarations related to progress incidators and object id or commit lists. Create a new write_commit_graph_context struct that contains the core data structures used in this process. Replace the other local variables with the values inside the context object. Following this change, we will start to lift code segments wholesale out of the write_commit_graph() method and into helper functions. Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Derrick Stolee committed Jun 12, 2019 at 06:29 UTC c9905beade13efff6be9c15ebe03d07fe5278ccc
1 file changed +194 -196
commit-graph.c
+194 -196
@@ -518,14 +518,38 @@ struct tree *get_commit_tree_in_graph(struct repository *r, const struct commit
518 return get_commit_tree_in_graph_one(r, r->objects->commit_graph, c);
519 }
520
521 +struct packed_commit_list {
522 + struct commit **list;
523 + int nr;
524 + int alloc;
525 +};
526 +
527 +struct packed_oid_list {
528 + struct object_id *list;
529 + int nr;
530 + int alloc;
531 +};
532 +
533 +struct write_commit_graph_context {
534 + struct repository *r;
535 + const char *obj_dir;
536 + char *graph_name;
537 + struct packed_oid_list oids;
538 + struct packed_commit_list commits;
539 + int num_extra_edges;
540 + unsigned long approx_nr_objects;
541 + struct progress *progress;
542 + int progress_done;
543 + uint64_t progress_cnt;
544 + unsigned append:1,
545 + report_progress:1;
546 +};
547 +
548 static void write_graph_chunk_fanout(struct hashfile *f,
522 - struct commit **commits,
523 - int nr_commits,
524 - struct progress *progress,
525 - uint64_t *progress_cnt)
549 + struct write_commit_graph_context *ctx)
550 {
551 int i, count = 0;
528 - struct commit **list = commits;
552 + struct commit **list = ctx->commits.list;
553
554 /*
555 * Write the first-level table (the list is sorted,
@@ -533,10 +557,10 @@ static void write_graph_chunk_fanout(struct hashfile *f,
557 * having to do eight extra binary search iterations).
558 */
559 for (i = 0; i < 256; i++) {
536 - while (count < nr_commits) {
560 + while (count < ctx->commits.nr) {
561 if ((*list)->object.oid.hash[0] != i)
562 break;
539 - display_progress(progress, ++*progress_cnt);
563 + display_progress(ctx->progress, ++ctx->progress_cnt);
564 count++;
565 list++;
566 }
@@ -546,14 +570,12 @@ static void write_graph_chunk_fanout(struct hashfile *f,
570 }
571
572 static void write_graph_chunk_oids(struct hashfile *f, int hash_len,
549 - struct commit **commits, int nr_commits,
550 - struct progress *progress,
551 - uint64_t *progress_cnt)
573 + struct write_commit_graph_context *ctx)
574 {
553 - struct commit **list = commits;
575 + struct commit **list = ctx->commits.list;
576 int count;
555 - for (count = 0; count < nr_commits; count++, list++) {
556 - display_progress(progress, ++*progress_cnt);
577 + for (count = 0; count < ctx->commits.nr; count++, list++) {
578 + display_progress(ctx->progress, ++ctx->progress_cnt);
579 hashwrite(f, (*list)->object.oid.hash, (int)hash_len);
580 }
581 }
@@ -565,19 +587,17 @@ static const unsigned char *commit_to_sha1(size_t index, void *table)
587 }
588
589 static void write_graph_chunk_data(struct hashfile *f, int hash_len,
568 - struct commit **commits, int nr_commits,
569 - struct progress *progress,
570 - uint64_t *progress_cnt)
590 + struct write_commit_graph_context *ctx)
591 {
572 - struct commit **list = commits;
573 - struct commit **last = commits + nr_commits;
592 + struct commit **list = ctx->commits.list;
593 + struct commit **last = ctx->commits.list + ctx->commits.nr;
594 uint32_t num_extra_edges = 0;
595
596 while (list < last) {
597 struct commit_list *parent;
598 int edge_value;
599 uint32_t packedDate[2];
580 - display_progress(progress, ++*progress_cnt);
600 + display_progress(ctx->progress, ++ctx->progress_cnt);
601
602 parse_commit_no_graph(*list);
603 hashwrite(f, get_commit_tree_oid(*list)->hash, hash_len);
@@ -588,8 +608,8 @@ static void write_graph_chunk_data(struct hashfile *f, int hash_len,
608 edge_value = GRAPH_PARENT_NONE;
609 else {
610 edge_value = sha1_pos(parent->item->object.oid.hash,
591 - commits,
592 - nr_commits,
611 + ctx->commits.list,
612 + ctx->commits.nr,
613 commit_to_sha1);
614
615 if (edge_value < 0)
@@ -609,8 +629,8 @@ static void write_graph_chunk_data(struct hashfile *f, int hash_len,
629 edge_value = GRAPH_EXTRA_EDGES_NEEDED | num_extra_edges;
630 else {
631 edge_value = sha1_pos(parent->item->object.oid.hash,
612 - commits,
613 - nr_commits,
632 + ctx->commits.list,
633 + ctx->commits.nr,
634 commit_to_sha1);
635 if (edge_value < 0)
636 BUG("missing parent %s for commit %s",
@@ -642,19 +662,16 @@ static void write_graph_chunk_data(struct hashfile *f, int hash_len,
662 }
663
664 static void write_graph_chunk_extra_edges(struct hashfile *f,
645 - struct commit **commits,
646 - int nr_commits,
647 - struct progress *progress,
648 - uint64_t *progress_cnt)
665 + struct write_commit_graph_context *ctx)
666 {
650 - struct commit **list = commits;
651 - struct commit **last = commits + nr_commits;
667 + struct commit **list = ctx->commits.list;
668 + struct commit **last = ctx->commits.list + ctx->commits.nr;
669 struct commit_list *parent;
670
671 while (list < last) {
672 int num_parents = 0;
673
657 - display_progress(progress, ++*progress_cnt);
674 + display_progress(ctx->progress, ++ctx->progress_cnt);
675
676 for (parent = (*list)->parents; num_parents < 3 && parent;
677 parent = parent->next)
@@ -668,8 +685,8 @@ static void write_graph_chunk_extra_edges(struct hashfile *f,
685 /* Since num_parents > 2, this initializer is safe. */
686 for (parent = (*list)->parents->next; parent; parent = parent->next) {
687 int edge_value = sha1_pos(parent->item->object.oid.hash,
671 - commits,
672 - nr_commits,
688 + ctx->commits.list,
689 + ctx->commits.nr,
690 commit_to_sha1);
691
692 if (edge_value < 0)
@@ -693,125 +710,111 @@ static int commit_compare(const void *_a, const void *_b)
710 return oidcmp(a, b);
711 }
712
696 -struct packed_commit_list {
697 - struct commit **list;
698 - int nr;
699 - int alloc;
700 -};
701 -
702 -struct packed_oid_list {
703 - struct object_id *list;
704 - int nr;
705 - int alloc;
706 - struct progress *progress;
707 - int progress_done;
708 -};
709 -
713 static int add_packed_commits(const struct object_id *oid,
714 struct packed_git *pack,
715 uint32_t pos,
716 void *data)
717 {
715 - struct packed_oid_list *list = (struct packed_oid_list*)data;
718 + struct write_commit_graph_context *ctx = (struct write_commit_graph_context*)data;
719 enum object_type type;
720 off_t offset = nth_packed_object_offset(pack, pos);
721 struct object_info oi = OBJECT_INFO_INIT;
722
720 - if (list->progress)
721 - display_progress(list->progress, ++list->progress_done);
723 + if (ctx->progress)
724 + display_progress(ctx->progress, ++ctx->progress_done);
725
726 oi.typep = &type;
724 - if (packed_object_info(the_repository, pack, offset, &oi) < 0)
727 + if (packed_object_info(ctx->r, pack, offset, &oi) < 0)
728 die(_("unable to get type of object %s"), oid_to_hex(oid));
729
730 if (type != OBJ_COMMIT)
731 return 0;
732
730 - ALLOC_GROW(list->list, list->nr + 1, list->alloc);
731 - oidcpy(&(list->list[list->nr]), oid);
732 - list->nr++;
733 + ALLOC_GROW(ctx->oids.list, ctx->oids.nr + 1, ctx->oids.alloc);
734 + oidcpy(&(ctx->oids.list[ctx->oids.nr]), oid);
735 + ctx->oids.nr++;
736
737 return 0;
738 }
739
737 -static void add_missing_parents(struct packed_oid_list *oids, struct commit *commit)
740 +static void add_missing_parents(struct write_commit_graph_context *ctx, struct commit *commit)
741 {
742 struct commit_list *parent;
743 for (parent = commit->parents; parent; parent = parent->next) {
744 if (!(parent->item->object.flags & UNINTERESTING)) {
742 - ALLOC_GROW(oids->list, oids->nr + 1, oids->alloc);
743 - oidcpy(&oids->list[oids->nr], &(parent->item->object.oid));
744 - oids->nr++;
745 + ALLOC_GROW(ctx->oids.list, ctx->oids.nr + 1, ctx->oids.alloc);
746 + oidcpy(&ctx->oids.list[ctx->oids.nr], &(parent->item->object.oid));
747 + ctx->oids.nr++;
748 parent->item->object.flags |= UNINTERESTING;
749 }
750 }
751 }
752
750 -static void close_reachable(struct packed_oid_list *oids, int report_progress)
753 +static void close_reachable(struct write_commit_graph_context *ctx)
754 {
755 int i;
756 struct commit *commit;
754 - struct progress *progress = NULL;
757
756 - if (report_progress)
757 - progress = start_delayed_progress(
758 - _("Loading known commits in commit graph"), oids->nr);
759 - for (i = 0; i < oids->nr; i++) {
760 - display_progress(progress, i + 1);
761 - commit = lookup_commit(the_repository, &oids->list[i]);
758 + if (ctx->report_progress)
759 + ctx->progress = start_delayed_progress(
760 + _("Loading known commits in commit graph"),
761 + ctx->oids.nr);
762 + for (i = 0; i < ctx->oids.nr; i++) {
763 + display_progress(ctx->progress, i + 1);
764 + commit = lookup_commit(ctx->r, &ctx->oids.list[i]);
765 if (commit)
766 commit->object.flags |= UNINTERESTING;
767 }
765 - stop_progress(&progress);
768 + stop_progress(&ctx->progress);
769
770 /*
768 - * As this loop runs, oids->nr may grow, but not more
771 + * As this loop runs, ctx->oids.nr may grow, but not more
772 * than the number of missing commits in the reachable
773 * closure.
774 */
772 - if (report_progress)
773 - progress = start_delayed_progress(
774 - _("Expanding reachable commits in commit graph"), oids->nr);
775 - for (i = 0; i < oids->nr; i++) {
776 - display_progress(progress, i + 1);
777 - commit = lookup_commit(the_repository, &oids->list[i]);
775 + if (ctx->report_progress)
776 + ctx->progress = start_delayed_progress(
777 + _("Expanding reachable commits in commit graph"),
778 + ctx->oids.nr);
779 + for (i = 0; i < ctx->oids.nr; i++) {
780 + display_progress(ctx->progress, i + 1);
781 + commit = lookup_commit(ctx->r, &ctx->oids.list[i]);
782
783 if (commit && !parse_commit_no_graph(commit))
780 - add_missing_parents(oids, commit);
784 + add_missing_parents(ctx, commit);
785 }
782 - stop_progress(&progress);
786 + stop_progress(&ctx->progress);
787
784 - if (report_progress)
785 - progress = start_delayed_progress(
786 - _("Clearing commit marks in commit graph"), oids->nr);
787 - for (i = 0; i < oids->nr; i++) {
788 - display_progress(progress, i + 1);
789 - commit = lookup_commit(the_repository, &oids->list[i]);
788 + if (ctx->report_progress)
789 + ctx->progress = start_delayed_progress(
790 + _("Clearing commit marks in commit graph"),
791 + ctx->oids.nr);
792 + for (i = 0; i < ctx->oids.nr; i++) {
793 + display_progress(ctx->progress, i + 1);
794 + commit = lookup_commit(ctx->r, &ctx->oids.list[i]);
795
796 if (commit)
797 commit->object.flags &= ~UNINTERESTING;
798 }
794 - stop_progress(&progress);
799 + stop_progress(&ctx->progress);
800 }
801
797 -static void compute_generation_numbers(struct packed_commit_list* commits,
798 - int report_progress)
802 +static void compute_generation_numbers(struct write_commit_graph_context *ctx)
803 {
804 int i;
805 struct commit_list *list = NULL;
802 - struct progress *progress = NULL;
806
804 - if (report_progress)
805 - progress = start_progress(
806 - _("Computing commit graph generation numbers"),
807 - commits->nr);
808 - for (i = 0; i < commits->nr; i++) {
809 - display_progress(progress, i + 1);
810 - if (commits->list[i]->generation != GENERATION_NUMBER_INFINITY &&
811 - commits->list[i]->generation != GENERATION_NUMBER_ZERO)
807 + if (ctx->report_progress)
808 + ctx->progress = start_progress(
809 + _("Computing commit graph generation numbers"),
810 + ctx->commits.nr);
811 + for (i = 0; i < ctx->commits.nr; i++) {
812 + display_progress(ctx->progress, i + 1);
813 + if (ctx->commits.list[i]->generation != GENERATION_NUMBER_INFINITY &&
814 + ctx->commits.list[i]->generation != GENERATION_NUMBER_ZERO)
815 continue;
816
814 - commit_list_insert(commits->list[i], &list);
817 + commit_list_insert(ctx->commits.list[i], &list);
818 while (list) {
819 struct commit *current = list->item;
820 struct commit_list *parent;
@@ -838,7 +841,7 @@ static void compute_generation_numbers(struct packed_commit_list* commits,
841 }
842 }
843 }
841 - stop_progress(&progress);
844 + stop_progress(&ctx->progress);
845 }
846
847 static int add_ref_to_list(const char *refname,
@@ -869,8 +872,7 @@ int write_commit_graph(const char *obj_dir,
872 struct string_list *commit_hex,
873 unsigned int flags)
874 {
872 - struct packed_oid_list oids;
873 - struct packed_commit_list commits;
875 + struct write_commit_graph_context *ctx;
876 struct hashfile *f;
877 uint32_t i, count_distinct = 0;
878 char *graph_name = NULL;
@@ -878,44 +880,38 @@ int write_commit_graph(const char *obj_dir,
880 uint32_t chunk_ids[5];
881 uint64_t chunk_offsets[5];
882 int num_chunks;
881 - int num_extra_edges;
883 struct commit_list *parent;
883 - struct progress *progress = NULL;
884 const unsigned hashsz = the_hash_algo->rawsz;
885 - uint64_t progress_cnt = 0;
885 struct strbuf progress_title = STRBUF_INIT;
887 - unsigned long approx_nr_objects;
886 int res = 0;
889 - int append = flags & COMMIT_GRAPH_APPEND;
890 - int report_progress = flags & COMMIT_GRAPH_PROGRESS;
887
888 if (!commit_graph_compatible(the_repository))
889 return 0;
890
895 - oids.nr = 0;
896 - approx_nr_objects = approximate_object_count();
897 - oids.alloc = approx_nr_objects / 32;
898 - oids.progress = NULL;
899 - oids.progress_done = 0;
900 - commits.list = NULL;
901 -
902 - if (append) {
903 - prepare_commit_graph_one(the_repository, obj_dir);
904 - if (the_repository->objects->commit_graph)
905 - oids.alloc += the_repository->objects->commit_graph->num_commits;
891 + ctx = xcalloc(1, sizeof(struct write_commit_graph_context));
892 + ctx->r = the_repository;
893 + ctx->obj_dir = obj_dir;
894 + ctx->append = flags & COMMIT_GRAPH_APPEND ? 1 : 0;
895 + ctx->report_progress = flags & COMMIT_GRAPH_PROGRESS ? 1 : 0;
896 +
897 + ctx->approx_nr_objects = approximate_object_count();
898 + ctx->oids.alloc = ctx->approx_nr_objects / 32;
899 +
900 + if (ctx->append) {
901 + prepare_commit_graph_one(ctx->r, ctx->obj_dir);
902 + if (ctx->r->objects->commit_graph)
903 + ctx->oids.alloc += ctx->r->objects->commit_graph->num_commits;
904 }
905
908 - if (oids.alloc < 1024)
909 - oids.alloc = 1024;
910 - ALLOC_ARRAY(oids.list, oids.alloc);
911 -
912 - if (append && the_repository->objects->commit_graph) {
913 - struct commit_graph *commit_graph =
914 - the_repository->objects->commit_graph;
915 - for (i = 0; i < commit_graph->num_commits; i++) {
916 - const unsigned char *hash = commit_graph->chunk_oid_lookup +
917 - commit_graph->hash_len * i;
918 - hashcpy(oids.list[oids.nr++].hash, hash);
906 + if (ctx->oids.alloc < 1024)
907 + ctx->oids.alloc = 1024;
908 + ALLOC_ARRAY(ctx->oids.list, ctx->oids.alloc);
909 +
910 + if (ctx->append && ctx->r->objects->commit_graph) {
911 + struct commit_graph *g = ctx->r->objects->commit_graph;
912 + for (i = 0; i < g->num_commits; i++) {
913 + const unsigned char *hash = g->chunk_oid_lookup + g->hash_len * i;
914 + hashcpy(ctx->oids.list[ctx->oids.nr++].hash, hash);
915 }
916 }
917
@@ -924,14 +920,14 @@ int write_commit_graph(const char *obj_dir,
920 int dirlen;
921 strbuf_addf(&packname, "%s/pack/", obj_dir);
922 dirlen = packname.len;
927 - if (report_progress) {
923 + if (ctx->report_progress) {
924 strbuf_addf(&progress_title,
925 Q_("Finding commits for commit graph in %d pack",
926 "Finding commits for commit graph in %d packs",
927 pack_indexes->nr),
928 pack_indexes->nr);
933 - oids.progress = start_delayed_progress(progress_title.buf, 0);
934 - oids.progress_done = 0;
929 + ctx->progress = start_delayed_progress(progress_title.buf, 0);
930 + ctx->progress_done = 0;
931 }
932 for (i = 0; i < pack_indexes->nr; i++) {
933 struct packed_git *p;
@@ -948,75 +944,76 @@ int write_commit_graph(const char *obj_dir,
944 res = -1;
945 goto cleanup;
946 }
951 - for_each_object_in_pack(p, add_packed_commits, &oids,
947 + for_each_object_in_pack(p, add_packed_commits, ctx,
948 FOR_EACH_OBJECT_PACK_ORDER);
949 close_pack(p);
950 free(p);
951 }
956 - stop_progress(&oids.progress);
952 + stop_progress(&ctx->progress);
953 strbuf_reset(&progress_title);
954 strbuf_release(&packname);
955 }
956
957 if (commit_hex) {
962 - if (report_progress) {
958 + if (ctx->report_progress) {
959 strbuf_addf(&progress_title,
960 Q_("Finding commits for commit graph from %d ref",
961 "Finding commits for commit graph from %d refs",
962 commit_hex->nr),
963 commit_hex->nr);
968 - progress = start_delayed_progress(progress_title.buf,
969 - commit_hex->nr);
964 + ctx->progress = start_delayed_progress(
965 + progress_title.buf,
966 + commit_hex->nr);
967 }
968 for (i = 0; i < commit_hex->nr; i++) {
969 const char *end;
970 struct object_id oid;
971 struct commit *result;
972
976 - display_progress(progress, i + 1);
973 + display_progress(ctx->progress, i + 1);
974 if (commit_hex->items[i].string &&
975 parse_oid_hex(commit_hex->items[i].string, &oid, &end))
976 continue;
977
981 - result = lookup_commit_reference_gently(the_repository, &oid, 1);
978 + result = lookup_commit_reference_gently(ctx->r, &oid, 1);
979
980 if (result) {
984 - ALLOC_GROW(oids.list, oids.nr + 1, oids.alloc);
985 - oidcpy(&oids.list[oids.nr], &(result->object.oid));
986 - oids.nr++;
981 + ALLOC_GROW(ctx->oids.list, ctx->oids.nr + 1, ctx->oids.alloc);
982 + oidcpy(&ctx->oids.list[ctx->oids.nr], &(result->object.oid));
983 + ctx->oids.nr++;
984 }
985 }
989 - stop_progress(&progress);
986 + stop_progress(&ctx->progress);
987 strbuf_reset(&progress_title);
988 }
989
990 if (!pack_indexes && !commit_hex) {
994 - if (report_progress)
995 - oids.progress = start_delayed_progress(
991 + if (ctx->report_progress)
992 + ctx->progress = start_delayed_progress(
993 _("Finding commits for commit graph among packed objects"),
997 - approx_nr_objects);
998 - for_each_packed_object(add_packed_commits, &oids,
994 + ctx->approx_nr_objects);
995 + for_each_packed_object(add_packed_commits, ctx,
996 FOR_EACH_OBJECT_PACK_ORDER);
1000 - if (oids.progress_done < approx_nr_objects)
1001 - display_progress(oids.progress, approx_nr_objects);
1002 - stop_progress(&oids.progress);
997 + if (ctx->progress_done < ctx->approx_nr_objects)
998 + display_progress(ctx->progress, ctx->approx_nr_objects);
999 + stop_progress(&ctx->progress);
1000 }
1001
1005 - close_reachable(&oids, report_progress);
1002 + close_reachable(ctx);
1003
1007 - if (report_progress)
1008 - progress = start_delayed_progress(
1004 + if (ctx->report_progress)
1005 + ctx->progress = start_delayed_progress(
1006 _("Counting distinct commits in commit graph"),
1010 - oids.nr);
1011 - display_progress(progress, 0); /* TODO: Measure QSORT() progress */
1012 - QSORT(oids.list, oids.nr, commit_compare);
1007 + ctx->oids.nr);
1008 + display_progress(ctx->progress, 0); /* TODO: Measure QSORT() progress */
1009 + QSORT(ctx->oids.list, ctx->oids.nr, commit_compare);
1010 count_distinct = 1;
1014 - for (i = 1; i < oids.nr; i++) {
1015 - display_progress(progress, i + 1);
1016 - if (!oideq(&oids.list[i - 1], &oids.list[i]))
1011 + for (i = 1; i < ctx->oids.nr; i++) {
1012 + display_progress(ctx->progress, i + 1);
1013 + if (!oideq(&ctx->oids.list[i - 1], &ctx->oids.list[i]))
1014 count_distinct++;
1015 }
1019 - stop_progress(&progress);
1016 + stop_progress(&ctx->progress);
1017
1018 if (count_distinct >= GRAPH_EDGE_LAST_MASK) {
1019 error(_("the commit graph format cannot write %d commits"), count_distinct);
@@ -1024,54 +1021,54 @@ int write_commit_graph(const char *obj_dir,
1021 goto cleanup;
1022 }
1023
1027 - commits.nr = 0;
1028 - commits.alloc = count_distinct;
1029 - ALLOC_ARRAY(commits.list, commits.alloc);
1024 + ctx->commits.alloc = count_distinct;
1025 + ALLOC_ARRAY(ctx->commits.list, ctx->commits.alloc);
1026
1031 - num_extra_edges = 0;
1032 - if (report_progress)
1033 - progress = start_delayed_progress(
1027 + ctx->num_extra_edges = 0;
1028 + if (ctx->report_progress)
1029 + ctx->progress = start_delayed_progress(
1030 _("Finding extra edges in commit graph"),
1035 - oids.nr);
1036 - for (i = 0; i < oids.nr; i++) {
1031 + ctx->oids.nr);
1032 + for (i = 0; i < ctx->oids.nr; i++) {
1033 int num_parents = 0;
1038 - display_progress(progress, i + 1);
1039 - if (i > 0 && oideq(&oids.list[i - 1], &oids.list[i]))
1034 + display_progress(ctx->progress, i + 1);
1035 + if (i > 0 && oideq(&ctx->oids.list[i - 1], &ctx->oids.list[i]))
1036 continue;
1037
1042 - commits.list[commits.nr] = lookup_commit(the_repository, &oids.list[i]);
1043 - parse_commit_no_graph(commits.list[commits.nr]);
1038 + ctx->commits.list[ctx->commits.nr] = lookup_commit(ctx->r, &ctx->oids.list[i]);
1039 + parse_commit_no_graph(ctx->commits.list[ctx->commits.nr]);
1040
1045 - for (parent = commits.list[commits.nr]->parents;
1041 + for (parent = ctx->commits.list[ctx->commits.nr]->parents;
1042 parent; parent = parent->next)
1043 num_parents++;
1044
1045 if (num_parents > 2)
1050 - num_extra_edges += num_parents - 1;
1046 + ctx->num_extra_edges += num_parents - 1;
1047
1052 - commits.nr++;
1048 + ctx->commits.nr++;
1049 }
1054 - num_chunks = num_extra_edges ? 4 : 3;
1055 - stop_progress(&progress);
1050 + stop_progress(&ctx->progress);
1051
1057 - if (commits.nr >= GRAPH_EDGE_LAST_MASK) {
1052 + if (ctx->commits.nr >= GRAPH_EDGE_LAST_MASK) {
1053 error(_("too many commits to write graph"));
1054 res = -1;
1055 goto cleanup;
1056 }
1057
1063 - compute_generation_numbers(&commits, report_progress);
1058 + compute_generation_numbers(ctx);
1059
1065 - graph_name = get_commit_graph_filename(obj_dir);
1066 - if (safe_create_leading_directories(graph_name)) {
1067 - UNLEAK(graph_name);
1060 + num_chunks = ctx->num_extra_edges ? 4 : 3;
1061 +
1062 + ctx->graph_name = get_commit_graph_filename(ctx->obj_dir);
1063 + if (safe_create_leading_directories(ctx->graph_name)) {
1064 + UNLEAK(ctx->graph_name);
1065 error(_("unable to create leading directories of %s"),
1069 - graph_name);
1066 + ctx->graph_name);
1067 res = -1;
1068 goto cleanup;
1069 }
1070
1074 - hold_lock_file_for_update(&lk, graph_name, LOCK_DIE_ON_ERROR);
1071 + hold_lock_file_for_update(&lk, ctx->graph_name, LOCK_DIE_ON_ERROR);
1072 f = hashfd(lk.tempfile->fd, lk.tempfile->filename.buf);
1073
1074 hashwrite_be32(f, GRAPH_SIGNATURE);
@@ -1084,7 +1081,7 @@ int write_commit_graph(const char *obj_dir,
1081 chunk_ids[0] = GRAPH_CHUNKID_OIDFANOUT;
1082 chunk_ids[1] = GRAPH_CHUNKID_OIDLOOKUP;
1083 chunk_ids[2] = GRAPH_CHUNKID_DATA;
1087 - if (num_extra_edges)
1084 + if (ctx->num_extra_edges)
1085 chunk_ids[3] = GRAPH_CHUNKID_EXTRAEDGES;
1086 else
1087 chunk_ids[3] = 0;
@@ -1092,9 +1089,9 @@ int write_commit_graph(const char *obj_dir,
1089
1090 chunk_offsets[0] = 8 + (num_chunks + 1) * GRAPH_CHUNKLOOKUP_WIDTH;
1091 chunk_offsets[1] = chunk_offsets[0] + GRAPH_FANOUT_SIZE;
1095 - chunk_offsets[2] = chunk_offsets[1] + hashsz * commits.nr;
1096 - chunk_offsets[3] = chunk_offsets[2] + (hashsz + 16) * commits.nr;
1097 - chunk_offsets[4] = chunk_offsets[3] + 4 * num_extra_edges;
1092 + chunk_offsets[2] = chunk_offsets[1] + hashsz * ctx->commits.nr;
1093 + chunk_offsets[3] = chunk_offsets[2] + (hashsz + 16) * ctx->commits.nr;
1094 + chunk_offsets[4] = chunk_offsets[3] + 4 * ctx->num_extra_edges;
1095
1096 for (i = 0; i <= num_chunks; i++) {
1097 uint32_t chunk_write[3];
@@ -1105,32 +1102,33 @@ int write_commit_graph(const char *obj_dir,
1102 hashwrite(f, chunk_write, 12);
1103 }
1104
1108 - if (report_progress) {
1105 + if (ctx->report_progress) {
1106 strbuf_addf(&progress_title,
1107 Q_("Writing out commit graph in %d pass",
1108 "Writing out commit graph in %d passes",
1109 num_chunks),
1110 num_chunks);
1114 - progress = start_delayed_progress(
1111 + ctx->progress = start_delayed_progress(
1112 progress_title.buf,
1116 - num_chunks * commits.nr);
1113 + num_chunks * ctx->commits.nr);
1114 }
1118 - write_graph_chunk_fanout(f, commits.list, commits.nr, progress, &progress_cnt);
1119 - write_graph_chunk_oids(f, hashsz, commits.list, commits.nr, progress, &progress_cnt);
1120 - write_graph_chunk_data(f, hashsz, commits.list, commits.nr, progress, &progress_cnt);
1121 - if (num_extra_edges)
1122 - write_graph_chunk_extra_edges(f, commits.list, commits.nr, progress, &progress_cnt);
1123 - stop_progress(&progress);
1115 + write_graph_chunk_fanout(f, ctx);
1116 + write_graph_chunk_oids(f, hashsz, ctx);
1117 + write_graph_chunk_data(f, hashsz, ctx);
1118 + if (ctx->num_extra_edges)
1119 + write_graph_chunk_extra_edges(f, ctx);
1120 + stop_progress(&ctx->progress);
1121 strbuf_release(&progress_title);
1122
1126 - close_commit_graph(the_repository);
1123 + close_commit_graph(ctx->r);
1124 finalize_hashfile(f, NULL, CSUM_HASH_IN_STREAM | CSUM_FSYNC);
1125 commit_lock_file(&lk);
1126
1127 cleanup:
1128 free(graph_name);
1132 - free(commits.list);
1133 - free(oids.list);
1129 + free(ctx->commits.list);
1130 + free(ctx->oids.list);
1131 + free(ctx);
1132
1133 return res;
1134 }