Skip to content

Commit e05881a

Browse files
kbleesgitster
authored andcommitted
name-hash.c: use new hash map implementation for directories
Signed-off-by: Karsten Blees <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent f79d9c5 commit e05881a

File tree

2 files changed

+20
-60
lines changed

2 files changed

+20
-60
lines changed

cache.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "git-compat-util.h"
55
#include "strbuf.h"
66
#include "hash.h"
7+
#include "hashmap.h"
78
#include "advice.h"
89
#include "gettext.h"
910
#include "convert.h"
@@ -278,7 +279,7 @@ struct index_state {
278279
unsigned name_hash_initialized : 1,
279280
initialized : 1;
280281
struct hash_table name_hash;
281-
struct hash_table dir_hash;
282+
struct hashmap dir_hash;
282283
};
283284

284285
extern struct index_state the_index;

name-hash.c

Lines changed: 18 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -8,49 +8,28 @@
88
#define NO_THE_INDEX_COMPATIBILITY_MACROS
99
#include "cache.h"
1010

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-
3511
struct dir_entry {
36-
struct dir_entry *next;
12+
struct hashmap_entry ent;
3713
struct dir_entry *parent;
3814
struct cache_entry *ce;
3915
int nr;
4016
unsigned int namelen;
4117
};
4218

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+
4326
static struct dir_entry *find_dir_entry(struct index_state *istate,
4427
const char *name, unsigned int namelen)
4528
{
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);
5433
}
5534

5635
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,
8463
dir = find_dir_entry(istate, ce->name, namelen);
8564
if (!dir) {
8665
/* not found, create it and add to hash table */
87-
void **pdir;
88-
unsigned int hash = hash_name(ce->name, namelen);
89-
9066
dir = xcalloc(1, sizeof(struct dir_entry));
67+
hashmap_entry_init(dir, memihash(ce->name, namelen));
9168
dir->namelen = namelen;
9269
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);
9971

10072
/* recursively add missing parent directories */
10173
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)
134106
return;
135107
ce->ce_flags |= CE_HASHED;
136108
ce->next = NULL;
137-
hash = hash_name(ce->name, ce_namelen(ce));
109+
hash = memihash(ce->name, ce_namelen(ce));
138110
pos = insert_hash(hash, ce, &istate->name_hash);
139111
if (pos) {
140112
ce->next = *pos;
@@ -153,6 +125,7 @@ static void lazy_init_name_hash(struct index_state *istate)
153125
return;
154126
if (istate->cache_nr)
155127
preallocate_hash(&istate->name_hash, istate->cache_nr);
128+
hashmap_init(&istate->dir_hash, (hashmap_cmp_fn) dir_entry_cmp, 0);
156129
for (nr = 0; nr < istate->cache_nr; nr++)
157130
hash_index_entry(istate, istate->cache[nr]);
158131
istate->name_hash_initialized = 1;
@@ -247,7 +220,7 @@ struct cache_entry *index_dir_exists(struct index_state *istate, const char *nam
247220

248221
struct cache_entry *index_file_exists(struct index_state *istate, const char *name, int namelen, int icase)
249222
{
250-
unsigned int hash = hash_name(name, namelen);
223+
unsigned int hash = memihash(name, namelen);
251224
struct cache_entry *ce;
252225

253226
lazy_init_name_hash(istate);
@@ -270,26 +243,12 @@ struct cache_entry *index_name_exists(struct index_state *istate, const char *na
270243
return index_file_exists(istate, name, namelen, icase);
271244
}
272245

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-
284246
void free_name_hash(struct index_state *istate)
285247
{
286248
if (!istate->name_hash_initialized)
287249
return;
288250
istate->name_hash_initialized = 0;
289-
if (ignore_case)
290-
/* free directory entries */
291-
for_each_hash(&istate->dir_hash, free_dir_entry, NULL);
292251

293252
free_hash(&istate->name_hash);
294-
free_hash(&istate->dir_hash);
253+
hashmap_free(&istate->dir_hash, 1);
295254
}

0 commit comments

Comments
 (0)