lazy index hashing
This delays the hashing of index names until it becomes necessary for the first time. Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
1
cache.h
1
cache.h
@ -191,6 +191,7 @@ struct index_state {
|
|||||||
struct cache_tree *cache_tree;
|
struct cache_tree *cache_tree;
|
||||||
time_t timestamp;
|
time_t timestamp;
|
||||||
void *alloc;
|
void *alloc;
|
||||||
|
unsigned name_hash_initialized : 1;
|
||||||
struct hash_table name_hash;
|
struct hash_table name_hash;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
26
read-cache.c
26
read-cache.c
@ -34,12 +34,11 @@ static unsigned int hash_name(const char *name, int namelen)
|
|||||||
return hash;
|
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;
|
void **pos;
|
||||||
unsigned int hash = hash_name(ce->name, ce_namelen(ce));
|
unsigned int hash = hash_name(ce->name, ce_namelen(ce));
|
||||||
|
|
||||||
istate->cache[nr] = ce;
|
|
||||||
pos = insert_hash(hash, ce, &istate->name_hash);
|
pos = insert_hash(hash, ce, &istate->name_hash);
|
||||||
if (pos) {
|
if (pos) {
|
||||||
ce->next = *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 don't actually *remove* it, we can just mark it invalid so that
|
||||||
* we won't find it in lookups.
|
* 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)
|
int index_name_exists(struct index_state *istate, const char *name, int namelen)
|
||||||
{
|
{
|
||||||
unsigned int hash = hash_name(name, 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) {
|
while (ce) {
|
||||||
if (!(ce->ce_flags & CE_UNHASHED)) {
|
if (!(ce->ce_flags & CE_UNHASHED)) {
|
||||||
|
Reference in New Issue
Block a user