regen pidl all: rm epan/dissectors/pidl/*-stamp; pushd epan/dissectors/pidl/ && make...
[wireshark-sm.git] / wsutil / wmem / wmem_multimap.c
blobb36e5ced5fb6adaf64d5f2fbb29ce4aa0eb6cf22
1 /* wmem_multimap.c
2 * Wireshark Memory Manager Hash Multimap
3 * Copyright 2021, John Thacker <johnthacker@gmail.com>
4 * Copyright 2014, Evan Huus <eapache@gmail.com>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
12 #include "config.h"
14 #include <glib.h>
16 #include "wmem_core.h"
17 #include "wmem_list.h"
18 #include "wmem_map.h"
19 #include "wmem_multimap.h"
20 #include "wmem_tree.h"
21 #include "wmem_user_cb.h"
23 struct _wmem_multimap_t {
25 wmem_map_t *map;
27 unsigned metadata_scope_cb_id;
28 unsigned data_scope_cb_id;
30 wmem_allocator_t *metadata_allocator;
31 wmem_allocator_t *data_allocator;
34 wmem_multimap_t *
35 wmem_multimap_new(wmem_allocator_t *allocator,
36 GHashFunc hash_func, GEqualFunc eql_func)
38 wmem_multimap_t *multimap;
40 multimap = wmem_new(allocator, wmem_multimap_t);
42 multimap->map = wmem_map_new(allocator, hash_func, eql_func);
43 multimap->metadata_allocator = allocator;
44 multimap->data_allocator = allocator;
46 return multimap;
49 static bool
50 wmem_multimap_reset_cb(wmem_allocator_t *allocator _U_, wmem_cb_event_t event,
51 void *user_data)
53 wmem_multimap_t *multimap = (wmem_multimap_t*)user_data;
55 if (event == WMEM_CB_DESTROY_EVENT) {
56 wmem_unregister_callback(multimap->metadata_allocator, multimap->metadata_scope_cb_id);
57 wmem_free(multimap->metadata_allocator, multimap);
60 return true;
63 static bool
64 wmem_multimap_destroy_cb(wmem_allocator_t *allocator _U_, wmem_cb_event_t event _U_,
65 void *user_data)
67 wmem_multimap_t *multimap = (wmem_multimap_t*)user_data;
69 wmem_unregister_callback(multimap->data_allocator, multimap->data_scope_cb_id);
71 return false;
74 wmem_multimap_t *
75 wmem_multimap_new_autoreset(wmem_allocator_t *metadata_scope, wmem_allocator_t *data_scope,
76 GHashFunc hash_func, GEqualFunc eql_func)
78 wmem_multimap_t *multimap;
80 multimap = wmem_new(metadata_scope, wmem_multimap_t);
82 multimap->map = wmem_map_new_autoreset(metadata_scope, data_scope, hash_func, eql_func);
83 multimap->metadata_allocator = metadata_scope;
84 multimap->data_allocator = data_scope;
86 multimap->metadata_scope_cb_id = wmem_register_callback(metadata_scope, wmem_multimap_destroy_cb, multimap);
87 multimap->data_scope_cb_id = wmem_register_callback(data_scope, wmem_multimap_reset_cb, multimap);
89 return multimap;
92 wmem_list_t*
93 wmem_multimap_get_keys(wmem_allocator_t *list_allocator, wmem_multimap_t *map)
95 return wmem_map_get_keys(list_allocator, map->map);
98 static void
99 count_nodes(void * key _U_, void * value, void * user_data)
101 unsigned* count = (unsigned*)user_data;
102 (*count) += wmem_tree_count(value);
105 unsigned
106 wmem_multimap_size(wmem_multimap_t *map)
108 unsigned count = 0;
110 wmem_map_foreach(map->map, count_nodes, &count);
111 return count;
114 unsigned
115 wmem_multimap_count(wmem_multimap_t *map, const void *key)
117 wmem_tree_t *tree;
119 if ((tree = wmem_map_lookup(map->map, key)) == NULL) {
120 return 0;
122 return wmem_tree_count(tree);
125 bool
126 wmem_multimap_insert32(wmem_multimap_t *map, const void *key, uint32_t frame_num, void *value)
128 wmem_tree_t *tree;
129 bool ret = true;
131 if ((tree = wmem_map_lookup(map->map, key)) == NULL) {
132 tree = wmem_tree_new(map->data_allocator);
133 wmem_map_insert(map->map, key, tree);
134 ret = false;
136 wmem_tree_insert32(tree, frame_num, value);
138 return ret;
141 void *
142 wmem_multimap_lookup32(wmem_multimap_t *map, const void *key, uint32_t frame_num)
144 wmem_tree_t *tree;
146 if ((tree = wmem_map_lookup(map->map, key)) == NULL) {
147 return NULL;
149 return wmem_tree_lookup32(tree, frame_num);
152 void *
153 wmem_multimap_lookup32_le(wmem_multimap_t *map, const void *key, uint32_t frame_num)
155 wmem_tree_t *tree;
157 if ((tree = wmem_map_lookup(map->map, key)) == NULL) {
158 return NULL;
160 return wmem_tree_lookup32_le(tree, frame_num);
163 void *
164 wmem_multimap_remove32(wmem_multimap_t *map, const void *key, const uint32_t frame_num)
166 wmem_tree_t *tree;
168 if ((tree = wmem_map_lookup(map->map, key)) == NULL) {
169 return NULL;
171 return wmem_tree_remove32(tree, frame_num);
175 * Editor modelines - https://www.wireshark.org/tools/modelines.html
177 * Local variables:
178 * c-basic-offset: 4
179 * tab-width: 8
180 * indent-tabs-mode: nil
181 * End:
183 * vi: set shiftwidth=4 tabstop=8 expandtab:
184 * :indentSize=4:tabSize=8:noTabs=true: