forked from osmocom/wireshark
wmem: Add a wmem_map_foreach_remove function
Like wmem_map_remove(), this frees the key/value pair item in the map but not the key or the value itself (which may in fact be the same object.) Not generally a problem, as they'll get freed by the pool. (If someone wants to manage memory themselves, they should probably be using a GHashTable.)
This commit is contained in:
parent
c949c99ad1
commit
819d392aff
|
@ -283,6 +283,7 @@ libwsutil.so.0 libwsutil0 #MINVER#
|
|||
wmem_list_tail@Base 3.5.0
|
||||
wmem_map_contains@Base 3.5.0
|
||||
wmem_map_foreach@Base 3.5.0
|
||||
wmem_map_foreach_remove@Base 4.1.0
|
||||
wmem_map_get_keys@Base 3.5.0
|
||||
wmem_map_insert@Base 3.5.0
|
||||
wmem_map_lookup@Base 3.5.0
|
||||
|
|
|
@ -408,6 +408,34 @@ wmem_map_foreach(wmem_map_t *map, GHFunc foreach_func, gpointer user_data)
|
|||
}
|
||||
}
|
||||
|
||||
guint
|
||||
wmem_map_foreach_remove(wmem_map_t *map, GHRFunc foreach_func, gpointer user_data)
|
||||
{
|
||||
wmem_map_item_t **item, *tmp;
|
||||
unsigned i, deleted = 0;
|
||||
|
||||
/* Make sure we have a table */
|
||||
if (map->table == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < CAPACITY(map); i++) {
|
||||
item = &(map->table[i]);
|
||||
while (*item) {
|
||||
if (foreach_func((gpointer)(*item)->key, (gpointer)(*item)->value, user_data)) {
|
||||
tmp = *item;
|
||||
*item = tmp->next;
|
||||
wmem_free(map->data_allocator, tmp);
|
||||
map->count--;
|
||||
deleted++;
|
||||
} else {
|
||||
item = &((*item)->next);
|
||||
}
|
||||
}
|
||||
}
|
||||
return deleted;
|
||||
}
|
||||
|
||||
guint
|
||||
wmem_map_size(wmem_map_t *map)
|
||||
{
|
||||
|
|
|
@ -164,6 +164,20 @@ WS_DLL_PUBLIC
|
|||
void
|
||||
wmem_map_foreach(wmem_map_t *map, GHFunc foreach_func, gpointer user_data);
|
||||
|
||||
/** Run a function against all key/value pairs in the map. If the
|
||||
* function returns TRUE, then the key/value pair is removed from
|
||||
* the map. The order of the calls is unpredictable, since it is
|
||||
* based on the internal storage of data.
|
||||
*
|
||||
* @param map The map to use
|
||||
* @param foreach_func the function to call for each key/value pair
|
||||
* @param user_data user data to pass to the function
|
||||
* @return The number of items removed
|
||||
*/
|
||||
WS_DLL_PUBLIC
|
||||
guint
|
||||
wmem_map_foreach_remove(wmem_map_t *map, GHRFunc foreach_func, gpointer user_data);
|
||||
|
||||
/** Return the number of elements of the map.
|
||||
*
|
||||
* @param map The map to use
|
||||
|
|
|
@ -894,6 +894,12 @@ check_val_map(gpointer key _U_, gpointer val, gpointer user_data)
|
|||
g_assert_true(val == user_data);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
equal_val_map(gpointer key _U_, gpointer val, gpointer user_data)
|
||||
{
|
||||
return val == user_data;
|
||||
}
|
||||
|
||||
static void
|
||||
wmem_test_map(void)
|
||||
{
|
||||
|
@ -990,6 +996,9 @@ wmem_test_map(void)
|
|||
}
|
||||
wmem_map_foreach(map, check_val_map, GINT_TO_POINTER(2));
|
||||
|
||||
wmem_map_foreach_remove(map, equal_val_map, GINT_TO_POINTER(2));
|
||||
g_assert_true(wmem_map_size(map) == 0);
|
||||
|
||||
/* test size */
|
||||
map = wmem_map_new(allocator, g_direct_hash, g_direct_equal);
|
||||
g_assert_true(map);
|
||||
|
@ -998,6 +1007,11 @@ wmem_test_map(void)
|
|||
}
|
||||
g_assert_true(wmem_map_size(map) == CONTAINER_ITERS);
|
||||
|
||||
for (i=0; i<CONTAINER_ITERS; i+=2) {
|
||||
wmem_map_foreach_remove(map, equal_val_map, GINT_TO_POINTER(i));
|
||||
}
|
||||
g_assert_true(wmem_map_size(map) == CONTAINER_ITERS/2);
|
||||
|
||||
wmem_destroy_allocator(extra_allocator);
|
||||
wmem_destroy_allocator(allocator);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue