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_list_tail@Base 3.5.0
|
||||||
wmem_map_contains@Base 3.5.0
|
wmem_map_contains@Base 3.5.0
|
||||||
wmem_map_foreach@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_get_keys@Base 3.5.0
|
||||||
wmem_map_insert@Base 3.5.0
|
wmem_map_insert@Base 3.5.0
|
||||||
wmem_map_lookup@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
|
guint
|
||||||
wmem_map_size(wmem_map_t *map)
|
wmem_map_size(wmem_map_t *map)
|
||||||
{
|
{
|
||||||
|
|
|
@ -164,6 +164,20 @@ WS_DLL_PUBLIC
|
||||||
void
|
void
|
||||||
wmem_map_foreach(wmem_map_t *map, GHFunc foreach_func, gpointer user_data);
|
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.
|
/** Return the number of elements of the map.
|
||||||
*
|
*
|
||||||
* @param map The map to use
|
* @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);
|
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
|
static void
|
||||||
wmem_test_map(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(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 */
|
/* test size */
|
||||||
map = wmem_map_new(allocator, g_direct_hash, g_direct_equal);
|
map = wmem_map_new(allocator, g_direct_hash, g_direct_equal);
|
||||||
g_assert_true(map);
|
g_assert_true(map);
|
||||||
|
@ -998,6 +1007,11 @@ wmem_test_map(void)
|
||||||
}
|
}
|
||||||
g_assert_true(wmem_map_size(map) == CONTAINER_ITERS);
|
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(extra_allocator);
|
||||||
wmem_destroy_allocator(allocator);
|
wmem_destroy_allocator(allocator);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue