8
8
#define NO_THE_INDEX_COMPATIBILITY_MACROS
9
9
#include "cache.h"
10
10
11
- /*
12
- * This removes bit 5 if bit 6 is set.
13
- *
14
- * That will make US-ASCII characters hash to their upper-case
15
- * equivalent. We could easily do this one whole word at a time,
16
- * but that's for future worries.
17
- */
18
- static inline unsigned char icase_hash (unsigned char c )
19
- {
20
- return c & ~((c & 0x40 ) >> 1 );
21
- }
22
-
23
- static unsigned int hash_name (const char * name , int namelen )
24
- {
25
- unsigned int hash = 0x123 ;
26
-
27
- while (namelen -- ) {
28
- unsigned char c = * name ++ ;
29
- c = icase_hash (c );
30
- hash = hash * 101 + c ;
31
- }
32
- return hash ;
33
- }
34
-
35
11
struct dir_entry {
36
- struct dir_entry * next ;
12
+ struct hashmap_entry ent ;
37
13
struct dir_entry * parent ;
38
14
struct cache_entry * ce ;
39
15
int nr ;
40
16
unsigned int namelen ;
41
17
};
42
18
19
+ static int dir_entry_cmp (const struct dir_entry * e1 ,
20
+ const struct dir_entry * e2 , const char * name )
21
+ {
22
+ return e1 -> namelen != e2 -> namelen || strncasecmp (e1 -> ce -> name ,
23
+ name ? name : e2 -> ce -> name , e1 -> namelen );
24
+ }
25
+
43
26
static struct dir_entry * find_dir_entry (struct index_state * istate ,
44
27
const char * name , unsigned int namelen )
45
28
{
46
- unsigned int hash = hash_name (name , namelen );
47
- struct dir_entry * dir ;
48
-
49
- for (dir = lookup_hash (hash , & istate -> dir_hash ); dir ; dir = dir -> next )
50
- if (dir -> namelen == namelen &&
51
- !strncasecmp (dir -> ce -> name , name , namelen ))
52
- return dir ;
53
- return NULL ;
29
+ struct dir_entry key ;
30
+ hashmap_entry_init (& key , memihash (name , namelen ));
31
+ key .namelen = namelen ;
32
+ return hashmap_get (& istate -> dir_hash , & key , name );
54
33
}
55
34
56
35
static struct dir_entry * hash_dir_entry (struct index_state * istate ,
@@ -84,18 +63,11 @@ static struct dir_entry *hash_dir_entry(struct index_state *istate,
84
63
dir = find_dir_entry (istate , ce -> name , namelen );
85
64
if (!dir ) {
86
65
/* not found, create it and add to hash table */
87
- void * * pdir ;
88
- unsigned int hash = hash_name (ce -> name , namelen );
89
-
90
66
dir = xcalloc (1 , sizeof (struct dir_entry ));
67
+ hashmap_entry_init (dir , memihash (ce -> name , namelen ));
91
68
dir -> namelen = namelen ;
92
69
dir -> ce = ce ;
93
-
94
- pdir = insert_hash (hash , dir , & istate -> dir_hash );
95
- if (pdir ) {
96
- dir -> next = * pdir ;
97
- * pdir = dir ;
98
- }
70
+ hashmap_add (& istate -> dir_hash , dir );
99
71
100
72
/* recursively add missing parent directories */
101
73
dir -> parent = hash_dir_entry (istate , ce , namelen );
@@ -134,7 +106,7 @@ static void hash_index_entry(struct index_state *istate, struct cache_entry *ce)
134
106
return ;
135
107
ce -> ce_flags |= CE_HASHED ;
136
108
ce -> next = NULL ;
137
- hash = hash_name (ce -> name , ce_namelen (ce ));
109
+ hash = memihash (ce -> name , ce_namelen (ce ));
138
110
pos = insert_hash (hash , ce , & istate -> name_hash );
139
111
if (pos ) {
140
112
ce -> next = * pos ;
@@ -153,6 +125,7 @@ static void lazy_init_name_hash(struct index_state *istate)
153
125
return ;
154
126
if (istate -> cache_nr )
155
127
preallocate_hash (& istate -> name_hash , istate -> cache_nr );
128
+ hashmap_init (& istate -> dir_hash , (hashmap_cmp_fn ) dir_entry_cmp , 0 );
156
129
for (nr = 0 ; nr < istate -> cache_nr ; nr ++ )
157
130
hash_index_entry (istate , istate -> cache [nr ]);
158
131
istate -> name_hash_initialized = 1 ;
@@ -247,7 +220,7 @@ struct cache_entry *index_dir_exists(struct index_state *istate, const char *nam
247
220
248
221
struct cache_entry * index_file_exists (struct index_state * istate , const char * name , int namelen , int icase )
249
222
{
250
- unsigned int hash = hash_name (name , namelen );
223
+ unsigned int hash = memihash (name , namelen );
251
224
struct cache_entry * ce ;
252
225
253
226
lazy_init_name_hash (istate );
@@ -270,26 +243,12 @@ struct cache_entry *index_name_exists(struct index_state *istate, const char *na
270
243
return index_file_exists (istate , name , namelen , icase );
271
244
}
272
245
273
- static int free_dir_entry (void * entry , void * unused )
274
- {
275
- struct dir_entry * dir = entry ;
276
- while (dir ) {
277
- struct dir_entry * next = dir -> next ;
278
- free (dir );
279
- dir = next ;
280
- }
281
- return 0 ;
282
- }
283
-
284
246
void free_name_hash (struct index_state * istate )
285
247
{
286
248
if (!istate -> name_hash_initialized )
287
249
return ;
288
250
istate -> name_hash_initialized = 0 ;
289
- if (ignore_case )
290
- /* free directory entries */
291
- for_each_hash (& istate -> dir_hash , free_dir_entry , NULL );
292
251
293
252
free_hash (& istate -> name_hash );
294
- free_hash (& istate -> dir_hash );
253
+ hashmap_free (& istate -> dir_hash , 1 );
295
254
}
0 commit comments