4 * Hashing names in the index state
6 * Copyright (C) 2008 Linus Torvalds
8 #define NO_THE_INDEX_COMPATIBILITY_MACROS
12 * This removes bit 5 if bit 6 is set.
14 * That will make US-ASCII characters hash to their upper-case
15 * equivalent. We could easily do this one whole word at a time,
16 * but that's for future worries.
18 static inline unsigned char icase_hash(unsigned char c
)
20 return c
& ~((c
& 0x40) >> 1);
23 static unsigned int hash_name(const char *name
, int namelen
)
25 unsigned int hash
= 0x123;
28 unsigned char c
= *name
++;
35 static void hash_index_entry(struct index_state
*istate
, struct cache_entry
*ce
)
40 if (ce
->ce_flags
& CE_HASHED
)
42 ce
->ce_flags
|= CE_HASHED
;
44 hash
= hash_name(ce
->name
, ce_namelen(ce
));
45 pos
= insert_hash(hash
, ce
, &istate
->name_hash
);
52 static void lazy_init_name_hash(struct index_state
*istate
)
56 if (istate
->name_hash_initialized
)
58 for (nr
= 0; nr
< istate
->cache_nr
; nr
++)
59 hash_index_entry(istate
, istate
->cache
[nr
]);
60 istate
->name_hash_initialized
= 1;
63 void add_name_hash(struct index_state
*istate
, struct cache_entry
*ce
)
65 ce
->ce_flags
&= ~CE_UNHASHED
;
66 if (istate
->name_hash_initialized
)
67 hash_index_entry(istate
, ce
);
70 static int slow_same_name(const char *name1
, int len1
, const char *name2
, int len2
)
76 unsigned char c1
= *name1
++;
77 unsigned char c2
= *name2
++;
89 static int same_name(const struct cache_entry
*ce
, const char *name
, int namelen
, int icase
)
91 int len
= ce_namelen(ce
);
94 * Always do exact compare, even if we want a case-ignoring comparison;
95 * we do the quick exact one first, because it will be the common case.
97 if (len
== namelen
&& !cache_name_compare(name
, namelen
, ce
->name
, len
))
100 return icase
&& slow_same_name(name
, namelen
, ce
->name
, len
);
103 struct cache_entry
*index_name_exists(struct index_state
*istate
, const char *name
, int namelen
, int icase
)
105 unsigned int hash
= hash_name(name
, namelen
);
106 struct cache_entry
*ce
;
108 lazy_init_name_hash(istate
);
109 ce
= lookup_hash(hash
, &istate
->name_hash
);
112 if (!(ce
->ce_flags
& CE_UNHASHED
)) {
113 if (same_name(ce
, name
, namelen
, icase
))