@@ -107,241 +107,6 @@ static int repack_config(const char *var, const char *value,
107107 return git_default_config (var , value , ctx , cb );
108108}
109109
110- struct pack_geometry {
111- struct packed_git * * pack ;
112- uint32_t pack_nr , pack_alloc ;
113- uint32_t split ;
114-
115- int split_factor ;
116- };
117-
118- static uint32_t pack_geometry_weight (struct packed_git * p )
119- {
120- if (open_pack_index (p ))
121- die (_ ("cannot open index for %s" ), p -> pack_name );
122- return p -> num_objects ;
123- }
124-
125- static int pack_geometry_cmp (const void * va , const void * vb )
126- {
127- uint32_t aw = pack_geometry_weight (* (struct packed_git * * )va ),
128- bw = pack_geometry_weight (* (struct packed_git * * )vb );
129-
130- if (aw < bw )
131- return -1 ;
132- if (aw > bw )
133- return 1 ;
134- return 0 ;
135- }
136-
137- static void pack_geometry_init (struct pack_geometry * geometry ,
138- struct existing_packs * existing ,
139- const struct pack_objects_args * args ,
140- int pack_kept_objects )
141- {
142- struct packfile_store * packs = existing -> repo -> objects -> packfiles ;
143- struct packed_git * p ;
144- struct strbuf buf = STRBUF_INIT ;
145-
146- for (p = packfile_store_get_all_packs (packs ); p ; p = p -> next ) {
147- if (args -> local && !p -> pack_local )
148- /*
149- * When asked to only repack local packfiles we skip
150- * over any packfiles that are borrowed from alternate
151- * object directories.
152- */
153- continue ;
154-
155- if (!pack_kept_objects ) {
156- /*
157- * Any pack that has its pack_keep bit set will
158- * appear in existing->kept_packs below, but
159- * this saves us from doing a more expensive
160- * check.
161- */
162- if (p -> pack_keep )
163- continue ;
164-
165- /*
166- * The pack may be kept via the --keep-pack
167- * option; check 'existing->kept_packs' to
168- * determine whether to ignore it.
169- */
170- strbuf_reset (& buf );
171- strbuf_addstr (& buf , pack_basename (p ));
172- strbuf_strip_suffix (& buf , ".pack" );
173-
174- if (string_list_has_string (& existing -> kept_packs , buf .buf ))
175- continue ;
176- }
177- if (p -> is_cruft )
178- continue ;
179-
180- ALLOC_GROW (geometry -> pack ,
181- geometry -> pack_nr + 1 ,
182- geometry -> pack_alloc );
183-
184- geometry -> pack [geometry -> pack_nr ] = p ;
185- geometry -> pack_nr ++ ;
186- }
187-
188- QSORT (geometry -> pack , geometry -> pack_nr , pack_geometry_cmp );
189- strbuf_release (& buf );
190- }
191-
192- static void pack_geometry_split (struct pack_geometry * geometry )
193- {
194- uint32_t i ;
195- uint32_t split ;
196- off_t total_size = 0 ;
197-
198- if (!geometry -> pack_nr ) {
199- geometry -> split = geometry -> pack_nr ;
200- return ;
201- }
202-
203- /*
204- * First, count the number of packs (in descending order of size) which
205- * already form a geometric progression.
206- */
207- for (i = geometry -> pack_nr - 1 ; i > 0 ; i -- ) {
208- struct packed_git * ours = geometry -> pack [i ];
209- struct packed_git * prev = geometry -> pack [i - 1 ];
210-
211- if (unsigned_mult_overflows (geometry -> split_factor ,
212- pack_geometry_weight (prev )))
213- die (_ ("pack %s too large to consider in geometric "
214- "progression" ),
215- prev -> pack_name );
216-
217- if (pack_geometry_weight (ours ) <
218- geometry -> split_factor * pack_geometry_weight (prev ))
219- break ;
220- }
221-
222- split = i ;
223-
224- if (split ) {
225- /*
226- * Move the split one to the right, since the top element in the
227- * last-compared pair can't be in the progression. Only do this
228- * when we split in the middle of the array (otherwise if we got
229- * to the end, then the split is in the right place).
230- */
231- split ++ ;
232- }
233-
234- /*
235- * Then, anything to the left of 'split' must be in a new pack. But,
236- * creating that new pack may cause packs in the heavy half to no longer
237- * form a geometric progression.
238- *
239- * Compute an expected size of the new pack, and then determine how many
240- * packs in the heavy half need to be joined into it (if any) to restore
241- * the geometric progression.
242- */
243- for (i = 0 ; i < split ; i ++ ) {
244- struct packed_git * p = geometry -> pack [i ];
245-
246- if (unsigned_add_overflows (total_size , pack_geometry_weight (p )))
247- die (_ ("pack %s too large to roll up" ), p -> pack_name );
248- total_size += pack_geometry_weight (p );
249- }
250- for (i = split ; i < geometry -> pack_nr ; i ++ ) {
251- struct packed_git * ours = geometry -> pack [i ];
252-
253- if (unsigned_mult_overflows (geometry -> split_factor ,
254- total_size ))
255- die (_ ("pack %s too large to roll up" ), ours -> pack_name );
256-
257- if (pack_geometry_weight (ours ) <
258- geometry -> split_factor * total_size ) {
259- if (unsigned_add_overflows (total_size ,
260- pack_geometry_weight (ours )))
261- die (_ ("pack %s too large to roll up" ),
262- ours -> pack_name );
263-
264- split ++ ;
265- total_size += pack_geometry_weight (ours );
266- } else
267- break ;
268- }
269-
270- geometry -> split = split ;
271- }
272-
273- static struct packed_git * pack_geometry_preferred_pack (struct pack_geometry * geometry )
274- {
275- uint32_t i ;
276-
277- if (!geometry ) {
278- /*
279- * No geometry means either an all-into-one repack (in which
280- * case there is only one pack left and it is the largest) or an
281- * incremental one.
282- *
283- * If repacking incrementally, then we could check the size of
284- * all packs to determine which should be preferred, but leave
285- * this for later.
286- */
287- return NULL ;
288- }
289- if (geometry -> split == geometry -> pack_nr )
290- return NULL ;
291-
292- /*
293- * The preferred pack is the largest pack above the split line. In
294- * other words, it is the largest pack that does not get rolled up in
295- * the geometric repack.
296- */
297- for (i = geometry -> pack_nr ; i > geometry -> split ; i -- )
298- /*
299- * A pack that is not local would never be included in a
300- * multi-pack index. We thus skip over any non-local packs.
301- */
302- if (geometry -> pack [i - 1 ]-> pack_local )
303- return geometry -> pack [i - 1 ];
304-
305- return NULL ;
306- }
307-
308- static void pack_geometry_remove_redundant (struct pack_geometry * geometry ,
309- struct string_list * names ,
310- struct existing_packs * existing ,
311- const char * packdir )
312- {
313- const struct git_hash_algo * algop = existing -> repo -> hash_algo ;
314- struct strbuf buf = STRBUF_INIT ;
315- uint32_t i ;
316-
317- for (i = 0 ; i < geometry -> split ; i ++ ) {
318- struct packed_git * p = geometry -> pack [i ];
319- if (string_list_has_string (names , hash_to_hex_algop (p -> hash ,
320- algop )))
321- continue ;
322-
323- strbuf_reset (& buf );
324- strbuf_addstr (& buf , pack_basename (p ));
325- strbuf_strip_suffix (& buf , ".pack" );
326-
327- if ((p -> pack_keep ) ||
328- (string_list_has_string (& existing -> kept_packs , buf .buf )))
329- continue ;
330-
331- repack_remove_redundant_pack (existing -> repo , packdir , buf .buf );
332- }
333-
334- strbuf_release (& buf );
335- }
336-
337- static void pack_geometry_release (struct pack_geometry * geometry )
338- {
339- if (!geometry )
340- return ;
341-
342- free (geometry -> pack );
343- }
344-
345110static int midx_has_unknown_packs (char * * midx_pack_names ,
346111 size_t midx_pack_names_nr ,
347112 struct string_list * include ,
0 commit comments