GNUnet debian-0.24.3-29-g453fda2cf
 
Loading...
Searching...
No Matches
container_multihashmap32.c File Reference

a version of hash map implemented in container_multihashmap.c but with uint32_t as keys More...

#include "platform.h"
#include "gnunet_util_lib.h"
Include dependency graph for container_multihashmap32.c:

Go to the source code of this file.

Data Structures

union  MapEntry
 Entry in the map. More...
 
struct  GNUNET_CONTAINER_MultiHashMap32
 Internal representation of the hash map. More...
 
struct  GNUNET_CONTAINER_MultiHashMap32Iterator
 Cursor into a multihashmap. More...
 

Macros

#define LOG(kind, ...)    GNUNET_log_from (kind, "util-container-multihashmap32", __VA_ARGS__)
 
#define NEXT_CACHE_SIZE   16
 Maximum recursion depth for callbacks of GNUNET_CONTAINER_multihashmap_get_multiple() themselves again calling GNUNET_CONTAINER_multihashmap_get_multiple().
 

Functions

struct GNUNET_CONTAINER_MultiHashMap32GNUNET_CONTAINER_multihashmap32_create (unsigned int len)
 Create a multi hash map.
 
void GNUNET_CONTAINER_multihashmap32_destroy (struct GNUNET_CONTAINER_MultiHashMap32 *map)
 Destroy a hash map.
 
static unsigned int idx_of (const struct GNUNET_CONTAINER_MultiHashMap32 *m, const uint32_t key)
 Compute the index of the bucket for the given key.
 
unsigned int GNUNET_CONTAINER_multihashmap32_size (const struct GNUNET_CONTAINER_MultiHashMap32 *map)
 Get the number of key-value pairs in the map.
 
void * GNUNET_CONTAINER_multihashmap32_get (const struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key)
 Given a key find a value in the map matching the key.
 
int GNUNET_CONTAINER_multihashmap32_iterate (struct GNUNET_CONTAINER_MultiHashMap32 *map, GNUNET_CONTAINER_MultiHashMapIterator32Callback it, void *it_cls)
 Iterate over all entries in the map.
 
static void update_next_cache (struct GNUNET_CONTAINER_MultiHashMap32 *map, const struct MapEntry *me)
 We are about to free() the me, make sure it is not in the list of next values for any iterator in the map's next_cache.
 
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap32_remove (struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key, const void *value)
 Remove the given key-value pair from the map.
 
int GNUNET_CONTAINER_multihashmap32_remove_all (struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key)
 Remove all entries for the given key from the map.
 
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap32_contains (const struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key)
 Check if the map contains any value under the given key (including values that are NULL).
 
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap32_contains_value (const struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key, const void *value)
 Check if the map contains the given value under the given key.
 
static void grow (struct GNUNET_CONTAINER_MultiHashMap32 *map)
 Grow the given map to a more appropriate size.
 
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap32_put (struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
 Store a key-value pair in the map.
 
int GNUNET_CONTAINER_multihashmap32_get_multiple (struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key, GNUNET_CONTAINER_MultiHashMapIterator32Callback it, void *it_cls)
 Iterate over all entries in the map that match a particular key.
 
struct GNUNET_CONTAINER_MultiHashMap32IteratorGNUNET_CONTAINER_multihashmap32_iterator_create (const struct GNUNET_CONTAINER_MultiHashMap32 *map)
 Create an iterator for a multihashmap.
 
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap32_iterator_next (struct GNUNET_CONTAINER_MultiHashMap32Iterator *iter, uint32_t *key, const void **value)
 Retrieve the next element from the hash map at the iterator's position.
 
void GNUNET_CONTAINER_multihashmap32_iterator_destroy (struct GNUNET_CONTAINER_MultiHashMapIterator *iter)
 Destroy a multihashmap iterator.
 

Detailed Description

a version of hash map implemented in container_multihashmap.c but with uint32_t as keys

Author
Christian Grothoff
Sree Harsha Totakura

Definition in file container_multihashmap32.c.

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)     GNUNET_log_from (kind, "util-container-multihashmap32", __VA_ARGS__)

Definition at line 32 of file container_multihashmap32.c.

