-/*
- * mono-conc-hashtable.h: A mostly concurrent hashtable
+/**
+ * \file
+ * A mostly concurrent hashtable
*
* Author:
* Rodrigo Kumpera (kumpera@gmail.com)
static void
conc_table_lf_free (conc_table *table)
{
- mono_thread_hazardous_free_or_queue (table, conc_table_free, HAZARD_FREE_MAY_LOCK, HAZARD_FREE_SAFE_CTX);
+ mono_thread_hazardous_try_free (table, conc_table_free);
}
{
MonoConcurrentHashTable *res = g_new0 (MonoConcurrentHashTable, 1);
res->hash_func = hash_func ? hash_func : g_direct_hash;
- res->equal_func = key_equal_func ? key_equal_func : g_direct_equal;
+ res->equal_func = key_equal_func;
// res->equal_func = g_direct_equal;
res->table = conc_table_new (INITIAL_SIZE);
res->element_count = 0;
hp = mono_hazard_pointer_get ();
retry:
- table = (conc_table *)get_hazardous_pointer ((gpointer volatile*)&hash_table->table, hp, 0);
+ table = (conc_table *)mono_get_hazardous_pointer ((gpointer volatile*)&hash_table->table, hp, 0);
table_mask = table->table_size - 1;
kvs = table->kvs;
i = hash & table_mask;
/**
* mono_conc_hashtable_remove:
- *
* Remove a value from the hashtable. Requires external locking
- *
- * @Returns the old value if key is already present or null
+ * \returns the old value if \p key is already present or NULL
*/
gpointer
mono_conc_hashtable_remove (MonoConcurrentHashTable *hash_table, gpointer key)
kvs [i].value = NULL;
mono_memory_barrier ();
kvs [i].key = TOMBSTONE;
+ --hash_table->element_count;
if (hash_table->key_destroy_func != NULL)
(*hash_table->key_destroy_func) (key);
}
/**
* mono_conc_hashtable_insert:
- *
* Insert a value into the hashtable. Requires external locking.
- * @Returns the old value if key is already present or null
+ * \returns the old value if \p key is already present or NULL
*/
gpointer
mono_conc_hashtable_insert (MonoConcurrentHashTable *hash_table, gpointer key, gpointer value)
/**
* mono_conc_hashtable_foreach:
- *
- * Calls @func for each value in the hashtable. Requires external locking.
+ * Calls \p func for each value in the hashtable. Requires external locking.
*/
void
mono_conc_hashtable_foreach (MonoConcurrentHashTable *hash_table, GHFunc func, gpointer userdata)
}
}
}
+
+/**
+ * mono_conc_hashtable_foreach_steal:
+ *
+ * Calls @func for each entry in the hashtable, if @func returns true, remove from the hashtable. Requires external locking.
+ * Same semantics as g_hash_table_foreach_steal.
+ */
+void
+mono_conc_hashtable_foreach_steal (MonoConcurrentHashTable *hash_table, GHRFunc func, gpointer userdata)
+{
+ int i;
+ conc_table *table = (conc_table*)hash_table->table;
+ key_value_pair *kvs = table->kvs;
+
+ for (i = 0; i < table->table_size; ++i) {
+ if (kvs [i].key && kvs [i].key != TOMBSTONE) {
+ if (func (kvs [i].key, kvs [i].value, userdata)) {
+ kvs [i].value = NULL;
+ mono_memory_barrier ();
+ kvs [i].key = TOMBSTONE;
+ --hash_table->element_count;
+ }
+ }
+ }
+}