@@ -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