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));
+ unsigned int hash;
- istate->cache[nr] = ce;
+ 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;
}
}
+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);
+}
+
/*
* We don't actually *remove* it, we can just mark it invalid so that
* we won't find it in lookups.
{
struct cache_entry *old = istate->cache[nr];
- if (ce != old) {
- remove_hash_entry(istate, old);
- set_index_entry(istate, nr, ce);
- }
+ remove_hash_entry(istate, 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 = 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)) {