name-hash.c: use new hash map implementation for directories

Signed-off-by: Karsten Blees <blees@dcon.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Karsten Blees committed Nov 14, 2013 at 20:20 UTC e05881a4577cedca4d7456b3cb1f8bbd6f480df2
2 files changed +20 -60
cache.h
+2 -1
@@ -4,6 +4,7 @@
4 #include "git-compat-util.h"
5 #include "strbuf.h"
6 #include "hash.h"
7 +#include "hashmap.h"
8 #include "advice.h"
9 #include "gettext.h"
10 #include "convert.h"
@@ -278,7 +279,7 @@ struct index_state {
279 unsigned name_hash_initialized : 1,
280 initialized : 1;
281 struct hash_table name_hash;
281 - struct hash_table dir_hash;
282 + struct hashmap dir_hash;
283 };
284
285 extern struct index_state the_index;
name-hash.c
+18 -59
@@ -8,49 +8,28 @@
8 #define NO_THE_INDEX_COMPATIBILITY_MACROS
9 #include "cache.h"
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 -
11 struct dir_entry {
36 - struct dir_entry *next;
12 + struct hashmap_entry ent;
13 struct dir_entry *parent;
14 struct cache_entry *ce;
15 int nr;
16 unsigned int namelen;
17 };
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 +
26 static struct dir_entry *find_dir_entry(struct index_state *istate,
27 const char *name, unsigned int namelen)
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);
33 }
34
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,
63 dir = find_dir_entry(istate, ce->name, namelen);
64 if (!dir) {
65 /* not found, create it and add to hash table */
87 - void **pdir;
88 - unsigned int hash = hash_name(ce->name, namelen);
89 -
66 dir = xcalloc(1, sizeof(struct dir_entry));
67 + hashmap_entry_init(dir, memihash(ce->name, namelen));
68 dir->namelen = namelen;
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);
71
72 /* recursively add missing parent directories */
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)
106 return;
107 ce->ce_flags |= CE_HASHED;
108 ce->next = NULL;
137 - hash = hash_name(ce->name, ce_namelen(ce));
109 + hash = memihash(ce->name, ce_namelen(ce));
110 pos = insert_hash(hash, ce, &istate->name_hash);
111 if (pos) {
112 ce->next = *pos;
@@ -153,6 +125,7 @@ static void lazy_init_name_hash(struct index_state *istate)
125 return;
126 if (istate->cache_nr)
127 preallocate_hash(&istate->name_hash, istate->cache_nr);
128 + hashmap_init(&istate->dir_hash, (hashmap_cmp_fn) dir_entry_cmp, 0);
129 for (nr = 0; nr < istate->cache_nr; nr++)
130 hash_index_entry(istate, istate->cache[nr]);
131 istate->name_hash_initialized = 1;
@@ -247,7 +220,7 @@ struct cache_entry *index_dir_exists(struct index_state *istate, const char *nam
220
221 struct cache_entry *index_file_exists(struct index_state *istate, const char *name, int namelen, int icase)
222 {
250 - unsigned int hash = hash_name(name, namelen);
223 + unsigned int hash = memihash(name, namelen);
224 struct cache_entry *ce;
225
226 lazy_init_name_hash(istate);
@@ -270,26 +243,12 @@ struct cache_entry *index_name_exists(struct index_state *istate, const char *na
243 return index_file_exists(istate, name, namelen, icase);
244 }
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 -
246 void free_name_hash(struct index_state *istate)
247 {
248 if (!istate->name_hash_initialized)
249 return;
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);
251
252 free_hash(&istate->name_hash);
294 - free_hash(&istate->dir_hash);
253 + hashmap_free(&istate->dir_hash, 1);
254 }