Move name hashing functions into a file of its own
It's really totally separate functionality, and if we want to start doing case-insensitive hash lookups, I'd rather do it when it's separated out. It also renames "remove_index_entry()" to "remove_name_hash()", because that really describes the thing better. It doesn't actually remove the index entry, that's done by "remove_index_entry_at()", which is something very different, despite the similarity in names. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Linus Torvalds committed
Mar 21, 2008 at 13:16 UTC
96872bc200c41407607019c1f0fb005840f576a2
5 files changed
+95
-77
Makefile
+1
@@ -422,6 +422,7 @@ LIB_OBJS += log-tree.o
422
LIB_OBJS += mailmap.o
423
LIB_OBJS += match-trees.o
424
LIB_OBJS += merge-file.o
425
+LIB_OBJS += name-hash.o
426
LIB_OBJS += object.o
427
LIB_OBJS += pack-check.o
428
LIB_OBJS += pack-revindex.o
builtin-read-tree.c
+1
-1
@@ -40,7 +40,7 @@ static int read_cache_unmerged(void)
40
for (i = 0; i < active_nr; i++) {
41
struct cache_entry *ce = active_cache[i];
42
if (ce_stage(ce)) {
43
- remove_index_entry(ce);
43
+ remove_name_hash(ce);
44
if (last && !strcmp(ce->name, last->name))
45
continue;
46
cache_tree_invalidate_path(active_cache_tree, ce->name);
cache.h
+17
-14
@@ -153,20 +153,6 @@ static inline void copy_cache_entry(struct cache_entry *dst, struct cache_entry
153
dst->ce_flags = (dst->ce_flags & ~CE_STATE_MASK) | state;
154
}
155
156
-/*
157
- * We don't actually *remove* it, we can just mark it invalid so that
158
- * we won't find it in lookups.
159
- *
160
- * Not only would we have to search the lists (simple enough), but
161
- * we'd also have to rehash other hash buckets in case this makes the
162
- * hash bucket empty (common). So it's much better to just mark
163
- * it.
164
- */
165
-static inline void remove_index_entry(struct cache_entry *ce)
166
-{
167
- ce->ce_flags |= CE_UNHASHED;
168
-}
169
-
156
static inline unsigned create_ce_flags(size_t len, unsigned stage)
157
{
158
if (len >= CE_NAMEMASK)
@@ -241,6 +227,23 @@ struct index_state {
227
228
extern struct index_state the_index;
229
230
+/* Name hashing */
231
+extern void add_name_hash(struct index_state *istate, struct cache_entry *ce);
232
+/*
233
+ * We don't actually *remove* it, we can just mark it invalid so that
234
+ * we won't find it in lookups.
235
+ *
236
+ * Not only would we have to search the lists (simple enough), but
237
+ * we'd also have to rehash other hash buckets in case this makes the
238
+ * hash bucket empty (common). So it's much better to just mark
239
+ * it.
240
+ */
241
+static inline void remove_name_hash(struct cache_entry *ce)
242
+{
243
+ ce->ce_flags |= CE_UNHASHED;
244
+}
245
+
246
+
247
#ifndef NO_THE_INDEX_COMPATIBILITY_MACROS
248
#define active_cache (the_index.cache)
249
#define active_nr (the_index.cache_nr)
name-hash.c
new
+73
@@ -0,0 +1,73 @@
1
+/*
2
+ * name-hash.c
3
+ *
4
+ * Hashing names in the index state
5
+ *
6
+ * Copyright (C) 2008 Linus Torvalds
7
+ */
8
+#define NO_THE_INDEX_COMPATIBILITY_MACROS
9
+#include "cache.h"
10
+
11
+static unsigned int hash_name(const char *name, int namelen)
12
+{
13
+ unsigned int hash = 0x123;
14
+
15
+ do {
16
+ unsigned char c = *name++;
17
+ hash = hash*101 + c;
18
+ } while (--namelen);
19
+ return hash;
20
+}
21
+
22
+static void hash_index_entry(struct index_state *istate, struct cache_entry *ce)
23
+{
24
+ void **pos;
25
+ unsigned int hash;
26
+
27
+ if (ce->ce_flags & CE_HASHED)
28
+ return;
29
+ ce->ce_flags |= CE_HASHED;
30
+ ce->next = NULL;
31
+ hash = hash_name(ce->name, ce_namelen(ce));
32
+ pos = insert_hash(hash, ce, &istate->name_hash);
33
+ if (pos) {
34
+ ce->next = *pos;
35
+ *pos = ce;
36
+ }
37
+}
38
+
39
+static void lazy_init_name_hash(struct index_state *istate)
40
+{
41
+ int nr;
42
+
43
+ if (istate->name_hash_initialized)
44
+ return;
45
+ for (nr = 0; nr < istate->cache_nr; nr++)
46
+ hash_index_entry(istate, istate->cache[nr]);
47
+ istate->name_hash_initialized = 1;
48
+}
49
+
50
+void add_name_hash(struct index_state *istate, struct cache_entry *ce)
51
+{
52
+ ce->ce_flags &= ~CE_UNHASHED;
53
+ if (istate->name_hash_initialized)
54
+ hash_index_entry(istate, ce);
55
+}
56
+
57
+int index_name_exists(struct index_state *istate, const char *name, int namelen)
58
+{
59
+ unsigned int hash = hash_name(name, namelen);
60
+ struct cache_entry *ce;
61
+
62
+ lazy_init_name_hash(istate);
63
+ ce = lookup_hash(hash, &istate->name_hash);
64
+
65
+ while (ce) {
66
+ if (!(ce->ce_flags & CE_UNHASHED)) {
67
+ if (!cache_name_compare(name, namelen, ce->name, ce->ce_flags))
68
+ return 1;
69
+ }
70
+ ce = ce->next;
71
+ }
72
+ return 0;
73
+}
read-cache.c
+3
-62
@@ -23,80 +23,21 @@
23
24
struct index_state the_index;
25
26
-static unsigned int hash_name(const char *name, int namelen)
27
-{
28
- unsigned int hash = 0x123;
29
-
30
- do {
31
- unsigned char c = *name++;
32
- hash = hash*101 + c;
33
- } while (--namelen);
34
- return hash;
35
-}
36
-
37
-static void hash_index_entry(struct index_state *istate, struct cache_entry *ce)
38
-{
39
- void **pos;
40
- unsigned int hash;
41
-
42
- if (ce->ce_flags & CE_HASHED)
43
- return;
44
- ce->ce_flags |= CE_HASHED;
45
- ce->next = NULL;
46
- hash = hash_name(ce->name, ce_namelen(ce));
47
- pos = insert_hash(hash, ce, &istate->name_hash);
48
- if (pos) {
49
- ce->next = *pos;
50
- *pos = ce;
51
- }
52
-}
53
-
54
-static void lazy_init_name_hash(struct index_state *istate)
55
-{
56
- int nr;
57
-
58
- if (istate->name_hash_initialized)
59
- return;
60
- for (nr = 0; nr < istate->cache_nr; nr++)
61
- hash_index_entry(istate, istate->cache[nr]);
62
- istate->name_hash_initialized = 1;
63
-}
64
-
26
static void set_index_entry(struct index_state *istate, int nr, struct cache_entry *ce)
27
{
67
- ce->ce_flags &= ~CE_UNHASHED;
28
istate->cache[nr] = ce;
69
- if (istate->name_hash_initialized)
70
- hash_index_entry(istate, ce);
29
+ add_name_hash(istate, ce);
30
}
31
32
static void replace_index_entry(struct index_state *istate, int nr, struct cache_entry *ce)
33
{
34
struct cache_entry *old = istate->cache[nr];
35
77
- remove_index_entry(old);
36
+ remove_name_hash(old);
37
set_index_entry(istate, nr, ce);
38
istate->cache_changed = 1;
39
}
40
82
-int index_name_exists(struct index_state *istate, const char *name, int namelen)
83
-{
84
- unsigned int hash = hash_name(name, namelen);
85
- struct cache_entry *ce;
86
-
87
- lazy_init_name_hash(istate);
88
- ce = lookup_hash(hash, &istate->name_hash);
89
-
90
- while (ce) {
91
- if (!(ce->ce_flags & CE_UNHASHED)) {
92
- if (!cache_name_compare(name, namelen, ce->name, ce->ce_flags))
93
- return 1;
94
- }
95
- ce = ce->next;
96
- }
97
- return 0;
98
-}
99
-
41
/*
42
* This only updates the "non-critical" parts of the directory
43
* cache, ie the parts that aren't tracked by GIT, and only used
@@ -438,7 +379,7 @@ int remove_index_entry_at(struct index_state *istate, int pos)
379
{
380
struct cache_entry *ce = istate->cache[pos];
381
441
- remove_index_entry(ce);
382
+ remove_name_hash(ce);
383
istate->cache_changed = 1;
384
istate->cache_nr--;
385
if (pos >= istate->cache_nr)