lazy index hashing
authorJunio C Hamano <gitster@pobox.com>
Wed, 23 Jan 2008 07:01:13 +0000 (23:01 -0800)
committerJunio C Hamano <gitster@pobox.com>
Wed, 23 Jan 2008 07:01:13 +0000 (23:01 -0800)
This delays the hashing of index names until it becomes necessary for
the first time.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
cache.h
read-cache.c

diff --git a/cache.h b/cache.h
index 409738c..e4aeff0 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -191,6 +191,7 @@ struct index_state {
        struct cache_tree *cache_tree;
        time_t timestamp;
        void *alloc;
+       unsigned name_hash_initialized : 1;
        struct hash_table name_hash;
 };
 
index 9477c0b..e45f4b3 100644 (file)
@@ -34,12 +34,11 @@ static unsigned int hash_name(const char *name, int namelen)
        return hash;
 }
 
-static void set_index_entry(struct index_state *istate, int nr, struct cache_entry *ce)
+static void hash_index_entry(struct index_state *istate, struct cache_entry *ce)
 {
        void **pos;
        unsigned int hash = hash_name(ce->name, ce_namelen(ce));
 
-       istate->cache[nr] = ce;
        pos = insert_hash(hash, ce, &istate->name_hash);
        if (pos) {
                ce->next = *pos;
@@ -47,6 +46,24 @@ static void set_index_entry(struct index_state *istate, int nr, struct cache_ent
        }
 }
 
+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)
+{
+       istate->cache[nr] = ce;
+       if (istate->name_hash_initialized)
+               hash_index_entry(istate, ce);
+}
+
 /*
  * We don't actually *remove* it, we can just mark it invalid so that
  * we won't find it in lookups.
@@ -75,7 +92,10 @@ static void replace_index_entry(struct index_state *istate, int nr, struct cache
 int index_name_exists(struct index_state *istate, const char *name, int namelen)
 {
        unsigned int hash = hash_name(name, namelen);
-       struct cache_entry *ce = lookup_hash(hash, &istate->name_hash);
+       struct cache_entry *ce;
+
+       lazy_init_name_hash(istate);
+       ce = lookup_hash(hash, &istate->name_hash);
 
        while (ce) {
                if (!(ce->ce_flags & CE_UNHASHED)) {