|
18 | 18 | #include "tree.h"
|
19 | 19 | #include "tree-walk.h"
|
20 | 20 | #include "pseudo-merge.h"
|
| 21 | +#include "oid-array.h" |
21 | 22 |
|
22 | 23 | struct bitmapped_commit {
|
23 | 24 | struct commit *commit;
|
@@ -771,6 +772,130 @@ static void write_selected_commits_v1(struct bitmap_writer *writer,
|
771 | 772 | }
|
772 | 773 | }
|
773 | 774 |
|
| 775 | +static void write_pseudo_merges(struct bitmap_writer *writer, |
| 776 | + struct hashfile *f) |
| 777 | +{ |
| 778 | + struct oid_array commits = OID_ARRAY_INIT; |
| 779 | + struct bitmap **commits_bitmap = NULL; |
| 780 | + off_t *pseudo_merge_ofs = NULL; |
| 781 | + off_t start, table_start, next_ext; |
| 782 | + |
| 783 | + uint32_t base = bitmap_writer_nr_selected_commits(writer); |
| 784 | + size_t i, j = 0; |
| 785 | + |
| 786 | + CALLOC_ARRAY(commits_bitmap, writer->pseudo_merges_nr); |
| 787 | + CALLOC_ARRAY(pseudo_merge_ofs, writer->pseudo_merges_nr); |
| 788 | + |
| 789 | + for (i = 0; i < writer->pseudo_merges_nr; i++) { |
| 790 | + struct bitmapped_commit *merge = &writer->selected[base + i]; |
| 791 | + struct commit_list *p; |
| 792 | + |
| 793 | + if (!merge->pseudo_merge) |
| 794 | + BUG("found non-pseudo merge commit at %"PRIuMAX, (uintmax_t)i); |
| 795 | + |
| 796 | + commits_bitmap[i] = bitmap_new(); |
| 797 | + |
| 798 | + for (p = merge->commit->parents; p; p = p->next) |
| 799 | + bitmap_set(commits_bitmap[i], |
| 800 | + find_object_pos(writer, &p->item->object.oid, |
| 801 | + NULL)); |
| 802 | + } |
| 803 | + |
| 804 | + start = hashfile_total(f); |
| 805 | + |
| 806 | + for (i = 0; i < writer->pseudo_merges_nr; i++) { |
| 807 | + struct ewah_bitmap *commits_ewah = bitmap_to_ewah(commits_bitmap[i]); |
| 808 | + |
| 809 | + pseudo_merge_ofs[i] = hashfile_total(f); |
| 810 | + |
| 811 | + dump_bitmap(f, commits_ewah); |
| 812 | + dump_bitmap(f, writer->selected[base+i].write_as); |
| 813 | + |
| 814 | + ewah_free(commits_ewah); |
| 815 | + } |
| 816 | + |
| 817 | + next_ext = st_add(hashfile_total(f), |
| 818 | + st_mult(kh_size(writer->pseudo_merge_commits), |
| 819 | + sizeof(uint64_t))); |
| 820 | + |
| 821 | + table_start = hashfile_total(f); |
| 822 | + |
| 823 | + commits.alloc = kh_size(writer->pseudo_merge_commits); |
| 824 | + CALLOC_ARRAY(commits.oid, commits.alloc); |
| 825 | + |
| 826 | + for (i = kh_begin(writer->pseudo_merge_commits); i != kh_end(writer->pseudo_merge_commits); i++) { |
| 827 | + if (!kh_exist(writer->pseudo_merge_commits, i)) |
| 828 | + continue; |
| 829 | + oid_array_append(&commits, &kh_key(writer->pseudo_merge_commits, i)); |
| 830 | + } |
| 831 | + |
| 832 | + oid_array_sort(&commits); |
| 833 | + |
| 834 | + /* write lookup table (non-extended) */ |
| 835 | + for (i = 0; i < commits.nr; i++) { |
| 836 | + int hash_pos; |
| 837 | + struct pseudo_merge_commit_idx *c; |
| 838 | + |
| 839 | + hash_pos = kh_get_oid_map(writer->pseudo_merge_commits, |
| 840 | + commits.oid[i]); |
| 841 | + if (hash_pos == kh_end(writer->pseudo_merge_commits)) |
| 842 | + BUG("could not find pseudo-merge commit %s", |
| 843 | + oid_to_hex(&commits.oid[i])); |
| 844 | + |
| 845 | + c = kh_value(writer->pseudo_merge_commits, hash_pos); |
| 846 | + |
| 847 | + hashwrite_be32(f, find_object_pos(writer, &commits.oid[i], |
| 848 | + NULL)); |
| 849 | + if (c->nr == 1) |
| 850 | + hashwrite_be64(f, pseudo_merge_ofs[c->pseudo_merge[0]]); |
| 851 | + else if (c->nr > 1) { |
| 852 | + if (next_ext & ((uint64_t)1<<63)) |
| 853 | + die(_("too many pseudo-merges")); |
| 854 | + hashwrite_be64(f, next_ext | ((uint64_t)1<<63)); |
| 855 | + next_ext = st_add3(next_ext, |
| 856 | + sizeof(uint32_t), |
| 857 | + st_mult(c->nr, sizeof(uint64_t))); |
| 858 | + } else |
| 859 | + BUG("expected commit '%s' to have at least one " |
| 860 | + "pseudo-merge", oid_to_hex(&commits.oid[i])); |
| 861 | + } |
| 862 | + |
| 863 | + /* write lookup table (extended) */ |
| 864 | + for (i = 0; i < commits.nr; i++) { |
| 865 | + int hash_pos; |
| 866 | + struct pseudo_merge_commit_idx *c; |
| 867 | + |
| 868 | + hash_pos = kh_get_oid_map(writer->pseudo_merge_commits, |
| 869 | + commits.oid[i]); |
| 870 | + if (hash_pos == kh_end(writer->pseudo_merge_commits)) |
| 871 | + BUG("could not find pseudo-merge commit %s", |
| 872 | + oid_to_hex(&commits.oid[i])); |
| 873 | + |
| 874 | + c = kh_value(writer->pseudo_merge_commits, hash_pos); |
| 875 | + if (c->nr == 1) |
| 876 | + continue; |
| 877 | + |
| 878 | + hashwrite_be32(f, c->nr); |
| 879 | + for (j = 0; j < c->nr; j++) |
| 880 | + hashwrite_be64(f, pseudo_merge_ofs[c->pseudo_merge[j]]); |
| 881 | + } |
| 882 | + |
| 883 | + /* write positions for all pseudo merges */ |
| 884 | + for (i = 0; i < writer->pseudo_merges_nr; i++) |
| 885 | + hashwrite_be64(f, pseudo_merge_ofs[i]); |
| 886 | + |
| 887 | + hashwrite_be32(f, writer->pseudo_merges_nr); |
| 888 | + hashwrite_be32(f, kh_size(writer->pseudo_merge_commits)); |
| 889 | + hashwrite_be64(f, table_start - start); |
| 890 | + hashwrite_be64(f, hashfile_total(f) - start + sizeof(uint64_t)); |
| 891 | + |
| 892 | + for (i = 0; i < writer->pseudo_merges_nr; i++) |
| 893 | + bitmap_free(commits_bitmap[i]); |
| 894 | + |
| 895 | + free(pseudo_merge_ofs); |
| 896 | + free(commits_bitmap); |
| 897 | +} |
| 898 | + |
774 | 899 | static int table_cmp(const void *_va, const void *_vb, void *_data)
|
775 | 900 | {
|
776 | 901 | struct bitmap_writer *writer = _data;
|
@@ -878,6 +1003,9 @@ void bitmap_writer_finish(struct bitmap_writer *writer,
|
878 | 1003 |
|
879 | 1004 | int fd = odb_mkstemp(&tmp_file, "pack/tmp_bitmap_XXXXXX");
|
880 | 1005 |
|
| 1006 | + if (writer->pseudo_merges_nr) |
| 1007 | + options |= BITMAP_OPT_PSEUDO_MERGES; |
| 1008 | + |
881 | 1009 | f = hashfd(fd, tmp_file.buf);
|
882 | 1010 |
|
883 | 1011 | memcpy(header.magic, BITMAP_IDX_SIGNATURE, sizeof(BITMAP_IDX_SIGNATURE));
|
@@ -907,6 +1035,9 @@ void bitmap_writer_finish(struct bitmap_writer *writer,
|
907 | 1035 |
|
908 | 1036 | write_selected_commits_v1(writer, f, offsets);
|
909 | 1037 |
|
| 1038 | + if (options & BITMAP_OPT_PSEUDO_MERGES) |
| 1039 | + write_pseudo_merges(writer, f); |
| 1040 | + |
910 | 1041 | if (options & BITMAP_OPT_LOOKUP_TABLE)
|
911 | 1042 | write_lookup_table(writer, f, offsets);
|
912 | 1043 |
|
|
0 commit comments