@@ -26,8 +26,6 @@ static kh_oid_map_t *island_marks;
2626static unsigned island_counter ;
2727static unsigned island_counter_core ;
2828
29- static kh_str_t * remote_islands ;
30-
3129struct remote_island {
3230 uint64_t hash ;
3331 struct oid_array oids ;
@@ -312,29 +310,55 @@ void resolve_tree_islands(struct repository *r,
312310 free (todo );
313311}
314312
315- static regex_t * island_regexes ;
316- static unsigned int island_regexes_alloc , island_regexes_nr ;
313+ struct island_load_data {
314+ kh_str_t * remote_islands ;
315+ regex_t * rx ;
316+ size_t nr ;
317+ size_t alloc ;
318+ };
317319static const char * core_island_name ;
318320
319- static int island_config_callback ( const char * k , const char * v , void * cb UNUSED )
321+ static void free_config_regexes ( struct island_load_data * ild )
320322{
323+ for (size_t i = 0 ; i < ild -> nr ; i ++ )
324+ regfree (& ild -> rx [i ]);
325+ free (ild -> rx );
326+ }
327+
328+ static void free_remote_islands (kh_str_t * remote_islands )
329+ {
330+ const char * island_name ;
331+ struct remote_island * rl ;
332+
333+ kh_foreach (remote_islands , island_name , rl , {
334+ free ((void * )island_name );
335+ oid_array_clear (& rl -> oids );
336+ free (rl );
337+ });
338+ kh_destroy_str (remote_islands );
339+ }
340+
341+ static int island_config_callback (const char * k , const char * v , void * cb )
342+ {
343+ struct island_load_data * ild = cb ;
344+
321345 if (!strcmp (k , "pack.island" )) {
322346 struct strbuf re = STRBUF_INIT ;
323347
324348 if (!v )
325349 return config_error_nonbool (k );
326350
327- ALLOC_GROW (island_regexes , island_regexes_nr + 1 , island_regexes_alloc );
351+ ALLOC_GROW (ild -> rx , ild -> nr + 1 , ild -> alloc );
328352
329353 if (* v != '^' )
330354 strbuf_addch (& re , '^' );
331355 strbuf_addstr (& re , v );
332356
333- if (regcomp (& island_regexes [ island_regexes_nr ], re .buf , REG_EXTENDED ))
357+ if (regcomp (& ild -> rx [ ild -> nr ], re .buf , REG_EXTENDED ))
334358 die (_ ("failed to load island regex for '%s': %s" ), k , re .buf );
335359
336360 strbuf_release (& re );
337- island_regexes_nr ++ ;
361+ ild -> nr ++ ;
338362 return 0 ;
339363 }
340364
@@ -344,7 +368,8 @@ static int island_config_callback(const char *k, const char *v, void *cb UNUSED)
344368 return 0 ;
345369}
346370
347- static void add_ref_to_island (const char * island_name , const struct object_id * oid )
371+ static void add_ref_to_island (kh_str_t * remote_islands , const char * island_name ,
372+ const struct object_id * oid )
348373{
349374 uint64_t sha_core ;
350375 struct remote_island * rl = NULL ;
@@ -365,8 +390,10 @@ static void add_ref_to_island(const char *island_name, const struct object_id *o
365390}
366391
367392static int find_island_for_ref (const char * refname , const struct object_id * oid ,
368- int flags UNUSED , void * data UNUSED )
393+ int flags UNUSED , void * cb )
369394{
395+ struct island_load_data * ild = cb ;
396+
370397 /*
371398 * We should advertise 'ARRAY_SIZE(matches) - 2' as the max,
372399 * so we can diagnose below a config with more capture groups
@@ -377,8 +404,8 @@ static int find_island_for_ref(const char *refname, const struct object_id *oid,
377404 struct strbuf island_name = STRBUF_INIT ;
378405
379406 /* walk backwards to get last-one-wins ordering */
380- for (i = island_regexes_nr - 1 ; i >= 0 ; i -- ) {
381- if (!regexec (& island_regexes [i ], refname ,
407+ for (i = ild -> nr - 1 ; i >= 0 ; i -- ) {
408+ if (!regexec (& ild -> rx [i ], refname ,
382409 ARRAY_SIZE (matches ), matches , 0 ))
383410 break ;
384411 }
@@ -403,12 +430,12 @@ static int find_island_for_ref(const char *refname, const struct object_id *oid,
403430 strbuf_add (& island_name , refname + match -> rm_so , match -> rm_eo - match -> rm_so );
404431 }
405432
406- add_ref_to_island (island_name .buf , oid );
433+ add_ref_to_island (ild -> remote_islands , island_name .buf , oid );
407434 strbuf_release (& island_name );
408435 return 0 ;
409436}
410437
411- static struct remote_island * get_core_island (void )
438+ static struct remote_island * get_core_island (kh_str_t * remote_islands )
412439{
413440 if (core_island_name ) {
414441 khiter_t pos = kh_get_str (remote_islands , core_island_name );
@@ -419,7 +446,7 @@ static struct remote_island *get_core_island(void)
419446 return NULL ;
420447}
421448
422- static void deduplicate_islands (struct repository * r )
449+ static void deduplicate_islands (kh_str_t * remote_islands , struct repository * r )
423450{
424451 struct remote_island * island , * core = NULL , * * list ;
425452 unsigned int island_count , dst , src , ref , i = 0 ;
@@ -445,7 +472,7 @@ static void deduplicate_islands(struct repository *r)
445472 }
446473
447474 island_bitmap_size = (island_count / 32 ) + 1 ;
448- core = get_core_island ();
475+ core = get_core_island (remote_islands );
449476
450477 for (i = 0 ; i < island_count ; ++ i ) {
451478 mark_remote_island_1 (r , list [i ], core && list [i ]-> hash == core -> hash );
@@ -456,12 +483,16 @@ static void deduplicate_islands(struct repository *r)
456483
457484void load_delta_islands (struct repository * r , int progress )
458485{
486+ struct island_load_data ild = { 0 };
487+
459488 island_marks = kh_init_oid_map ();
460- remote_islands = kh_init_str ();
461489
462- git_config (island_config_callback , NULL );
463- for_each_ref (find_island_for_ref , NULL );
464- deduplicate_islands (r );
490+ git_config (island_config_callback , & ild );
491+ ild .remote_islands = kh_init_str ();
492+ for_each_ref (find_island_for_ref , & ild );
493+ free_config_regexes (& ild );
494+ deduplicate_islands (ild .remote_islands , r );
495+ free_remote_islands (ild .remote_islands );
465496
466497 if (progress )
467498 fprintf (stderr , _ ("Marked %d islands, done.\n" ), island_counter );
0 commit comments