1818#define MIDX_HASH_LEN 20
1919#define MIDX_MIN_SIZE (MIDX_HEADER_SIZE + MIDX_HASH_LEN)
2020
21- #define MIDX_MAX_CHUNKS 1
21+ #define MIDX_MAX_CHUNKS 2
2222#define MIDX_CHUNK_ALIGNMENT 4
2323#define MIDX_CHUNKID_PACKNAMES 0x504e414d /* "PNAM" */
24+ #define MIDX_CHUNKID_OIDLOOKUP 0x4f49444c /* "OIDL" */
2425#define MIDX_CHUNKLOOKUP_WIDTH (sizeof(uint32_t) + sizeof(uint64_t))
2526
2627static char * get_midx_filename (const char * object_dir )
@@ -101,6 +102,10 @@ struct multi_pack_index *load_multi_pack_index(const char *object_dir)
101102 m -> chunk_pack_names = m -> data + chunk_offset ;
102103 break ;
103104
105+ case MIDX_CHUNKID_OIDLOOKUP :
106+ m -> chunk_oid_lookup = m -> data + chunk_offset ;
107+ break ;
108+
104109 case 0 :
105110 die (_ ("terminating multi-pack-index chunk id appears earlier than expected" ));
106111 break ;
@@ -116,6 +121,8 @@ struct multi_pack_index *load_multi_pack_index(const char *object_dir)
116121
117122 if (!m -> chunk_pack_names )
118123 die (_ ("multi-pack-index missing required pack-name chunk" ));
124+ if (!m -> chunk_oid_lookup )
125+ die (_ ("multi-pack-index missing required OID lookup chunk" ));
119126
120127 m -> pack_names = xcalloc (m -> num_packs , sizeof (* m -> pack_names ));
121128
@@ -382,6 +389,32 @@ static size_t write_midx_pack_names(struct hashfile *f,
382389 return written ;
383390}
384391
392+ static size_t write_midx_oid_lookup (struct hashfile * f , unsigned char hash_len ,
393+ struct pack_midx_entry * objects ,
394+ uint32_t nr_objects )
395+ {
396+ struct pack_midx_entry * list = objects ;
397+ uint32_t i ;
398+ size_t written = 0 ;
399+
400+ for (i = 0 ; i < nr_objects ; i ++ ) {
401+ struct pack_midx_entry * obj = list ++ ;
402+
403+ if (i < nr_objects - 1 ) {
404+ struct pack_midx_entry * next = list ;
405+ if (oidcmp (& obj -> oid , & next -> oid ) >= 0 )
406+ BUG ("OIDs not in order: %s >= %s" ,
407+ oid_to_hex (& obj -> oid ),
408+ oid_to_hex (& next -> oid ));
409+ }
410+
411+ hashwrite (f , obj -> oid .hash , (int )hash_len );
412+ written += hash_len ;
413+ }
414+
415+ return written ;
416+ }
417+
385418int write_midx_file (const char * object_dir )
386419{
387420 unsigned char cur_chunk , num_chunks = 0 ;
@@ -428,17 +461,21 @@ int write_midx_file(const char *object_dir)
428461 FREE_AND_NULL (midx_name );
429462
430463 cur_chunk = 0 ;
431- num_chunks = 1 ;
464+ num_chunks = 2 ;
432465
433466 written = write_midx_header (f , num_chunks , packs .nr );
434467
435468 chunk_ids [cur_chunk ] = MIDX_CHUNKID_PACKNAMES ;
436469 chunk_offsets [cur_chunk ] = written + (num_chunks + 1 ) * MIDX_CHUNKLOOKUP_WIDTH ;
437470
438471 cur_chunk ++ ;
439- chunk_ids [cur_chunk ] = 0 ;
472+ chunk_ids [cur_chunk ] = MIDX_CHUNKID_OIDLOOKUP ;
440473 chunk_offsets [cur_chunk ] = chunk_offsets [cur_chunk - 1 ] + packs .pack_name_concat_len ;
441474
475+ cur_chunk ++ ;
476+ chunk_ids [cur_chunk ] = 0 ;
477+ chunk_offsets [cur_chunk ] = chunk_offsets [cur_chunk - 1 ] + nr_entries * MIDX_HASH_LEN ;
478+
442479 for (i = 0 ; i <= num_chunks ; i ++ ) {
443480 if (i && chunk_offsets [i ] < chunk_offsets [i - 1 ])
444481 BUG ("incorrect chunk offsets: %" PRIu64 " before %" PRIu64 ,
@@ -468,6 +505,10 @@ int write_midx_file(const char *object_dir)
468505 written += write_midx_pack_names (f , packs .names , packs .nr );
469506 break ;
470507
508+ case MIDX_CHUNKID_OIDLOOKUP :
509+ written += write_midx_oid_lookup (f , MIDX_HASH_LEN , entries , nr_entries );
510+ break ;
511+
471512 default :
472513 BUG ("trying to write unknown chunk id %" PRIx32 ,
473514 chunk_ids [i ]);
0 commit comments