@@ -34,6 +34,11 @@ struct stored_bitmap {
3434 int flags ;
3535};
3636
37+ struct stored_bitmap_tag_pos {
38+ struct stored_bitmap stored ;
39+ size_t map_pos ;
40+ };
41+
3742/*
3843 * The active bitmap index for a repository. By design, repositories only have
3944 * a single bitmap index available (the index for the biggest packfile in
@@ -148,6 +153,7 @@ static int existing_bitmaps_hits_nr;
148153static int existing_bitmaps_misses_nr ;
149154static int roots_with_bitmaps_nr ;
150155static int roots_without_bitmaps_nr ;
156+ static int tag_pos_on_bitmap ;
151157
152158static struct ewah_bitmap * lookup_stored_bitmap (struct stored_bitmap * st )
153159{
@@ -314,13 +320,18 @@ static struct stored_bitmap *store_bitmap(struct bitmap_index *index,
314320 struct ewah_bitmap * root ,
315321 const struct object_id * oid ,
316322 struct stored_bitmap * xor_with ,
317- int flags )
323+ int flags , size_t map_pos )
318324{
319325 struct stored_bitmap * stored ;
326+ struct stored_bitmap_tag_pos * tagged ;
320327 khiter_t hash_pos ;
321328 int ret ;
322329
323- stored = xmalloc (sizeof (struct stored_bitmap ));
330+ tagged = xmalloc (tag_pos_on_bitmap ? sizeof (struct stored_bitmap_tag_pos ) :
331+ sizeof (struct stored_bitmap ));
332+ stored = & tagged -> stored ;
333+ if (tag_pos_on_bitmap )
334+ tagged -> map_pos = map_pos ;
324335 stored -> root = root ;
325336 stored -> xor = xor_with ;
326337 stored -> flags = flags ;
@@ -376,10 +387,12 @@ static int load_bitmap_entries_v1(struct bitmap_index *index)
376387 struct stored_bitmap * xor_bitmap = NULL ;
377388 uint32_t commit_idx_pos ;
378389 struct object_id oid ;
390+ size_t entry_map_pos ;
379391
380392 if (index -> map_size - index -> map_pos < 6 )
381393 return error (_ ("corrupt ewah bitmap: truncated header for entry %d" ), i );
382394
395+ entry_map_pos = index -> map_pos ;
383396 commit_idx_pos = read_be32 (index -> map , & index -> map_pos );
384397 xor_offset = read_u8 (index -> map , & index -> map_pos );
385398 flags = read_u8 (index -> map , & index -> map_pos );
@@ -402,8 +415,9 @@ static int load_bitmap_entries_v1(struct bitmap_index *index)
402415 if (!bitmap )
403416 return -1 ;
404417
405- recent_bitmaps [i % MAX_XOR_OFFSET ] = store_bitmap (
406- index , bitmap , & oid , xor_bitmap , flags );
418+ recent_bitmaps [i % MAX_XOR_OFFSET ] =
419+ store_bitmap (index , bitmap , & oid , xor_bitmap , flags ,
420+ entry_map_pos );
407421 }
408422
409423 return 0 ;
@@ -869,6 +883,7 @@ static struct stored_bitmap *lazy_bitmap_for_commit(struct bitmap_index *bitmap_
869883 int xor_flags ;
870884 khiter_t hash_pos ;
871885 struct bitmap_lookup_table_xor_item * xor_item ;
886+ size_t entry_map_pos ;
872887
873888 if (is_corrupt )
874889 return NULL ;
@@ -928,14 +943,16 @@ static struct stored_bitmap *lazy_bitmap_for_commit(struct bitmap_index *bitmap_
928943 goto corrupt ;
929944 }
930945
946+ entry_map_pos = bitmap_git -> map_pos ;
931947 bitmap_git -> map_pos += sizeof (uint32_t ) + sizeof (uint8_t );
932948 xor_flags = read_u8 (bitmap_git -> map , & bitmap_git -> map_pos );
933949 bitmap = read_bitmap_1 (bitmap_git );
934950
935951 if (!bitmap )
936952 goto corrupt ;
937953
938- xor_bitmap = store_bitmap (bitmap_git , bitmap , & xor_item -> oid , xor_bitmap , xor_flags );
954+ xor_bitmap = store_bitmap (bitmap_git , bitmap , & xor_item -> oid ,
955+ xor_bitmap , xor_flags , entry_map_pos );
939956 xor_items_nr -- ;
940957 }
941958
@@ -969,14 +986,16 @@ static struct stored_bitmap *lazy_bitmap_for_commit(struct bitmap_index *bitmap_
969986 * Instead, we can skip ahead and immediately read the flags and
970987 * ewah bitmap.
971988 */
989+ entry_map_pos = bitmap_git -> map_pos ;
972990 bitmap_git -> map_pos += sizeof (uint32_t ) + sizeof (uint8_t );
973991 flags = read_u8 (bitmap_git -> map , & bitmap_git -> map_pos );
974992 bitmap = read_bitmap_1 (bitmap_git );
975993
976994 if (!bitmap )
977995 goto corrupt ;
978996
979- return store_bitmap (bitmap_git , bitmap , oid , xor_bitmap , flags );
997+ return store_bitmap (bitmap_git , bitmap , oid , xor_bitmap , flags ,
998+ entry_map_pos );
980999
9811000corrupt :
9821001 free (xor_items );
@@ -2856,6 +2875,48 @@ int test_bitmap_commits(struct repository *r)
28562875 return 0 ;
28572876}
28582877
2878+ int test_bitmap_commits_offset (struct repository * r )
2879+ {
2880+ struct object_id oid ;
2881+ struct stored_bitmap_tag_pos * tagged ;
2882+ struct bitmap_index * bitmap_git ;
2883+ size_t commit_idx_pos_map_pos , xor_offset_map_pos , flag_map_pos ,
2884+ ewah_bitmap_map_pos ;
2885+
2886+ tag_pos_on_bitmap = 1 ;
2887+ bitmap_git = prepare_bitmap_git (r );
2888+ if (!bitmap_git )
2889+ die (_ ("failed to load bitmap indexes" ));
2890+
2891+ /*
2892+ * As this function is only used to print bitmap selected
2893+ * commits, we don't have to read the commit table.
2894+ */
2895+ if (bitmap_git -> table_lookup ) {
2896+ if (load_bitmap_entries_v1 (bitmap_git ) < 0 )
2897+ die (_ ("failed to load bitmap indexes" ));
2898+ }
2899+
2900+ kh_foreach (bitmap_git -> bitmaps , oid , tagged , {
2901+ commit_idx_pos_map_pos = tagged -> map_pos ;
2902+ xor_offset_map_pos = tagged -> map_pos + sizeof (uint32_t );
2903+ flag_map_pos = xor_offset_map_pos + sizeof (uint8_t );
2904+ ewah_bitmap_map_pos = flag_map_pos + sizeof (uint8_t );
2905+
2906+ printf_ln ("%s %" PRIuMAX " %" PRIuMAX " %" PRIuMAX " %" PRIuMAX ,
2907+ oid_to_hex (& oid ),
2908+ (uintmax_t )commit_idx_pos_map_pos ,
2909+ (uintmax_t )xor_offset_map_pos ,
2910+ (uintmax_t )flag_map_pos ,
2911+ (uintmax_t )ewah_bitmap_map_pos );
2912+ })
2913+ ;
2914+
2915+ free_bitmap_index (bitmap_git );
2916+
2917+ return 0 ;
2918+ }
2919+
28592920int test_bitmap_hashes (struct repository * r )
28602921{
28612922 struct bitmap_index * bitmap_git = prepare_bitmap_git (r );
0 commit comments