47{
51 uint32_t key;
52
56 void *value;
57
61 struct MapEntry *next;
62};
63
68{
72 struct MapEntry **map;
73
77 unsigned int size;
78
82 unsigned int map_length;
83
88 unsigned int modification_counter;
89
96
101 unsigned int next_cache_off;
102};
103
104
110{
114 struct MapEntry *me;
115
119 unsigned int idx;
120
125 unsigned int modification_counter;
126
131};
132
133
142{
144
145 GNUNET_assert (len > 0);
147 ret->map = GNUNET_malloc_large (len * sizeof(struct MapEntry *));
148 if (NULL == ret->map)
149 {
151 return NULL;
152 }
153 ret->map_length = len;
154 return ret;
155}
156
157
164void
167{
168 struct MapEntry *e;
169
170 for (unsigned int i = 0; i < map->map_length; i++)
171 {
172 while (NULL != (e = map->map[i]))
173 {
174 map->map[i] = e->next;
175 GNUNET_free (e);
176 }
177 }
180}
181
182
190static unsigned int
191idx_of (const struct GNUNET_CONTAINER_MultiHashMap32 *m, const uint32_t key)
192{
193 GNUNET_assert (NULL != m);
194 return ((unsigned int) key) % m->map_length;
195}
196
197
198unsigned int
201{
202 return map->size;
203}
204
205
206void *
209 uint32_t key)
210{
211 struct MapEntry *e;
212
213 e = map->map[idx_of (map, key)];
214 while (NULL != e)
215 {
216 if (key == e->key)
217 return e->value;
218 e = e->next;
219 }
220 return NULL;
221}
222
223
224int
228 void *it_cls)
229{
230 int count;
231 struct MapEntry **ce;
232
233 count = 0;
234 GNUNET_assert (NULL != map);
237 for (unsigned int i = 0; i < map->map_length; i++)
238 {
239 struct MapEntry *e;
240
241 *ce = map->map[i];
242 while (NULL != (e = *ce))
243 {
244 *ce = e->next;
245 if (NULL != it)
246 {
247 if (GNUNET_OK != it (it_cls, e->key, e->value))
248 {
250 return GNUNET_SYSERR;
251 }
252 }
253 count++;
254 }
255 }
257 return count;
258}
259
260
268static void
270 const struct MapEntry *me)
271{
272 for (unsigned int i = 0; i < map->next_cache_off; i++)
273 if (map->next_cache[i] == me)
274 map->next_cache[i] = me->next;
275}
276
277
281 uint32_t key,
282 const void *value)
283{
284 struct MapEntry *e;
285 struct MapEntry *p;
286 unsigned int i;
287
289
290 i = idx_of (map, key);
291 p = NULL;
292 e = map->map[i];
293 while (e != NULL)
294 {
295 if ((key == e->key) && (value == e->value))
296 {
297 if (p == NULL)
298 map->map[i] = e->next;
299 else
300 p->next = e->next;
302 GNUNET_free (e);
303 map->size--;
304 return GNUNET_YES;
305 }
306 p = e;
307 e = e->next;
308 }
309 return GNUNET_NO;
310}
311
312
313int
316 uint32_t key)
317{
318 struct MapEntry *e;
319 struct MapEntry *p;
320 unsigned int i;
321 int ret;
322
324
325 ret = 0;
326 i = idx_of (map, key);
327 p = NULL;
328 e = map->map[i];
329 while (e != NULL)
330 {
331 if (key == e->key)
332 {
333 if (p == NULL)
334 map->map[i] = e->next;
335 else
336 p->next = e->next;
338 GNUNET_free (e);
339 map->size--;
340 if (p == NULL)
341 e = map->map[i];
342 else
343 e = p->next;
344 ret++;
345 }
346 else
347 {
348 p = e;
349 e = e->next;
350 }
351 }
352 return ret;
353}
354
355
359 uint32_t key)
360{
361 struct MapEntry *e;
362
363 e = map->map[idx_of (map, key)];
364 while (e != NULL)
365 {
366 if (key == e->key)
367 return GNUNET_YES;
368 e = e->next;
369 }
370 return GNUNET_NO;
371}
372
373
377 uint32_t key,
378 const void *value)
379{
380 struct MapEntry *e;
381
382 e = map->map[idx_of (map, key)];
383 while (e != NULL)
384 {
385 if ((key == e->key) && (e->value == value))
386 return GNUNET_YES;
387 e = e->next;
388 }
389 return GNUNET_NO;
390}
391
392
398static void
400{
401 struct MapEntry **old_map;
402 struct MapEntry **new_map;
403 struct MapEntry *e;
404 unsigned int old_len;
405 unsigned int new_len;
406 unsigned int idx;
407
408 old_map = map->map;
409 old_len = map->map_length;
410 new_len = old_len * 2;
411 if (0 == new_len) /* 2^31 * 2 == 0 */
412 new_len = old_len; /* never use 0 */
413 if (new_len == old_len)
414 return; /* nothing changed */
415 new_map = GNUNET_malloc_large (new_len * sizeof(struct MapEntry *));
416 if (NULL == new_map)
417 return; /* grow not possible */
419 map->map_length = new_len;
420 map->map = new_map;
421 for (unsigned int i = 0; i < old_len; i++)
422 {
423 while (NULL != (e = old_map[i]))
424 {
425 old_map[i] = e->next;
426 idx = idx_of (map, e->key);
427 e->next = new_map[idx];
428 new_map[idx] = e;
429 }
430 }
431 GNUNET_free (old_map);
432}
433
434
450 uint32_t key,
451 void *value,
453{
454 struct MapEntry *e;
455 unsigned int i;
456
457 i = idx_of (map, key);
460 {
461 e = map->map[i];
462 while (e != NULL)
463 {
464 if (key == e->key)
465 {
467 return GNUNET_SYSERR;
468 e->value = value;
469 return GNUNET_NO;
470 }
471 e = e->next;
472 }
473 }
474 if (map->size / 3 >= map->map_length / 4)
475 {
476 grow (map);
477 i = idx_of (map, key);
478 }
479 e = GNUNET_new (struct MapEntry);
480 e->key = key;
481 e->value = value;
482 e->next = map->map[i];
483 map->map[i] = e;
484 map->size++;
485 return GNUNET_OK;
486}
487
488
489int
492 uint32_t key,
494 void *it_cls)
495{
496 int count;
497 struct MapEntry *e;
498 struct MapEntry **ce;
499
500 count = 0;
503
504 *ce = map->map[idx_of (map, key)];
505 while (NULL != (e = *ce))
506 {
507 *ce = e->next;
508 if (key != e->key)
509 continue;
510 if ((NULL != it) && (GNUNET_OK != it (it_cls, key, e->value)))
511 {
513 return GNUNET_SYSERR;
514 }
515 count++;
516 }
518 return count;
519}
520
521
537{
539
541 iter->map = map;
543 iter->me = map->map[0];
544 return iter;
545}
546
547
565 uint32_t *key,
566 const void **value)
567{
568 /* make sure the map has not been modified */
570
571 /* look for the next entry, skipping empty buckets */
572 while (1)
573 {
574 if (iter->idx >= iter->map->map_length)
575 return GNUNET_NO;
576 if (NULL != iter->me)
577 {
578 if (NULL != key)
579 *key = iter->me->key;
580 if (NULL != value)
581 *value = iter->me->value;
582 iter->me = iter->me->next;
583 return GNUNET_YES;
584 }
585 iter->idx += 1;
586 if (iter->idx < iter->map->map_length)
587 iter->me = iter->map->map[iter->idx];
588 }
589}
590
591
597void
600{
601 GNUNET_free (iter);
602}
603
604
605/* end of container_multihashmap.c */
#define NEXT_CACHE_SIZE
Maximum recursion depth for callbacks of GNUNET_CONTAINER_multihashmap_get_multiple() themselves agai...
static unsigned int idx_of(const struct GNUNET_CONTAINER_MultiHashMap32 *m, const uint32_t key)
Compute the index of the bucket for the given key.
static void update_next_cache(struct GNUNET_CONTAINER_MultiHashMap32 *map, const struct MapEntry *me)
We are about to free() the me, make sure it is not in the list of next values for any iterator in the...
static void grow(struct GNUNET_CONTAINER_MultiHashMap32 *map)
Grow the given map to a more appropriate size.
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition gnunet-arm.c:103
static int ret
Final status code.
Definition gnunet-arm.c:93
static GNUNET_NETWORK_STRUCT_END struct GNUNET_PeerIdentity me
Our own peer identity.
struct GNUNET_HashCode key
The key used in the DHT.
static char * value
Value of the record to add/remove.
static struct GNUNET_OS_Process * p
Helper process we started.
Definition gnunet-uri.c:38
int GNUNET_CONTAINER_multihashmap32_get_multiple(struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key, GNUNET_CONTAINER_MultiHashMapIterator32Callback it, void *it_cls)
Iterate over all entries in the map that match a particular key.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap32_put(struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap32_contains(const struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key)
Check if the map contains any value under the given key (including values that are NULL).
struct GNUNET_CONTAINER_MultiHashMap32 * GNUNET_CONTAINER_multihashmap32_create(unsigned int len)
Create a multi hash map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap32_remove(struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key, const void *value)
Remove the given key-value pair from the map.
unsigned int GNUNET_CONTAINER_multihashmap32_size(const struct GNUNET_CONTAINER_MultiHashMap32 *map)
Get the number of key-value pairs in the map.
void * GNUNET_CONTAINER_multihashmap32_get(const struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key)
Given a key find a value in the map matching the key.
enum GNUNET_GenericReturnValue(* GNUNET_CONTAINER_MultiHashMapIterator32Callback)(void *cls, uint32_t key, void *value)
Iterator over hash map entries.
GNUNET_CONTAINER_MultiHashMapOption
Options for storing values in the HashMap.
void GNUNET_CONTAINER_multihashmap32_destroy(struct GNUNET_CONTAINER_MultiHashMap32 *map)
Destroy a hash map.
int GNUNET_CONTAINER_multihashmap32_remove_all(struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key)
Remove all entries for the given key from the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap32_contains_value(const struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key, const void *value)
Check if the map contains the given value under the given key.
int GNUNET_CONTAINER_multihashmap32_iterate(struct GNUNET_CONTAINER_MultiHashMap32 *map, GNUNET_CONTAINER_MultiHashMapIterator32Callback it, void *it_cls)
Iterate over all entries in the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST
, ' bother checking if a value already exists (faster than GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE...
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE
Allow multiple values with the same key.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...
struct GNUNET_CONTAINER_MultiHashMap32Iterator * GNUNET_CONTAINER_multihashmap32_iterator_create(const struct GNUNET_CONTAINER_MultiHashMap32 *map)
Create an iterator for a multihashmap.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap32_iterator_next(struct GNUNET_CONTAINER_MultiHashMap32Iterator *iter, uint32_t *key, const void **value)
Retrieve the next element from the hash map at the iterator's position.
void GNUNET_CONTAINER_multihashmap32_iterator_destroy(struct GNUNET_CONTAINER_MultiHashMapIterator *iter)
Destroy a multihashmap iterator.
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_malloc_large(size)
Wrapper around malloc.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
static struct GNUNET_CONTAINER_MultiPeerMap * map
Peermap of PeerIdentities to "struct PeerEntry" (for fast lookup).
Definition peer.c:63
struct MapEntry * me
Position in the bucket idx.
unsigned int modification_counter
Modification counter as observed on the map when the iterator was created.
const struct GNUNET_CONTAINER_MultiHashMap32 * map
Map that we are iterating over.
Internal representation of the hash map.
unsigned int modification_counter
Counts the destructive modifications (grow, remove) to the map, so that iterators can check if they a...
struct MapEntry * next_cache[16]
Map entries indicating iteration positions currently in use by GNUNET_CONTAINER_multihashmap_get_mult...
struct MapEntry ** map
All of our buckets.
unsigned int next_cache_off
Offset of next_cache entries in use, must be smaller than NEXT_CACHE_SIZE.
unsigned int map_length
Length of the map array.
unsigned int size
Number of entries in the map.
unsigned int next_cache_off
Offset of next_cache entries in use, must be smaller than NEXT_CACHE_SIZE.
unsigned int map_length
Length of the "map" array.
unsigned int modification_counter
Counts the destructive modifications (grow, remove) to the map, so that iterators can check if they a...
union MapEntry * map
All of our buckets.
unsigned int size
Number of entries in the map.
union MapEntry next_cache[16]
Map entries indicating iteration positions currently in use by GNUNET_CONTAINER_multihashmap_get_mult...
Entry in the map.
void * value
Value of the entry.
uint32_t key
Key for the entry.
struct MapEntry * next
If there is a hash collision, we create a linked list.

◆ NEXT_CACHE_SIZE

#define NEXT_CACHE_SIZE   16

Maximum recursion depth for callbacks of GNUNET_CONTAINER_multihashmap_get_multiple() themselves again calling GNUNET_CONTAINER_multihashmap_get_multiple().

Should be totally excessive, but if violated we die.

Definition at line 42 of file container_multihashmap32.c.

Function Documentation

◆ idx_of()

static unsigned int idx_of ( const struct GNUNET_CONTAINER_MultiHashMap32 m,
const uint32_t  key 
)
static

Compute the index of the bucket for the given key.

Parameters
mhash map for which to compute the index
keywhat key should the index be computed for
Returns
offset into the "map" array of "m"

Definition at line 192 of file container_multihashmap32.c.

193{
194 GNUNET_assert (NULL != m);
195 return ((unsigned int) key) % m->map_length;
196}

References GNUNET_assert, key, and m.

Referenced by GNUNET_CONTAINER_multihashmap32_contains(), GNUNET_CONTAINER_multihashmap32_contains_value(), GNUNET_CONTAINER_multihashmap32_get(), GNUNET_CONTAINER_multihashmap32_get_multiple(), GNUNET_CONTAINER_multihashmap32_put(), GNUNET_CONTAINER_multihashmap32_remove(), GNUNET_CONTAINER_multihashmap32_remove_all(), and grow().

Here is the caller graph for this function:

◆ update_next_cache()

static void update_next_cache ( struct GNUNET_CONTAINER_MultiHashMap32 map,
const struct MapEntry me 
)
static

We are about to free() the me, make sure it is not in the list of next values for any iterator in the map's next_cache.

Parameters
mapthe map to check
methe entry that is about to be free'd

Definition at line 270 of file container_multihashmap32.c.

272{
273 for (unsigned int i = 0; i < map->next_cache_off; i++)
274 if (map->next_cache[i] == me)
275 map->next_cache[i] = me->next;
276}

References map, me, GNUNET_CONTAINER_MultiPeerMap::next_cache, and GNUNET_CONTAINER_MultiPeerMap::next_cache_off.

Referenced by GNUNET_CONTAINER_multihashmap32_remove(), and GNUNET_CONTAINER_multihashmap32_remove_all().

Here is the caller graph for this function:

◆ grow()

static void grow ( struct GNUNET_CONTAINER_MultiHashMap32 map)
static

Grow the given map to a more appropriate size.

Parameters
mapthe hash map to grow

Definition at line 400 of file container_multihashmap32.c.

401{
402 struct MapEntry **old_map;
403 struct MapEntry **new_map;
404 struct MapEntry *e;
405 unsigned int old_len;
406 unsigned int new_len;
407 unsigned int idx;
408
409 old_map = map->map;
410 old_len = map->map_length;
411 new_len = old_len * 2;
412 if (0 == new_len) /* 2^31 * 2 == 0 */
413 new_len = old_len; /* never use 0 */
414 if (new_len == old_len)
415 return; /* nothing changed */
416 new_map = GNUNET_malloc_large (new_len * sizeof(struct MapEntry *));
417 if (NULL == new_map)
418 return; /* grow not possible */
420 map->map_length = new_len;
421 map->map = new_map;
422 for (unsigned int i = 0; i < old_len; i++)
423 {
424 while (NULL != (e = old_map[i]))
425 {
426 old_map[i] = e->next;
427 idx = idx_of (map, e->key);
428 e->next = new_map[idx];
429 new_map[idx] = e;
430 }
431 }
432 GNUNET_free (old_map);
433}

References GNUNET_free, GNUNET_malloc_large, idx_of(), MapEntry::key, GNUNET_CONTAINER_MultiPeerMap::map, map, GNUNET_CONTAINER_MultiPeerMap::map_length, GNUNET_CONTAINER_MultiPeerMap::modification_counter, and MapEntry::next.

Referenced by GNUNET_CONTAINER_multihashmap32_put().

Here is the call graph for this function:
Here is the caller graph for this function: