24
24
#include "dir.h"
25
25
#include "submodule.h"
26
26
27
+ struct path_hashmap_entry {
28
+ struct hashmap_entry e ;
29
+ char path [FLEX_ARRAY ];
30
+ };
31
+
32
+ static int path_hashmap_cmp (const void * cmp_data ,
33
+ const void * entry ,
34
+ const void * entry_or_key ,
35
+ const void * keydata )
36
+ {
37
+ const struct path_hashmap_entry * a = entry ;
38
+ const struct path_hashmap_entry * b = entry_or_key ;
39
+ const char * key = keydata ;
40
+
41
+ if (ignore_case )
42
+ return strcasecmp (a -> path , key ? key : b -> path );
43
+ else
44
+ return strcmp (a -> path , key ? key : b -> path );
45
+ }
46
+
47
+ static unsigned int path_hash (const char * path )
48
+ {
49
+ return ignore_case ? strihash (path ) : strhash (path );
50
+ }
51
+
27
52
static void flush_output (struct merge_options * o )
28
53
{
29
54
if (o -> buffer_output < 2 && o -> obuf .len ) {
@@ -314,15 +339,15 @@ static int save_files_dirs(const unsigned char *sha1,
314
339
struct strbuf * base , const char * path ,
315
340
unsigned int mode , int stage , void * context )
316
341
{
342
+ struct path_hashmap_entry * entry ;
317
343
int baselen = base -> len ;
318
344
struct merge_options * o = context ;
319
345
320
346
strbuf_addstr (base , path );
321
347
322
- if (S_ISDIR (mode ))
323
- string_list_insert (& o -> current_directory_set , base -> buf );
324
- else
325
- string_list_insert (& o -> current_file_set , base -> buf );
348
+ FLEX_ALLOC_MEM (entry , path , base -> buf , base -> len );
349
+ hashmap_entry_init (entry , path_hash (entry -> path ));
350
+ hashmap_add (& o -> current_file_dir_set , entry );
326
351
327
352
strbuf_setlen (base , baselen );
328
353
return (S_ISDIR (mode ) ? READ_TREE_RECURSIVE : 0 );
@@ -642,6 +667,7 @@ static void add_flattened_path(struct strbuf *out, const char *s)
642
667
643
668
static char * unique_path (struct merge_options * o , const char * path , const char * branch )
644
669
{
670
+ struct path_hashmap_entry * entry ;
645
671
struct strbuf newpath = STRBUF_INIT ;
646
672
int suffix = 0 ;
647
673
size_t base_len ;
@@ -650,14 +676,16 @@ static char *unique_path(struct merge_options *o, const char *path, const char *
650
676
add_flattened_path (& newpath , branch );
651
677
652
678
base_len = newpath .len ;
653
- while (string_list_has_string (& o -> current_file_set , newpath . buf ) ||
654
- string_list_has_string ( & o -> current_directory_set , newpath .buf ) ||
679
+ while (hashmap_get_from_hash (& o -> current_file_dir_set ,
680
+ path_hash ( newpath . buf ) , newpath .buf ) ||
655
681
(!o -> call_depth && file_exists (newpath .buf ))) {
656
682
strbuf_setlen (& newpath , base_len );
657
683
strbuf_addf (& newpath , "_%d" , suffix ++ );
658
684
}
659
685
660
- string_list_insert (& o -> current_file_set , newpath .buf );
686
+ FLEX_ALLOC_MEM (entry , path , newpath .buf , newpath .len );
687
+ hashmap_entry_init (entry , path_hash (entry -> path ));
688
+ hashmap_add (& o -> current_file_dir_set , entry );
661
689
return strbuf_detach (& newpath , NULL );
662
690
}
663
691
@@ -1941,8 +1969,14 @@ int merge_trees(struct merge_options *o,
1941
1969
if (unmerged_cache ()) {
1942
1970
struct string_list * entries , * re_head , * re_merge ;
1943
1971
int i ;
1944
- string_list_clear (& o -> current_file_set , 1 );
1945
- string_list_clear (& o -> current_directory_set , 1 );
1972
+ /*
1973
+ * Only need the hashmap while processing entries, so
1974
+ * initialize it here and free it when we are done running
1975
+ * through the entries. Keeping it in the merge_options as
1976
+ * opposed to decaring a local hashmap is for convenience
1977
+ * so that we don't have to pass it to around.
1978
+ */
1979
+ hashmap_init (& o -> current_file_dir_set , path_hashmap_cmp , NULL , 512 );
1946
1980
get_files_dirs (o , head );
1947
1981
get_files_dirs (o , merge );
1948
1982
@@ -1978,6 +2012,8 @@ int merge_trees(struct merge_options *o,
1978
2012
string_list_clear (re_head , 0 );
1979
2013
string_list_clear (entries , 1 );
1980
2014
2015
+ hashmap_free (& o -> current_file_dir_set , 1 );
2016
+
1981
2017
free (re_merge );
1982
2018
free (re_head );
1983
2019
free (entries );
@@ -2179,8 +2215,6 @@ void init_merge_options(struct merge_options *o)
2179
2215
if (o -> verbosity >= 5 )
2180
2216
o -> buffer_output = 0 ;
2181
2217
strbuf_init (& o -> obuf , 0 );
2182
- string_list_init (& o -> current_file_set , 1 );
2183
- string_list_init (& o -> current_directory_set , 1 );
2184
2218
string_list_init (& o -> df_conflict_file_set , 1 );
2185
2219
}
2186
2220
0 commit comments