Move name hashing functions into a file of its own
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Fri, 21 Mar 2008 20:16:24 +0000 (13:16 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 9 Apr 2008 08:22:25 +0000 (01:22 -0700)
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>
Makefile
builtin-read-tree.c
cache.h
name-hash.c [new file with mode: 0644]
read-cache.c

index 78b7738..390b37b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -422,6 +422,7 @@ LIB_OBJS += log-tree.o
 LIB_OBJS += mailmap.o
 LIB_OBJS += match-trees.o
 LIB_OBJS += merge-file.o
+LIB_OBJS += name-hash.o
 LIB_OBJS += object.o
 LIB_OBJS += pack-check.o
 LIB_OBJS += pack-revindex.o
index e9cfd2b..7ac3088 100644 (file)
@@ -40,7 +40,7 @@ static int read_cache_unmerged(void)
        for (i = 0; i < active_nr; i++) {
                struct cache_entry *ce = active_cache[i];
                if (ce_stage(ce)) {
-                       remove_index_entry(ce);
+                       remove_name_hash(ce);
                        if (last && !strcmp(ce->name, last->name))
                                continue;
                        cache_tree_invalidate_path(active_cache_tree, ce->name);
diff --git a/cache.h b/cache.h
index 2a1e7ec..2afc788 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -153,20 +153,6 @@ static inline void copy_cache_entry(struct cache_entry *dst, struct cache_entry
        dst->ce_flags = (dst->ce_flags & ~CE_STATE_MASK) | state;
 }
 
-/*
- * We don't actually *remove* it, we can just mark it invalid so that
- * we won't find it in lookups.
- *
- * Not only would we have to search the lists (simple enough), but
- * we'd also have to rehash other hash buckets in case this makes the
- * hash bucket empty (common). So it's much better to just mark
- * it.
- */
-static inline void remove_index_entry(struct cache_entry *ce)
-{
-       ce->ce_flags |= CE_UNHASHED;
-}
-
 static inline unsigned create_ce_flags(size_t len, unsigned stage)
 {
        if (len >= CE_NAMEMASK)
@@ -241,6 +227,23 @@ struct index_state {
 
 extern struct index_state the_index;
 
+/* Name hashing */
+extern void add_name_hash(struct index_state *istate, struct cache_entry *ce);
+/*
+ * We don't actually *remove* it, we can just mark it invalid so that
+ * we won't find it in lookups.
+ *
+ * Not only would we have to search the lists (simple enough), but
+ * we'd also have to rehash other hash buckets in case this makes the
+ * hash bucket empty (common). So it's much better to just mark
+ * it.
+ */
+static inline void remove_name_hash(struct cache_entry *ce)
+{
+       ce->ce_flags |= CE_UNHASHED;
+}
+
+
 #ifndef NO_THE_INDEX_COMPATIBILITY_MACROS
 #define active_cache (the_index.cache)
 #define active_nr (the_index.cache_nr)
diff --git a/name-hash.c b/name-hash.c
new file mode 100644 (file)
index 0000000..e56eb16
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * name-hash.c
+ *
+ * Hashing names in the index state
+ *
+ * Copyright (C) 2008 Linus Torvalds
+ */
+#define NO_THE_INDEX_COMPATIBILITY_MACROS
+#include "cache.h"
+
+static unsigned int hash_name(const char *name, int namelen)
+{
+       unsigned int hash = 0x123;
+
+       do {
+               unsigned char c = *name++;
+               hash = hash*101 + c;
+       } while (--namelen);
+       return hash;
+}
+
+static void hash_index_entry(struct index_state *istate, struct cache_entry *ce)
+{
+       void **pos;
+       unsigned int hash;
+
+       if (ce->ce_flags & CE_HASHED)
+               return;
+       ce->ce_flags |= CE_HASHED;
+       ce->next = NULL;
+       hash = hash_name(ce->name, ce_namelen(ce));
+       pos = insert_hash(hash, ce, &istate->name_hash);
+       if (pos) {
+               ce->next = *pos;
+               *pos = ce;
+       }
+}
+
+static void lazy_init_name_hash(struct index_state *istate)
+{
+       int nr;
+
+       if (istate->name_hash_initialized)
+               return;
+       for (nr = 0; nr < istate->cache_nr; nr++)
+               hash_index_entry(istate, istate->cache[nr]);
+       istate->name_hash_initialized = 1;
+}
+
+void add_name_hash(struct index_state *istate, struct cache_entry *ce)
+{
+       ce->ce_flags &= ~CE_UNHASHED;
+       if (istate->name_hash_initialized)
+               hash_index_entry(istate, ce);
+}
+
+int index_name_exists(struct index_state *istate, const char *name, int namelen)
+{
+       unsigned int hash = hash_name(name, namelen);
+       struct cache_entry *ce;
+
+       lazy_init_name_hash(istate);
+       ce = lookup_hash(hash, &istate->name_hash);
+
+       while (ce) {
+               if (!(ce->ce_flags & CE_UNHASHED)) {
+                       if (!cache_name_compare(name, namelen, ce->name, ce->ce_flags))
+                               return 1;
+               }
+               ce = ce->next;
+       }
+       return 0;
+}
index a92b25b..5dc998d 100644 (file)
 
 struct index_state the_index;
 
-static unsigned int hash_name(const char *name, int namelen)
-{
-       unsigned int hash = 0x123;
-
-       do {
-               unsigned char c = *name++;
-               hash = hash*101 + c;
-       } while (--namelen);
-       return hash;
-}
-
-static void hash_index_entry(struct index_state *istate, struct cache_entry *ce)
-{
-       void **pos;
-       unsigned int hash;
-
-       if (ce->ce_flags & CE_HASHED)
-               return;
-       ce->ce_flags |= CE_HASHED;
-       ce->next = NULL;
-       hash = hash_name(ce->name, ce_namelen(ce));
-       pos = insert_hash(hash, ce, &istate->name_hash);
-       if (pos) {
-               ce->next = *pos;
-               *pos = ce;
-       }
-}
-
-static void lazy_init_name_hash(struct index_state *istate)
-{
-       int nr;
-
-       if (istate->name_hash_initialized)
-               return;
-       for (nr = 0; nr < istate->cache_nr; nr++)
-               hash_index_entry(istate, istate->cache[nr]);
-       istate->name_hash_initialized = 1;
-}
-
 static void set_index_entry(struct index_state *istate, int nr, struct cache_entry *ce)
 {
-       ce->ce_flags &= ~CE_UNHASHED;
        istate->cache[nr] = ce;
-       if (istate->name_hash_initialized)
-               hash_index_entry(istate, ce);
+       add_name_hash(istate, ce);
 }
 
 static void replace_index_entry(struct index_state *istate, int nr, struct cache_entry *ce)
 {
        struct cache_entry *old = istate->cache[nr];
 
-       remove_index_entry(old);
+       remove_name_hash(old);
        set_index_entry(istate, nr, ce);
        istate->cache_changed = 1;
 }
 
-int index_name_exists(struct index_state *istate, const char *name, int namelen)
-{
-       unsigned int hash = hash_name(name, namelen);
-       struct cache_entry *ce;
-
-       lazy_init_name_hash(istate);
-       ce = lookup_hash(hash, &istate->name_hash);
-
-       while (ce) {
-               if (!(ce->ce_flags & CE_UNHASHED)) {
-                       if (!cache_name_compare(name, namelen, ce->name, ce->ce_flags))
-                               return 1;
-               }
-               ce = ce->next;
-       }
-       return 0;
-}
-
 /*
  * This only updates the "non-critical" parts of the directory
  * 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)
 {
        struct cache_entry *ce = istate->cache[pos];
 
-       remove_index_entry(ce);
+       remove_name_hash(ce);
        istate->cache_changed = 1;
        istate->cache_nr--;
        if (pos >= istate->cache_nr)