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,29 +339,25 @@ 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 );
329
354
}
330
355
331
- static int get_files_dirs (struct merge_options * o , struct tree * tree )
356
+ static void get_files_dirs (struct merge_options * o , struct tree * tree )
332
357
{
333
- int n ;
334
358
struct pathspec match_all ;
335
359
memset (& match_all , 0 , sizeof (match_all ));
336
- if (read_tree_recursive (tree , "" , 0 , 0 , & match_all , save_files_dirs , o ))
337
- return 0 ;
338
- n = o -> current_file_set .nr + o -> current_directory_set .nr ;
339
- return n ;
360
+ read_tree_recursive (tree , "" , 0 , 0 , & match_all , save_files_dirs , o );
340
361
}
341
362
342
363
/*
@@ -646,6 +667,7 @@ static void add_flattened_path(struct strbuf *out, const char *s)
646
667
647
668
static char * unique_path (struct merge_options * o , const char * path , const char * branch )
648
669
{
670
+ struct path_hashmap_entry * entry ;
649
671
struct strbuf newpath = STRBUF_INIT ;
650
672
int suffix = 0 ;
651
673
size_t base_len ;
@@ -654,14 +676,16 @@ static char *unique_path(struct merge_options *o, const char *path, const char *
654
676
add_flattened_path (& newpath , branch );
655
677
656
678
base_len = newpath .len ;
657
- while (string_list_has_string (& o -> current_file_set , newpath . buf ) ||
658
- 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 ) ||
659
681
(!o -> call_depth && file_exists (newpath .buf ))) {
660
682
strbuf_setlen (& newpath , base_len );
661
683
strbuf_addf (& newpath , "_%d" , suffix ++ );
662
684
}
663
685
664
- 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 );
665
689
return strbuf_detach (& newpath , NULL );
666
690
}
667
691
@@ -1945,8 +1969,14 @@ int merge_trees(struct merge_options *o,
1945
1969
if (unmerged_cache ()) {
1946
1970
struct string_list * entries , * re_head , * re_merge ;
1947
1971
int i ;
1948
- string_list_clear (& o -> current_file_set , 1 );
1949
- 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 );
1950
1980
get_files_dirs (o , head );
1951
1981
get_files_dirs (o , merge );
1952
1982
@@ -1956,16 +1986,18 @@ int merge_trees(struct merge_options *o,
1956
1986
re_merge = get_renames (o , merge , common , head , merge , entries );
1957
1987
clean = process_renames (o , re_head , re_merge );
1958
1988
if (clean < 0 )
1959
- return clean ;
1989
+ goto cleanup ;
1960
1990
for (i = entries -> nr - 1 ; 0 <= i ; i -- ) {
1961
1991
const char * path = entries -> items [i ].string ;
1962
1992
struct stage_data * e = entries -> items [i ].util ;
1963
1993
if (!e -> processed ) {
1964
1994
int ret = process_entry (o , path , e );
1965
1995
if (!ret )
1966
1996
clean = 0 ;
1967
- else if (ret < 0 )
1968
- return ret ;
1997
+ else if (ret < 0 ) {
1998
+ clean = ret ;
1999
+ goto cleanup ;
2000
+ }
1969
2001
}
1970
2002
}
1971
2003
for (i = 0 ; i < entries -> nr ; i ++ ) {
@@ -1975,13 +2007,19 @@ int merge_trees(struct merge_options *o,
1975
2007
entries -> items [i ].string );
1976
2008
}
1977
2009
2010
+ cleanup :
1978
2011
string_list_clear (re_merge , 0 );
1979
2012
string_list_clear (re_head , 0 );
1980
2013
string_list_clear (entries , 1 );
1981
2014
2015
+ hashmap_free (& o -> current_file_dir_set , 1 );
2016
+
1982
2017
free (re_merge );
1983
2018
free (re_head );
1984
2019
free (entries );
2020
+
2021
+ if (clean < 0 )
2022
+ return clean ;
1985
2023
}
1986
2024
else
1987
2025
clean = 1 ;
@@ -2177,8 +2215,6 @@ void init_merge_options(struct merge_options *o)
2177
2215
if (o -> verbosity >= 5 )
2178
2216
o -> buffer_output = 0 ;
2179
2217
strbuf_init (& o -> obuf , 0 );
2180
- string_list_init (& o -> current_file_set , 1 );
2181
- string_list_init (& o -> current_directory_set , 1 );
2182
2218
string_list_init (& o -> df_conflict_file_set , 1 );
2183
2219
}
2184
2220
0 commit comments