651
static void write_selected_commits_v1(struct hashfile *f,
652
struct pack_idx_entry **index,
653
uint32_t index_nr,
654
- uint32_t *commit_positions)
654
+ uint32_t *commit_positions,
655
+ off_t *offsets)
656
{
657
int i;
658
659
for (i = 0; i < writer.selected_nr; ++i) {
660
struct bitmapped_commit *stored = &writer.selected[i];
661
662
+ if (offsets)
663
+ offsets[i] = hashfile_total(f);
664
+
665
hashwrite_be32(f, commit_positions[i]);
666
hashwrite_u8(f, stored->xor_offset);
667
hashwrite_u8(f, stored->flags);
670
}
671
}
672
673
+static int table_cmp(const void *_va, const void *_vb, void *_data)
674
+{
675
+ uint32_t *commit_positions = _data;
676
+ uint32_t a = commit_positions[*(uint32_t *)_va];
677
+ uint32_t b = commit_positions[*(uint32_t *)_vb];
678
+
679
+ if (a > b)
680
+ return 1;
681
+ else if (a < b)
682
+ return -1;
683
+
684
+ return 0;
685
+}
686
+
687
+static void write_lookup_table(struct hashfile *f,
688
+ struct pack_idx_entry **index,
689
+ uint32_t index_nr,
690
+ uint32_t *commit_positions,
691
+ off_t *offsets)
692
+{
693
+ uint32_t i;
694
+ uint32_t *table, *table_inv;
695
+
696
+ ALLOC_ARRAY(table, writer.selected_nr);
697
+ ALLOC_ARRAY(table_inv, writer.selected_nr);
698
+
699
+ for (i = 0; i < writer.selected_nr; i++)
700
+ table[i] = i;
701
+
702
+ /*
703
+ * At the end of this sort table[j] = i means that the i'th
704
+ * bitmap corresponds to j'th bitmapped commit (among the selected
705
+ * commits) in lex order of OIDs.
706
+ */
707
+ QSORT_S(table, writer.selected_nr, table_cmp, commit_positions);
708
+
709
+ /* table_inv helps us discover that relationship (i'th bitmap
710
+ * to j'th commit by j = table_inv[i])
711
+ */
712
+ for (i = 0; i < writer.selected_nr; i++)
713
+ table_inv[table[i]] = i;
714
+
715
+ trace2_region_enter("pack-bitmap-write", "writing_lookup_table", the_repository);
716
+ for (i = 0; i < writer.selected_nr; i++) {
717
+ struct bitmapped_commit *selected = &writer.selected[table[i]];
718
+ uint32_t xor_offset = selected->xor_offset;
719
+ uint32_t xor_row;
720
+
721
+ if (xor_offset) {
722
+ /*
723
+ * xor_index stores the index (in the bitmap entries)
724
+ * of the corresponding xor bitmap. But we need to convert
725
+ * this index into lookup table's index. So, table_inv[xor_index]
726
+ * gives us the index position w.r.t. the lookup table.
727
+ *
728
+ * If "k = table[i] - xor_offset" then the xor base is the k'th
729
+ * bitmap. `table_inv[k]` gives us the position of that bitmap
730
+ * in the lookup table.
731
+ */
732
+ uint32_t xor_index = table[i] - xor_offset;
733
+ xor_row = table_inv[xor_index];
734
+ } else {
735
+ xor_row = 0xffffffff;
736
+ }
737
+
738
+ hashwrite_be32(f, commit_positions[table[i]]);
739
+ hashwrite_be64(f, (uint64_t)offsets[table[i]]);
740
+ hashwrite_be32(f, xor_row);
741
+ }
742
+ trace2_region_leave("pack-bitmap-write", "writing_lookup_table", the_repository);
743
+
744
+ free(table);
745
+ free(table_inv);
746
+}
747
+
748
static void write_hash_cache(struct hashfile *f,
749
struct pack_idx_entry **index,
750
uint32_t index_nr)
772
struct strbuf tmp_file = STRBUF_INIT;
773
struct hashfile *f;
774
uint32_t *commit_positions = NULL;
775
+ off_t *offsets = NULL;
776
uint32_t i;
777
778
struct bitmap_disk_header header;
793
dump_bitmap(f, writer.blobs);
794
dump_bitmap(f, writer.tags);
795
796
+ if (options & BITMAP_OPT_LOOKUP_TABLE)
797
+ CALLOC_ARRAY(offsets, index_nr);
798
+
799
ALLOC_ARRAY(commit_positions, writer.selected_nr);
800
801
for (i = 0; i < writer.selected_nr; i++) {
808
commit_positions[i] = commit_pos;
809
}
810
728
- write_selected_commits_v1(f, index, index_nr, commit_positions);
811
+ write_selected_commits_v1(f, index, index_nr, commit_positions, offsets);
812
+
813
+ if (options & BITMAP_OPT_LOOKUP_TABLE)
814
+ write_lookup_table(f, index, index_nr, commit_positions, offsets);
815
816
if (options & BITMAP_OPT_HASH_CACHE)
817
write_hash_cache(f, index, index_nr);
827
828
strbuf_release(&tmp_file);
829
free(commit_positions);
830
+ free(offsets);
831
}