@@ -431,6 +431,14 @@ static int pack_info_compare(const void *_a, const void *_b)
431
431
return strcmp (a -> pack_name , b -> pack_name );
432
432
}
433
433
434
+ static int idx_or_pack_name_cmp (const void * _va , const void * _vb )
435
+ {
436
+ const char * pack_name = _va ;
437
+ const struct pack_info * compar = _vb ;
438
+
439
+ return cmp_idx_or_pack_name (pack_name , compar -> pack_name );
440
+ }
441
+
434
442
struct write_midx_context {
435
443
struct pack_info * info ;
436
444
uint32_t nr ;
@@ -445,6 +453,8 @@ struct write_midx_context {
445
453
uint32_t * pack_perm ;
446
454
unsigned large_offsets_needed :1 ;
447
455
uint32_t num_large_offsets ;
456
+
457
+ int preferred_pack_idx ;
448
458
};
449
459
450
460
static void add_pack_to_midx (const char * full_path , size_t full_path_len ,
@@ -489,6 +499,7 @@ struct pack_midx_entry {
489
499
uint32_t pack_int_id ;
490
500
time_t pack_mtime ;
491
501
uint64_t offset ;
502
+ unsigned preferred : 1 ;
492
503
};
493
504
494
505
static int midx_oid_compare (const void * _a , const void * _b )
@@ -500,6 +511,12 @@ static int midx_oid_compare(const void *_a, const void *_b)
500
511
if (cmp )
501
512
return cmp ;
502
513
514
+ /* Sort objects in a preferred pack first when multiple copies exist. */
515
+ if (a -> preferred > b -> preferred )
516
+ return -1 ;
517
+ if (a -> preferred < b -> preferred )
518
+ return 1 ;
519
+
503
520
if (a -> pack_mtime > b -> pack_mtime )
504
521
return -1 ;
505
522
else if (a -> pack_mtime < b -> pack_mtime )
@@ -527,7 +544,8 @@ static int nth_midxed_pack_midx_entry(struct multi_pack_index *m,
527
544
static void fill_pack_entry (uint32_t pack_int_id ,
528
545
struct packed_git * p ,
529
546
uint32_t cur_object ,
530
- struct pack_midx_entry * entry )
547
+ struct pack_midx_entry * entry ,
548
+ int preferred )
531
549
{
532
550
if (nth_packed_object_id (& entry -> oid , p , cur_object ) < 0 )
533
551
die (_ ("failed to locate object %d in packfile" ), cur_object );
@@ -536,6 +554,7 @@ static void fill_pack_entry(uint32_t pack_int_id,
536
554
entry -> pack_mtime = p -> mtime ;
537
555
538
556
entry -> offset = nth_packed_object_offset (p , cur_object );
557
+ entry -> preferred = !!preferred ;
539
558
}
540
559
541
560
/*
@@ -552,7 +571,8 @@ static void fill_pack_entry(uint32_t pack_int_id,
552
571
static struct pack_midx_entry * get_sorted_entries (struct multi_pack_index * m ,
553
572
struct pack_info * info ,
554
573
uint32_t nr_packs ,
555
- uint32_t * nr_objects )
574
+ uint32_t * nr_objects ,
575
+ int preferred_pack )
556
576
{
557
577
uint32_t cur_fanout , cur_pack , cur_object ;
558
578
uint32_t alloc_fanout , alloc_objects , total_objects = 0 ;
@@ -589,20 +609,29 @@ static struct pack_midx_entry *get_sorted_entries(struct multi_pack_index *m,
589
609
nth_midxed_pack_midx_entry (m ,
590
610
& entries_by_fanout [nr_fanout ],
591
611
cur_object );
612
+ if (nth_midxed_pack_int_id (m , cur_object ) == preferred_pack )
613
+ entries_by_fanout [nr_fanout ].preferred = 1 ;
614
+ else
615
+ entries_by_fanout [nr_fanout ].preferred = 0 ;
592
616
nr_fanout ++ ;
593
617
}
594
618
}
595
619
596
620
for (cur_pack = start_pack ; cur_pack < nr_packs ; cur_pack ++ ) {
597
621
uint32_t start = 0 , end ;
622
+ int preferred = cur_pack == preferred_pack ;
598
623
599
624
if (cur_fanout )
600
625
start = get_pack_fanout (info [cur_pack ].p , cur_fanout - 1 );
601
626
end = get_pack_fanout (info [cur_pack ].p , cur_fanout );
602
627
603
628
for (cur_object = start ; cur_object < end ; cur_object ++ ) {
604
629
ALLOC_GROW (entries_by_fanout , nr_fanout + 1 , alloc_fanout );
605
- fill_pack_entry (cur_pack , info [cur_pack ].p , cur_object , & entries_by_fanout [nr_fanout ]);
630
+ fill_pack_entry (cur_pack ,
631
+ info [cur_pack ].p ,
632
+ cur_object ,
633
+ & entries_by_fanout [nr_fanout ],
634
+ preferred );
606
635
nr_fanout ++ ;
607
636
}
608
637
}
@@ -777,7 +806,9 @@ static int write_midx_large_offsets(struct hashfile *f,
777
806
}
778
807
779
808
static int write_midx_internal (const char * object_dir , struct multi_pack_index * m ,
780
- struct string_list * packs_to_drop , unsigned flags )
809
+ struct string_list * packs_to_drop ,
810
+ const char * preferred_pack_name ,
811
+ unsigned flags )
781
812
{
782
813
char * midx_name ;
783
814
uint32_t i ;
@@ -828,7 +859,19 @@ static int write_midx_internal(const char *object_dir, struct multi_pack_index *
828
859
if (ctx .m && ctx .nr == ctx .m -> num_packs && !packs_to_drop )
829
860
goto cleanup ;
830
861
831
- ctx .entries = get_sorted_entries (ctx .m , ctx .info , ctx .nr , & ctx .entries_nr );
862
+ ctx .preferred_pack_idx = -1 ;
863
+ if (preferred_pack_name ) {
864
+ for (i = 0 ; i < ctx .nr ; i ++ ) {
865
+ if (!cmp_idx_or_pack_name (preferred_pack_name ,
866
+ ctx .info [i ].pack_name )) {
867
+ ctx .preferred_pack_idx = i ;
868
+ break ;
869
+ }
870
+ }
871
+ }
872
+
873
+ ctx .entries = get_sorted_entries (ctx .m , ctx .info , ctx .nr , & ctx .entries_nr ,
874
+ ctx .preferred_pack_idx );
832
875
833
876
ctx .large_offsets_needed = 0 ;
834
877
for (i = 0 ; i < ctx .entries_nr ; i ++ ) {
@@ -889,6 +932,24 @@ static int write_midx_internal(const char *object_dir, struct multi_pack_index *
889
932
pack_name_concat_len += strlen (ctx .info [i ].pack_name ) + 1 ;
890
933
}
891
934
935
+ /* Check that the preferred pack wasn't expired (if given). */
936
+ if (preferred_pack_name ) {
937
+ struct pack_info * preferred = bsearch (preferred_pack_name ,
938
+ ctx .info , ctx .nr ,
939
+ sizeof (* ctx .info ),
940
+ idx_or_pack_name_cmp );
941
+
942
+ if (!preferred )
943
+ warning (_ ("unknown preferred pack: '%s'" ),
944
+ preferred_pack_name );
945
+ else {
946
+ uint32_t perm = ctx .pack_perm [preferred -> orig_pack_int_id ];
947
+ if (perm == PACK_EXPIRED )
948
+ warning (_ ("preferred pack '%s' is expired" ),
949
+ preferred_pack_name );
950
+ }
951
+ }
952
+
892
953
if (pack_name_concat_len % MIDX_CHUNK_ALIGNMENT )
893
954
pack_name_concat_len += MIDX_CHUNK_ALIGNMENT -
894
955
(pack_name_concat_len % MIDX_CHUNK_ALIGNMENT );
@@ -947,9 +1008,12 @@ static int write_midx_internal(const char *object_dir, struct multi_pack_index *
947
1008
return result ;
948
1009
}
949
1010
950
- int write_midx_file (const char * object_dir , unsigned flags )
1011
+ int write_midx_file (const char * object_dir ,
1012
+ const char * preferred_pack_name ,
1013
+ unsigned flags )
951
1014
{
952
- return write_midx_internal (object_dir , NULL , NULL , flags );
1015
+ return write_midx_internal (object_dir , NULL , NULL , preferred_pack_name ,
1016
+ flags );
953
1017
}
954
1018
955
1019
void clear_midx_file (struct repository * r )
@@ -1184,7 +1248,7 @@ int expire_midx_packs(struct repository *r, const char *object_dir, unsigned fla
1184
1248
free (count );
1185
1249
1186
1250
if (packs_to_drop .nr )
1187
- result = write_midx_internal (object_dir , m , & packs_to_drop , flags );
1251
+ result = write_midx_internal (object_dir , m , & packs_to_drop , NULL , flags );
1188
1252
1189
1253
string_list_clear (& packs_to_drop , 0 );
1190
1254
return result ;
@@ -1373,7 +1437,7 @@ int midx_repack(struct repository *r, const char *object_dir, size_t batch_size,
1373
1437
goto cleanup ;
1374
1438
}
1375
1439
1376
- result = write_midx_internal (object_dir , m , NULL , flags );
1440
+ result = write_midx_internal (object_dir , m , NULL , NULL , flags );
1377
1441
m = NULL ;
1378
1442
1379
1443
cleanup :
0 commit comments