@@ -106,17 +106,29 @@ static void hash_index_entry(struct index_state *istate, struct cache_entry *ce)
106
106
hashmap_entry_init (ce , memihash (ce -> name , ce_namelen (ce )));
107
107
hashmap_add (& istate -> name_hash , ce );
108
108
109
- if (ignore_case && !( ce -> ce_flags & CE_UNHASHED ) )
109
+ if (ignore_case )
110
110
add_dir_entry (istate , ce );
111
111
}
112
112
113
+ static int cache_entry_cmp (const struct cache_entry * ce1 ,
114
+ const struct cache_entry * ce2 , const void * remove )
115
+ {
116
+ /*
117
+ * For remove_name_hash, find the exact entry (pointer equality); for
118
+ * index_name_exists, find all entries with matching hash code and
119
+ * decide whether the entry matches in same_name.
120
+ */
121
+ return remove ? !(ce1 == ce2 ) : 0 ;
122
+ }
123
+
113
124
static void lazy_init_name_hash (struct index_state * istate )
114
125
{
115
126
int nr ;
116
127
117
128
if (istate -> name_hash_initialized )
118
129
return ;
119
- hashmap_init (& istate -> name_hash , NULL , istate -> cache_nr );
130
+ hashmap_init (& istate -> name_hash , (hashmap_cmp_fn ) cache_entry_cmp ,
131
+ istate -> cache_nr );
120
132
hashmap_init (& istate -> dir_hash , (hashmap_cmp_fn ) dir_entry_cmp , 0 );
121
133
for (nr = 0 ; nr < istate -> cache_nr ; nr ++ )
122
134
hash_index_entry (istate , istate -> cache [nr ]);
@@ -125,31 +137,19 @@ static void lazy_init_name_hash(struct index_state *istate)
125
137
126
138
void add_name_hash (struct index_state * istate , struct cache_entry * ce )
127
139
{
128
- /* if already hashed, add reference to directory entries */
129
- if (ignore_case && (ce -> ce_flags & CE_STATE_MASK ) == CE_STATE_MASK )
130
- add_dir_entry (istate , ce );
131
-
132
- ce -> ce_flags &= ~CE_UNHASHED ;
133
140
if (istate -> name_hash_initialized )
134
141
hash_index_entry (istate , ce );
135
142
}
136
143
137
- /*
138
- * We don't actually *remove* it, we can just mark it invalid so that
139
- * we won't find it in lookups.
140
- *
141
- * Not only would we have to search the lists (simple enough), but
142
- * we'd also have to rehash other hash buckets in case this makes the
143
- * hash bucket empty (common). So it's much better to just mark
144
- * it.
145
- */
146
144
void remove_name_hash (struct index_state * istate , struct cache_entry * ce )
147
145
{
148
- /* if already hashed, release reference to directory entries */
149
- if (ignore_case && (ce -> ce_flags & CE_STATE_MASK ) == CE_HASHED )
150
- remove_dir_entry (istate , ce );
146
+ if (!istate -> name_hash_initialized || !(ce -> ce_flags & CE_HASHED ))
147
+ return ;
148
+ ce -> ce_flags &= ~CE_HASHED ;
149
+ hashmap_remove (& istate -> name_hash , ce , ce );
151
150
152
- ce -> ce_flags |= CE_UNHASHED ;
151
+ if (ignore_case )
152
+ remove_dir_entry (istate , ce );
153
153
}
154
154
155
155
static int slow_same_name (const char * name1 , int len1 , const char * name2 , int len2 )
@@ -220,10 +220,8 @@ struct cache_entry *index_file_exists(struct index_state *istate, const char *na
220
220
hashmap_entry_init (& key , memihash (name , namelen ));
221
221
ce = hashmap_get (& istate -> name_hash , & key , NULL );
222
222
while (ce ) {
223
- if (!(ce -> ce_flags & CE_UNHASHED )) {
224
- if (same_name (ce , name , namelen , icase ))
225
- return ce ;
226
- }
223
+ if (same_name (ce , name , namelen , icase ))
224
+ return ce ;
227
225
ce = hashmap_get_next (& istate -> name_hash , ce );
228
226
}
229
227
return NULL ;
0 commit comments