Skip to content

Commit 93eb41e

Browse files
Abhra303ttaylorr
authored andcommitted
pack-bitmap-write.c: write lookup table extension
The bitmap lookup table extension was documented by an earlier change, but Git does not yet know how to write that extension. Teach Git to write bitmap lookup table extension. The table contains the list of `N` <commit_pos, offset, xor_row>` triplets. These triplets are sorted according to their commit pos (ascending order). The meaning of each data in the i'th triplet is given below: - commit_pos stores commit position (in the pack-index or midx). It is a 4 byte network byte order unsigned integer. - offset is the position (in the bitmap file) from which that commit's bitmap can be read. - xor_row is the position of the triplet in the lookup table whose bitmap is used to compress this bitmap, or `0xffffffff` if no such bitmap exists. Mentored-by: Taylor Blau <[email protected]> Co-mentored-by: Kaartic Sivaraam <[email protected]> Co-authored-by: Taylor Blau <[email protected]> Signed-off-by: Abhradeep Chakraborty <[email protected]> Reviewed-by: Taylor Blau <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent aa30162 commit 93eb41e

File tree

2 files changed

+92
-4
lines changed

2 files changed

+92
-4
lines changed

pack-bitmap-write.c

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -651,13 +651,17 @@ static const struct object_id *oid_access(size_t pos, const void *table)
651651
static void write_selected_commits_v1(struct hashfile *f,
652652
struct pack_idx_entry **index,
653653
uint32_t index_nr,
654-
uint32_t *commit_positions)
654+
uint32_t *commit_positions,
655+
off_t *offsets)
655656
{
656657
int i;
657658

658659
for (i = 0; i < writer.selected_nr; ++i) {
659660
struct bitmapped_commit *stored = &writer.selected[i];
660661

662+
if (offsets)
663+
offsets[i] = hashfile_total(f);
664+
661665
hashwrite_be32(f, commit_positions[i]);
662666
hashwrite_u8(f, stored->xor_offset);
663667
hashwrite_u8(f, stored->flags);
@@ -666,6 +670,81 @@ static void write_selected_commits_v1(struct hashfile *f,
666670
}
667671
}
668672

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+
669748
static void write_hash_cache(struct hashfile *f,
670749
struct pack_idx_entry **index,
671750
uint32_t index_nr)
@@ -693,6 +772,7 @@ void bitmap_writer_finish(struct pack_idx_entry **index,
693772
struct strbuf tmp_file = STRBUF_INIT;
694773
struct hashfile *f;
695774
uint32_t *commit_positions = NULL;
775+
off_t *offsets = NULL;
696776
uint32_t i;
697777

698778
struct bitmap_disk_header header;
@@ -713,6 +793,9 @@ void bitmap_writer_finish(struct pack_idx_entry **index,
713793
dump_bitmap(f, writer.blobs);
714794
dump_bitmap(f, writer.tags);
715795

796+
if (options & BITMAP_OPT_LOOKUP_TABLE)
797+
CALLOC_ARRAY(offsets, index_nr);
798+
716799
ALLOC_ARRAY(commit_positions, writer.selected_nr);
717800

718801
for (i = 0; i < writer.selected_nr; i++) {
@@ -725,7 +808,10 @@ void bitmap_writer_finish(struct pack_idx_entry **index,
725808
commit_positions[i] = commit_pos;
726809
}
727810

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);
729815

730816
if (options & BITMAP_OPT_HASH_CACHE)
731817
write_hash_cache(f, index, index_nr);
@@ -741,4 +827,5 @@ void bitmap_writer_finish(struct pack_idx_entry **index,
741827

742828
strbuf_release(&tmp_file);
743829
free(commit_positions);
830+
free(offsets);
744831
}

pack-bitmap.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ struct bitmap_disk_header {
2424
#define NEEDS_BITMAP (1u<<22)
2525

2626
enum pack_bitmap_opts {
27-
BITMAP_OPT_FULL_DAG = 1,
28-
BITMAP_OPT_HASH_CACHE = 4,
27+
BITMAP_OPT_FULL_DAG = 0x1,
28+
BITMAP_OPT_HASH_CACHE = 0x4,
29+
BITMAP_OPT_LOOKUP_TABLE = 0x10,
2930
};
3031

3132
enum pack_bitmap_flags {

0 commit comments

Comments
 (0)