@@ -29,8 +29,8 @@ static inline unsigned char get_bitmask(uint32_t pos)
29
29
}
30
30
31
31
static int load_bloom_filter_from_graph (struct commit_graph * g ,
32
- struct bloom_filter * filter ,
33
- struct commit * c )
32
+ struct bloom_filter * filter ,
33
+ struct commit * c )
34
34
{
35
35
uint32_t lex_pos , start_index , end_index ;
36
36
@@ -123,9 +123,9 @@ uint32_t murmur3_seeded(uint32_t seed, const char *data, size_t len)
123
123
}
124
124
125
125
void fill_bloom_key (const char * data ,
126
- size_t len ,
127
- struct bloom_key * key ,
128
- const struct bloom_filter_settings * settings )
126
+ size_t len ,
127
+ struct bloom_key * key ,
128
+ const struct bloom_filter_settings * settings )
129
129
{
130
130
int i ;
131
131
const uint32_t seed0 = 0x293ae76f ;
@@ -139,8 +139,8 @@ void fill_bloom_key(const char *data,
139
139
}
140
140
141
141
void add_key_to_filter (const struct bloom_key * key ,
142
- struct bloom_filter * filter ,
143
- const struct bloom_filter_settings * settings )
142
+ struct bloom_filter * filter ,
143
+ const struct bloom_filter_settings * settings )
144
144
{
145
145
int i ;
146
146
uint64_t mod = filter -> len * BITS_PER_WORD ;
@@ -158,9 +158,22 @@ void init_bloom_filters(void)
158
158
init_bloom_filter_slab (& bloom_filters );
159
159
}
160
160
161
+ static int pathmap_cmp (const void * hashmap_cmp_fn_data ,
162
+ const struct hashmap_entry * eptr ,
163
+ const struct hashmap_entry * entry_or_key ,
164
+ const void * keydata )
165
+ {
166
+ const struct pathmap_hash_entry * e1 , * e2 ;
167
+
168
+ e1 = container_of (eptr , const struct pathmap_hash_entry , entry );
169
+ e2 = container_of (entry_or_key , const struct pathmap_hash_entry , entry );
170
+
171
+ return strcmp (e1 -> path , e2 -> path );
172
+ }
173
+
161
174
struct bloom_filter * get_bloom_filter (struct repository * r ,
162
175
struct commit * c ,
163
- int compute_if_not_present )
176
+ int compute_if_not_present )
164
177
{
165
178
struct bloom_filter * filter ;
166
179
struct bloom_filter_settings settings = DEFAULT_BLOOM_FILTER_SETTINGS ;
@@ -193,35 +206,42 @@ struct bloom_filter *get_bloom_filter(struct repository *r,
193
206
diffopt .max_changes = max_changes ;
194
207
diff_setup_done (& diffopt );
195
208
209
+ /* ensure commit is parsed so we have parent information */
210
+ repo_parse_commit (r , c );
211
+
196
212
if (c -> parents )
197
213
diff_tree_oid (& c -> parents -> item -> object .oid , & c -> object .oid , "" , & diffopt );
198
214
else
199
215
diff_tree_oid (NULL , & c -> object .oid , "" , & diffopt );
200
216
diffcore_std (& diffopt );
201
217
202
- if (diff_queued_diff . nr <= max_changes ) {
218
+ if (diffopt . num_changes <= max_changes ) {
203
219
struct hashmap pathmap ;
204
220
struct pathmap_hash_entry * e ;
205
221
struct hashmap_iter iter ;
206
- hashmap_init (& pathmap , NULL , NULL , 0 );
222
+ hashmap_init (& pathmap , pathmap_cmp , NULL , 0 );
207
223
208
224
for (i = 0 ; i < diff_queued_diff .nr ; i ++ ) {
209
225
const char * path = diff_queued_diff .queue [i ]-> two -> path ;
210
226
211
227
/*
212
- * Add each leading directory of the changed file, i.e. for
213
- * 'dir/subdir/file' add 'dir' and 'dir/subdir' as well, so
214
- * the Bloom filter could be used to speed up commands like
215
- * 'git log dir/subdir', too.
216
- *
217
- * Note that directories are added without the trailing '/'.
218
- */
228
+ * Add each leading directory of the changed file, i.e. for
229
+ * 'dir/subdir/file' add 'dir' and 'dir/subdir' as well, so
230
+ * the Bloom filter could be used to speed up commands like
231
+ * 'git log dir/subdir', too.
232
+ *
233
+ * Note that directories are added without the trailing '/'.
234
+ */
219
235
do {
220
236
char * last_slash = strrchr (path , '/' );
221
237
222
238
FLEX_ALLOC_STR (e , path , path );
223
239
hashmap_entry_init (& e -> entry , strhash (path ));
224
- hashmap_add (& pathmap , & e -> entry );
240
+
241
+ if (!hashmap_get (& pathmap , & e -> entry , NULL ))
242
+ hashmap_add (& pathmap , & e -> entry );
243
+ else
244
+ free (e );
225
245
226
246
if (!last_slash )
227
247
last_slash = (char * )path ;
0 commit comments