@@ -66,45 +66,54 @@ void pack_geometry_init(struct pack_geometry *geometry,
6666 if (p -> is_cruft )
6767 continue ;
6868
69- ALLOC_GROW (geometry -> pack ,
70- geometry -> pack_nr + 1 ,
71- geometry -> pack_alloc );
72-
73- geometry -> pack [geometry -> pack_nr ] = p ;
74- geometry -> pack_nr ++ ;
69+ if (p -> pack_promisor ) {
70+ ALLOC_GROW (geometry -> promisor_pack ,
71+ geometry -> promisor_pack_nr + 1 ,
72+ geometry -> promisor_pack_alloc );
73+
74+ geometry -> promisor_pack [geometry -> promisor_pack_nr ] = p ;
75+ geometry -> promisor_pack_nr ++ ;
76+ } else {
77+ ALLOC_GROW (geometry -> pack ,
78+ geometry -> pack_nr + 1 ,
79+ geometry -> pack_alloc );
80+
81+ geometry -> pack [geometry -> pack_nr ] = p ;
82+ geometry -> pack_nr ++ ;
83+ }
7584 }
7685
7786 QSORT (geometry -> pack , geometry -> pack_nr , pack_geometry_cmp );
87+ QSORT (geometry -> promisor_pack , geometry -> promisor_pack_nr , pack_geometry_cmp );
7888 strbuf_release (& buf );
7989}
8090
81- void pack_geometry_split (struct pack_geometry * geometry )
91+ static uint32_t compute_pack_geometry_split (struct packed_git * * pack , size_t pack_nr ,
92+ int split_factor )
8293{
8394 uint32_t i ;
8495 uint32_t split ;
8596 off_t total_size = 0 ;
8697
87- if (!geometry -> pack_nr ) {
88- geometry -> split = geometry -> pack_nr ;
89- return ;
90- }
98+ if (!pack_nr )
99+ return 0 ;
91100
92101 /*
93102 * First, count the number of packs (in descending order of size) which
94103 * already form a geometric progression.
95104 */
96- for (i = geometry -> pack_nr - 1 ; i > 0 ; i -- ) {
97- struct packed_git * ours = geometry -> pack [i ];
98- struct packed_git * prev = geometry -> pack [i - 1 ];
105+ for (i = pack_nr - 1 ; i > 0 ; i -- ) {
106+ struct packed_git * ours = pack [i ];
107+ struct packed_git * prev = pack [i - 1 ];
99108
100- if (unsigned_mult_overflows (geometry -> split_factor ,
109+ if (unsigned_mult_overflows (split_factor ,
101110 pack_geometry_weight (prev )))
102111 die (_ ("pack %s too large to consider in geometric "
103112 "progression" ),
104113 prev -> pack_name );
105114
106115 if (pack_geometry_weight (ours ) <
107- geometry -> split_factor * pack_geometry_weight (prev ))
116+ split_factor * pack_geometry_weight (prev ))
108117 break ;
109118 }
110119
@@ -130,21 +139,19 @@ void pack_geometry_split(struct pack_geometry *geometry)
130139 * the geometric progression.
131140 */
132141 for (i = 0 ; i < split ; i ++ ) {
133- struct packed_git * p = geometry -> pack [i ];
142+ struct packed_git * p = pack [i ];
134143
135144 if (unsigned_add_overflows (total_size , pack_geometry_weight (p )))
136145 die (_ ("pack %s too large to roll up" ), p -> pack_name );
137146 total_size += pack_geometry_weight (p );
138147 }
139- for (i = split ; i < geometry -> pack_nr ; i ++ ) {
140- struct packed_git * ours = geometry -> pack [i ];
148+ for (i = split ; i < pack_nr ; i ++ ) {
149+ struct packed_git * ours = pack [i ];
141150
142- if (unsigned_mult_overflows (geometry -> split_factor ,
143- total_size ))
151+ if (unsigned_mult_overflows (split_factor , total_size ))
144152 die (_ ("pack %s too large to roll up" ), ours -> pack_name );
145153
146- if (pack_geometry_weight (ours ) <
147- geometry -> split_factor * total_size ) {
154+ if (pack_geometry_weight (ours ) < split_factor * total_size ) {
148155 if (unsigned_add_overflows (total_size ,
149156 pack_geometry_weight (ours )))
150157 die (_ ("pack %s too large to roll up" ),
@@ -156,7 +163,16 @@ void pack_geometry_split(struct pack_geometry *geometry)
156163 break ;
157164 }
158165
159- geometry -> split = split ;
166+ return split ;
167+ }
168+
169+ void pack_geometry_split (struct pack_geometry * geometry )
170+ {
171+ geometry -> split = compute_pack_geometry_split (geometry -> pack , geometry -> pack_nr ,
172+ geometry -> split_factor );
173+ geometry -> promisor_split = compute_pack_geometry_split (geometry -> promisor_pack ,
174+ geometry -> promisor_pack_nr ,
175+ geometry -> split_factor );
160176}
161177
162178struct packed_git * pack_geometry_preferred_pack (struct pack_geometry * geometry )
@@ -194,17 +210,18 @@ struct packed_git *pack_geometry_preferred_pack(struct pack_geometry *geometry)
194210 return NULL ;
195211}
196212
197- void pack_geometry_remove_redundant (struct pack_geometry * geometry ,
198- struct string_list * names ,
199- struct existing_packs * existing ,
200- const char * packdir )
213+ static void remove_redundant_packs (struct packed_git * * pack ,
214+ uint32_t pack_nr ,
215+ struct string_list * names ,
216+ struct existing_packs * existing ,
217+ const char * packdir )
201218{
202219 const struct git_hash_algo * algop = existing -> repo -> hash_algo ;
203220 struct strbuf buf = STRBUF_INIT ;
204221 uint32_t i ;
205222
206- for (i = 0 ; i < geometry -> split ; i ++ ) {
207- struct packed_git * p = geometry -> pack [i ];
223+ for (i = 0 ; i < pack_nr ; i ++ ) {
224+ struct packed_git * p = pack [i ];
208225 if (string_list_has_string (names , hash_to_hex_algop (p -> hash ,
209226 algop )))
210227 continue ;
@@ -223,10 +240,22 @@ void pack_geometry_remove_redundant(struct pack_geometry *geometry,
223240 strbuf_release (& buf );
224241}
225242
243+ void pack_geometry_remove_redundant (struct pack_geometry * geometry ,
244+ struct string_list * names ,
245+ struct existing_packs * existing ,
246+ const char * packdir )
247+ {
248+ remove_redundant_packs (geometry -> pack , geometry -> split ,
249+ names , existing , packdir );
250+ remove_redundant_packs (geometry -> promisor_pack , geometry -> promisor_split ,
251+ names , existing , packdir );
252+ }
253+
226254void pack_geometry_release (struct pack_geometry * geometry )
227255{
228256 if (!geometry )
229257 return ;
230258
231259 free (geometry -> pack );
260+ free (geometry -> promisor_pack );
232261}
0 commit comments