@@ -223,18 +223,6 @@ static void add_merge_config(struct ref **head,
223
223
}
224
224
}
225
225
226
- static int add_existing (const char * refname , const struct object_id * oid ,
227
- int flag , void * cbdata )
228
- {
229
- struct string_list * list = (struct string_list * )cbdata ;
230
- struct string_list_item * item = string_list_insert (list , refname );
231
- struct object_id * old_oid = xmalloc (sizeof (* old_oid ));
232
-
233
- oidcpy (old_oid , oid );
234
- item -> util = old_oid ;
235
- return 0 ;
236
- }
237
-
238
226
static int will_fetch (struct ref * * head , const unsigned char * sha1 )
239
227
{
240
228
struct ref * rm = * head ;
@@ -246,16 +234,72 @@ static int will_fetch(struct ref **head, const unsigned char *sha1)
246
234
return 0 ;
247
235
}
248
236
237
+ struct refname_hash_entry {
238
+ struct hashmap_entry ent ; /* must be the first member */
239
+ struct object_id oid ;
240
+ char refname [FLEX_ARRAY ];
241
+ };
242
+
243
+ static int refname_hash_entry_cmp (const void * hashmap_cmp_fn_data ,
244
+ const void * e1_ ,
245
+ const void * e2_ ,
246
+ const void * keydata )
247
+ {
248
+ const struct refname_hash_entry * e1 = e1_ ;
249
+ const struct refname_hash_entry * e2 = e2_ ;
250
+
251
+ return strcmp (e1 -> refname , keydata ? keydata : e2 -> refname );
252
+ }
253
+
254
+ static struct refname_hash_entry * refname_hash_add (struct hashmap * map ,
255
+ const char * refname ,
256
+ const struct object_id * oid )
257
+ {
258
+ struct refname_hash_entry * ent ;
259
+ size_t len = strlen (refname );
260
+
261
+ FLEX_ALLOC_MEM (ent , refname , refname , len );
262
+ hashmap_entry_init (ent , strhash (refname ));
263
+ oidcpy (& ent -> oid , oid );
264
+ hashmap_add (map , ent );
265
+ return ent ;
266
+ }
267
+
268
+ static int add_one_refname (const char * refname ,
269
+ const struct object_id * oid ,
270
+ int flag , void * cbdata )
271
+ {
272
+ struct hashmap * refname_map = cbdata ;
273
+
274
+ (void ) refname_hash_add (refname_map , refname , oid );
275
+ return 0 ;
276
+ }
277
+
278
+ static void refname_hash_init (struct hashmap * map )
279
+ {
280
+ hashmap_init (map , refname_hash_entry_cmp , NULL , 0 );
281
+ }
282
+
283
+ static int refname_hash_exists (struct hashmap * map , const char * refname )
284
+ {
285
+ return !!hashmap_get_from_hash (map , strhash (refname ), refname );
286
+ }
287
+
249
288
static void find_non_local_tags (const struct ref * refs ,
250
289
struct ref * * head ,
251
290
struct ref * * * tail )
252
291
{
253
- struct string_list existing_refs = STRING_LIST_INIT_DUP ;
254
- struct string_list remote_refs = STRING_LIST_INIT_NODUP ;
292
+ struct hashmap existing_refs ;
293
+ struct hashmap remote_refs ;
294
+ struct string_list remote_refs_list = STRING_LIST_INIT_NODUP ;
295
+ struct string_list_item * remote_ref_item ;
255
296
const struct ref * ref ;
256
- struct string_list_item * item = NULL ;
297
+ struct refname_hash_entry * item = NULL ;
298
+
299
+ refname_hash_init (& existing_refs );
300
+ refname_hash_init (& remote_refs );
257
301
258
- for_each_ref (add_existing , & existing_refs );
302
+ for_each_ref (add_one_refname , & existing_refs );
259
303
for (ref = refs ; ref ; ref = ref -> next ) {
260
304
if (!starts_with (ref -> name , "refs/tags/" ))
261
305
continue ;
@@ -271,10 +315,10 @@ static void find_non_local_tags(const struct ref *refs,
271
315
!has_object_file_with_flags (& ref -> old_oid ,
272
316
OBJECT_INFO_QUICK ) &&
273
317
!will_fetch (head , ref -> old_oid .hash ) &&
274
- !has_sha1_file_with_flags (item -> util ,
318
+ !has_sha1_file_with_flags (item -> oid . hash ,
275
319
OBJECT_INFO_QUICK ) &&
276
- !will_fetch (head , item -> util ))
277
- item -> util = NULL ;
320
+ !will_fetch (head , item -> oid . hash ))
321
+ oidclr ( & item -> oid ) ;
278
322
item = NULL ;
279
323
continue ;
280
324
}
@@ -286,48 +330,53 @@ static void find_non_local_tags(const struct ref *refs,
286
330
* fetch.
287
331
*/
288
332
if (item &&
289
- !has_sha1_file_with_flags (item -> util , OBJECT_INFO_QUICK ) &&
290
- !will_fetch (head , item -> util ))
291
- item -> util = NULL ;
333
+ !has_sha1_file_with_flags (item -> oid . hash , OBJECT_INFO_QUICK ) &&
334
+ !will_fetch (head , item -> oid . hash ))
335
+ oidclr ( & item -> oid ) ;
292
336
293
337
item = NULL ;
294
338
295
339
/* skip duplicates and refs that we already have */
296
- if (string_list_has_string (& remote_refs , ref -> name ) ||
297
- string_list_has_string (& existing_refs , ref -> name ))
340
+ if (refname_hash_exists (& remote_refs , ref -> name ) ||
341
+ refname_hash_exists (& existing_refs , ref -> name ))
298
342
continue ;
299
343
300
- item = string_list_insert (& remote_refs , ref -> name );
301
- item -> util = ( void * ) & ref -> old_oid ;
344
+ item = refname_hash_add (& remote_refs , ref -> name , & ref -> old_oid );
345
+ string_list_insert ( & remote_refs_list , ref -> name ) ;
302
346
}
303
- string_list_clear (& existing_refs , 1 );
347
+ hashmap_free (& existing_refs , 1 );
304
348
305
349
/*
306
350
* We may have a final lightweight tag that needs to be
307
351
* checked to see if it needs fetching.
308
352
*/
309
353
if (item &&
310
- !has_sha1_file_with_flags (item -> util , OBJECT_INFO_QUICK ) &&
311
- !will_fetch (head , item -> util ))
312
- item -> util = NULL ;
354
+ !has_sha1_file_with_flags (item -> oid . hash , OBJECT_INFO_QUICK ) &&
355
+ !will_fetch (head , item -> oid . hash ))
356
+ oidclr ( & item -> oid ) ;
313
357
314
358
/*
315
- * For all the tags in the remote_refs string list ,
359
+ * For all the tags in the remote_refs_list ,
316
360
* add them to the list of refs to be fetched
317
361
*/
318
- for_each_string_list_item (item , & remote_refs ) {
362
+ for_each_string_list_item (remote_ref_item , & remote_refs_list ) {
363
+ const char * refname = remote_ref_item -> string ;
364
+
365
+ item = hashmap_get_from_hash (& remote_refs , strhash (refname ), refname );
366
+ if (!item )
367
+ BUG ("unseen remote ref?" );
368
+
319
369
/* Unless we have already decided to ignore this item... */
320
- if (item -> util )
321
- {
322
- struct ref * rm = alloc_ref (item -> string );
323
- rm -> peer_ref = alloc_ref (item -> string );
324
- oidcpy (& rm -> old_oid , item -> util );
370
+ if (!is_null_oid (& item -> oid )) {
371
+ struct ref * rm = alloc_ref (item -> refname );
372
+ rm -> peer_ref = alloc_ref (item -> refname );
373
+ oidcpy (& rm -> old_oid , & item -> oid );
325
374
* * tail = rm ;
326
375
* tail = & rm -> next ;
327
376
}
328
377
}
329
-
330
- string_list_clear (& remote_refs , 0 );
378
+ hashmap_free ( & remote_refs , 1 );
379
+ string_list_clear (& remote_refs_list , 0 );
331
380
}
332
381
333
382
static struct ref * get_ref_map (struct remote * remote ,
@@ -343,7 +392,7 @@ static struct ref *get_ref_map(struct remote *remote,
343
392
/* opportunistically-updated references: */
344
393
struct ref * orefs = NULL , * * oref_tail = & orefs ;
345
394
346
- struct string_list existing_refs = STRING_LIST_INIT_DUP ;
395
+ struct hashmap existing_refs ;
347
396
348
397
if (rs -> nr ) {
349
398
struct refspec * fetch_refspec ;
@@ -437,19 +486,24 @@ static struct ref *get_ref_map(struct remote *remote,
437
486
438
487
ref_map = ref_remove_duplicates (ref_map );
439
488
440
- for_each_ref (add_existing , & existing_refs );
489
+ refname_hash_init (& existing_refs );
490
+ for_each_ref (add_one_refname , & existing_refs );
491
+
441
492
for (rm = ref_map ; rm ; rm = rm -> next ) {
442
493
if (rm -> peer_ref ) {
443
- struct string_list_item * peer_item =
444
- string_list_lookup (& existing_refs ,
445
- rm -> peer_ref -> name );
494
+ const char * refname = rm -> peer_ref -> name ;
495
+ struct refname_hash_entry * peer_item ;
496
+
497
+ peer_item = hashmap_get_from_hash (& existing_refs ,
498
+ strhash (refname ),
499
+ refname );
446
500
if (peer_item ) {
447
- struct object_id * old_oid = peer_item -> util ;
501
+ struct object_id * old_oid = & peer_item -> oid ;
448
502
oidcpy (& rm -> peer_ref -> old_oid , old_oid );
449
503
}
450
504
}
451
505
}
452
- string_list_clear (& existing_refs , 1 );
506
+ hashmap_free (& existing_refs , 1 );
453
507
454
508
return ref_map ;
455
509
}
0 commit comments