@@ -31,6 +31,7 @@ struct stored_bitmap {
3131 struct object_id oid ;
3232 struct ewah_bitmap * root ;
3333 struct stored_bitmap * xor ;
34+ size_t map_pos ;
3435 int flags ;
3536};
3637
@@ -314,13 +315,14 @@ static struct stored_bitmap *store_bitmap(struct bitmap_index *index,
314315 struct ewah_bitmap * root ,
315316 const struct object_id * oid ,
316317 struct stored_bitmap * xor_with ,
317- int flags )
318+ int flags , size_t map_pos )
318319{
319320 struct stored_bitmap * stored ;
320321 khiter_t hash_pos ;
321322 int ret ;
322323
323324 stored = xmalloc (sizeof (struct stored_bitmap ));
325+ stored -> map_pos = map_pos ;
324326 stored -> root = root ;
325327 stored -> xor = xor_with ;
326328 stored -> flags = flags ;
@@ -376,10 +378,12 @@ static int load_bitmap_entries_v1(struct bitmap_index *index)
376378 struct stored_bitmap * xor_bitmap = NULL ;
377379 uint32_t commit_idx_pos ;
378380 struct object_id oid ;
381+ size_t entry_map_pos ;
379382
380383 if (index -> map_size - index -> map_pos < 6 )
381384 return error (_ ("corrupt ewah bitmap: truncated header for entry %d" ), i );
382385
386+ entry_map_pos = index -> map_pos ;
383387 commit_idx_pos = read_be32 (index -> map , & index -> map_pos );
384388 xor_offset = read_u8 (index -> map , & index -> map_pos );
385389 flags = read_u8 (index -> map , & index -> map_pos );
@@ -402,8 +406,9 @@ static int load_bitmap_entries_v1(struct bitmap_index *index)
402406 if (!bitmap )
403407 return -1 ;
404408
405- recent_bitmaps [i % MAX_XOR_OFFSET ] = store_bitmap (
406- index , bitmap , & oid , xor_bitmap , flags );
409+ recent_bitmaps [i % MAX_XOR_OFFSET ] =
410+ store_bitmap (index , bitmap , & oid , xor_bitmap , flags ,
411+ entry_map_pos );
407412 }
408413
409414 return 0 ;
@@ -630,41 +635,28 @@ static int load_bitmap(struct repository *r, struct bitmap_index *bitmap_git,
630635 bitmap_git -> ext_index .positions = kh_init_oid_pos ();
631636
632637 if (load_reverse_index (r , bitmap_git ))
633- goto failed ;
638+ return -1 ;
634639
635640 if (!(bitmap_git -> commits = read_bitmap_1 (bitmap_git )) ||
636641 !(bitmap_git -> trees = read_bitmap_1 (bitmap_git )) ||
637642 !(bitmap_git -> blobs = read_bitmap_1 (bitmap_git )) ||
638643 !(bitmap_git -> tags = read_bitmap_1 (bitmap_git )))
639- goto failed ;
644+ return -1 ;
640645
641646 if (!bitmap_git -> table_lookup && load_bitmap_entries_v1 (bitmap_git ) < 0 )
642- goto failed ;
647+ return -1 ;
643648
644649 if (bitmap_git -> base ) {
645650 if (!bitmap_is_midx (bitmap_git ))
646651 BUG ("non-MIDX bitmap has non-NULL base bitmap index" );
647652 if (load_bitmap (r , bitmap_git -> base , 1 ) < 0 )
648- goto failed ;
653+ return -1 ;
649654 }
650655
651656 if (!recursing )
652657 load_all_type_bitmaps (bitmap_git );
653658
654659 return 0 ;
655-
656- failed :
657- munmap (bitmap_git -> map , bitmap_git -> map_size );
658- bitmap_git -> map = NULL ;
659- bitmap_git -> map_size = 0 ;
660-
661- kh_destroy_oid_map (bitmap_git -> bitmaps );
662- bitmap_git -> bitmaps = NULL ;
663-
664- kh_destroy_oid_pos (bitmap_git -> ext_index .positions );
665- bitmap_git -> ext_index .positions = NULL ;
666-
667- return -1 ;
668660}
669661
670662static int open_pack_bitmap (struct repository * r ,
@@ -882,6 +874,7 @@ static struct stored_bitmap *lazy_bitmap_for_commit(struct bitmap_index *bitmap_
882874 int xor_flags ;
883875 khiter_t hash_pos ;
884876 struct bitmap_lookup_table_xor_item * xor_item ;
877+ size_t entry_map_pos ;
885878
886879 if (is_corrupt )
887880 return NULL ;
@@ -941,14 +934,16 @@ static struct stored_bitmap *lazy_bitmap_for_commit(struct bitmap_index *bitmap_
941934 goto corrupt ;
942935 }
943936
937+ entry_map_pos = bitmap_git -> map_pos ;
944938 bitmap_git -> map_pos += sizeof (uint32_t ) + sizeof (uint8_t );
945939 xor_flags = read_u8 (bitmap_git -> map , & bitmap_git -> map_pos );
946940 bitmap = read_bitmap_1 (bitmap_git );
947941
948942 if (!bitmap )
949943 goto corrupt ;
950944
951- xor_bitmap = store_bitmap (bitmap_git , bitmap , & xor_item -> oid , xor_bitmap , xor_flags );
945+ xor_bitmap = store_bitmap (bitmap_git , bitmap , & xor_item -> oid ,
946+ xor_bitmap , xor_flags , entry_map_pos );
952947 xor_items_nr -- ;
953948 }
954949
@@ -982,14 +977,16 @@ static struct stored_bitmap *lazy_bitmap_for_commit(struct bitmap_index *bitmap_
982977 * Instead, we can skip ahead and immediately read the flags and
983978 * ewah bitmap.
984979 */
980+ entry_map_pos = bitmap_git -> map_pos ;
985981 bitmap_git -> map_pos += sizeof (uint32_t ) + sizeof (uint8_t );
986982 flags = read_u8 (bitmap_git -> map , & bitmap_git -> map_pos );
987983 bitmap = read_bitmap_1 (bitmap_git );
988984
989985 if (!bitmap )
990986 goto corrupt ;
991987
992- return store_bitmap (bitmap_git , bitmap , oid , xor_bitmap , flags );
988+ return store_bitmap (bitmap_git , bitmap , oid , xor_bitmap , flags ,
989+ entry_map_pos );
993990
994991corrupt :
995992 free (xor_items );
@@ -2852,8 +2849,9 @@ int test_bitmap_commits(struct repository *r)
28522849 die (_ ("failed to load bitmap indexes" ));
28532850
28542851 /*
2855- * As this function is only used to print bitmap selected
2856- * commits, we don't have to read the commit table.
2852+ * Since this function needs to print bitmap selected
2853+ * commits, bypass the commit lookup table (if one exists)
2854+ * by forcing the bitmap to eagerly load its entries.
28572855 */
28582856 if (bitmap_git -> table_lookup ) {
28592857 if (load_bitmap_entries_v1 (bitmap_git ) < 0 )
@@ -2869,6 +2867,48 @@ int test_bitmap_commits(struct repository *r)
28692867 return 0 ;
28702868}
28712869
2870+ int test_bitmap_commits_with_offset (struct repository * r )
2871+ {
2872+ struct object_id oid ;
2873+ struct stored_bitmap * stored ;
2874+ struct bitmap_index * bitmap_git ;
2875+ size_t commit_idx_pos_map_pos , xor_offset_map_pos , flag_map_pos ,
2876+ ewah_bitmap_map_pos ;
2877+
2878+ bitmap_git = prepare_bitmap_git (r );
2879+ if (!bitmap_git )
2880+ die (_ ("failed to load bitmap indexes" ));
2881+
2882+ /*
2883+ * Since this function needs to know the position of each individual
2884+ * bitmap, bypass the commit lookup table (if one exists) by forcing
2885+ * the bitmap to eagerly load its entries.
2886+ */
2887+ if (bitmap_git -> table_lookup ) {
2888+ if (load_bitmap_entries_v1 (bitmap_git ) < 0 )
2889+ die (_ ("failed to load bitmap indexes" ));
2890+ }
2891+
2892+ kh_foreach (bitmap_git -> bitmaps , oid , stored , {
2893+ commit_idx_pos_map_pos = stored -> map_pos ;
2894+ xor_offset_map_pos = stored -> map_pos + sizeof (uint32_t );
2895+ flag_map_pos = xor_offset_map_pos + sizeof (uint8_t );
2896+ ewah_bitmap_map_pos = flag_map_pos + sizeof (uint8_t );
2897+
2898+ printf_ln ("%s %" PRIuMAX " %" PRIuMAX " %" PRIuMAX " %" PRIuMAX ,
2899+ oid_to_hex (& oid ),
2900+ (uintmax_t )commit_idx_pos_map_pos ,
2901+ (uintmax_t )xor_offset_map_pos ,
2902+ (uintmax_t )flag_map_pos ,
2903+ (uintmax_t )ewah_bitmap_map_pos );
2904+ })
2905+ ;
2906+
2907+ free_bitmap_index (bitmap_git );
2908+
2909+ return 0 ;
2910+ }
2911+
28722912int test_bitmap_hashes (struct repository * r )
28732913{
28742914 struct bitmap_index * bitmap_git = prepare_bitmap_git (r );
0 commit comments