Browse Source
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>maint
Linus Torvalds
17 years ago
committed by
Junio C Hamano
5 changed files with 95 additions and 77 deletions
@ -0,0 +1,73 @@
@@ -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; |
||||
} |
Loading…
Reference in new issue