@@ -183,7 +183,7 @@ struct hashmap {
183183 const void * cmpfn_data ;
184184
185185 /* total number of entries (0 means the hashmap is empty) */
186- unsigned int size ;
186+ unsigned int private_size ; /* use hashmap_get_size() */
187187
188188 /*
189189 * tablesize is the allocated size of the hash table. A non-0 value
@@ -196,8 +196,7 @@ struct hashmap {
196196 unsigned int grow_at ;
197197 unsigned int shrink_at ;
198198
199- /* See `hashmap_disallow_rehash`. */
200- unsigned disallow_rehash : 1 ;
199+ unsigned int do_count_items : 1 ;
201200};
202201
203202/* hashmap functions */
@@ -252,6 +251,18 @@ static inline void hashmap_entry_init(void *entry, unsigned int hash)
252251 e -> next = NULL ;
253252}
254253
254+ /*
255+ * Return the number of items in the map.
256+ */
257+ static inline unsigned int hashmap_get_size (struct hashmap * map )
258+ {
259+ if (map -> do_count_items )
260+ return map -> private_size ;
261+
262+ BUG ("hashmap_get_size: size not set" );
263+ return 0 ;
264+ }
265+
255266/*
256267 * Returns the hashmap entry for the specified key, or NULL if not found.
257268 *
@@ -344,24 +355,6 @@ extern void *hashmap_remove(struct hashmap *map, const void *key,
344355 */
345356int hashmap_bucket (const struct hashmap * map , unsigned int hash );
346357
347- /*
348- * Disallow/allow rehashing of the hashmap.
349- * This is useful if the caller knows that the hashmap needs multi-threaded
350- * access. The caller is still required to guard/lock searches and inserts
351- * in a manner appropriate to their usage. This simply prevents the table
352- * from being unexpectedly re-mapped.
353- *
354- * It is up to the caller to ensure that the hashmap is initialized to a
355- * reasonable size to prevent poor performance.
356- *
357- * A call to allow rehashing does not force a rehash; that might happen
358- * with the next insert or delete.
359- */
360- static inline void hashmap_disallow_rehash (struct hashmap * map , unsigned value )
361- {
362- map -> disallow_rehash = value ;
363- }
364-
365358/*
366359 * Used to iterate over all entries of a hashmap. Note that it is
367360 * not safe to add or remove entries to the hashmap while
@@ -387,6 +380,43 @@ static inline void *hashmap_iter_first(struct hashmap *map,
387380 return hashmap_iter_next (iter );
388381}
389382
383+ /*
384+ * Disable item counting and automatic rehashing when adding/removing items.
385+ *
386+ * Normally, the hashmap keeps track of the number of items in the map
387+ * and uses it to dynamically resize it. This (both the counting and
388+ * the resizing) can cause problems when the map is being used by
389+ * threaded callers (because the hashmap code does not know about the
390+ * locking strategy used by the threaded callers and therefore, does
391+ * not know how to protect the "private_size" counter).
392+ */
393+ static inline void hashmap_disable_item_counting (struct hashmap * map )
394+ {
395+ map -> do_count_items = 0 ;
396+ }
397+
398+ /*
399+ * Re-enable item couting when adding/removing items.
400+ * If counting is currently disabled, it will force count them.
401+ * It WILL NOT automatically rehash them.
402+ */
403+ static inline void hashmap_enable_item_counting (struct hashmap * map )
404+ {
405+ void * item ;
406+ unsigned int n = 0 ;
407+ struct hashmap_iter iter ;
408+
409+ if (map -> do_count_items )
410+ return ;
411+
412+ hashmap_iter_init (map , & iter );
413+ while ((item = hashmap_iter_next (& iter )))
414+ n ++ ;
415+
416+ map -> do_count_items = 1 ;
417+ map -> private_size = n ;
418+ }
419+
390420/* String interning */
391421
392422/*
0 commit comments