GNUnet 0.21.1
container_multishortmap.c File Reference

hash map where the same key may be present multiple times More...

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

Go to the source code of this file.

Data Structures

struct  BigMapEntry
 An entry in the hash map with the full key. More...
 
struct  SmallMapEntry
 An entry in the hash map with just a pointer to the key. More...
 
union  MapEntry
 Entry in the map. More...
 
struct  GNUNET_CONTAINER_MultiShortmap
 Internal representation of the hash map. More...
 
struct  GNUNET_CONTAINER_MultiShortmapIterator
 Cursor into a multishortmap. More...
 

Macros

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

Functions

struct GNUNET_CONTAINER_MultiShortmapGNUNET_CONTAINER_multishortmap_create (unsigned int len, int do_not_copy_keys)
 Create a multi hash map. More...
 
void GNUNET_CONTAINER_multishortmap_destroy (struct GNUNET_CONTAINER_MultiShortmap *map)
 Destroy a hash map. More...
 
static unsigned int idx_of (const struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key)
 Compute the index of the bucket for the given key. More...
 
unsigned int GNUNET_CONTAINER_multishortmap_size (const struct GNUNET_CONTAINER_MultiShortmap *map)
 Get the number of key-value pairs in the map. More...
 
void * GNUNET_CONTAINER_multishortmap_get (const struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key)
 Given a key find a value in the map matching the key. More...
 
int GNUNET_CONTAINER_multishortmap_iterate (struct GNUNET_CONTAINER_MultiShortmap *map, GNUNET_CONTAINER_ShortmapIterator it, void *it_cls)
 Iterate over all entries in the map. More...
 
static void update_next_cache_bme (struct GNUNET_CONTAINER_MultiShortmap *map, const struct BigMapEntry *bme)
 We are about to free() the bme, make sure it is not in the list of next values for any iterator in the map's next_cache. More...
 
static void update_next_cache_sme (struct GNUNET_CONTAINER_MultiShortmap *map, const struct SmallMapEntry *sme)
 We are about to free() the sme, make sure it is not in the list of next values for any iterator in the map's next_cache. More...
 
int GNUNET_CONTAINER_multishortmap_remove (struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key, const void *value)
 Remove the given key-value pair from the map. More...
 
int GNUNET_CONTAINER_multishortmap_remove_all (struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key)
 Remove all entries for the given key from the map. More...
 
int GNUNET_CONTAINER_multishortmap_contains (const struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key)
 Check if the map contains any value under the given key (including values that are NULL). More...
 
int GNUNET_CONTAINER_multishortmap_contains_value (const struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key, const void *value)
 Check if the map contains the given value under the given key. More...
 
static void grow (struct GNUNET_CONTAINER_MultiShortmap *map)
 Grow the given map to a more appropriate size. More...
 
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multishortmap_put (struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
 Store a key-value pair in the map. More...
 
int GNUNET_CONTAINER_multishortmap_get_multiple (struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key, GNUNET_CONTAINER_ShortmapIterator it, void *it_cls)
 Iterate over all entries in the map that match a particular key. More...
 
unsigned int GNUNET_CONTAINER_multishortmap_get_random (const struct GNUNET_CONTAINER_MultiShortmap *map, GNUNET_CONTAINER_ShortmapIterator it, void *it_cls)
 Call it on a random value from the map, or not at all if the map is empty. More...
 
struct GNUNET_CONTAINER_MultiShortmapIteratorGNUNET_CONTAINER_multishortmap_iterator_create (const struct GNUNET_CONTAINER_MultiShortmap *map)
 Create an iterator for a multihashmap. More...
 
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multishortmap_iterator_next (struct GNUNET_CONTAINER_MultiShortmapIterator *iter, struct GNUNET_ShortHashCode *key, const void **value)
 Retrieve the next element from the hash map at the iterator's position. More...
 
void GNUNET_CONTAINER_multishortmap_iterator_destroy (struct GNUNET_CONTAINER_MultiShortmapIterator *iter)
 Destroy a multishortmap iterator. More...
 

Detailed Description

hash map where the same key may be present multiple times

Author
Christian Grothoff

Definition in file container_multishortmap.c.

Macro Definition Documentation

◆ LOG

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

Definition at line 30 of file container_multishortmap.c.

◆ NEXT_CACHE_SIZE

#define NEXT_CACHE_SIZE   16

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

Should be totally excessive, but if violated we die.

Definition at line 39 of file container_multishortmap.c.

Function Documentation

◆ idx_of()

static unsigned int idx_of ( const struct GNUNET_CONTAINER_MultiShortmap map,
const struct GNUNET_ShortHashCode key 
)
static

Compute the index of the bucket for the given key.

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

Definition at line 263 of file container_multishortmap.c.

265{
266 unsigned int kx;
267
268 GNUNET_assert (NULL != map);
269 GNUNET_memcpy (&kx, key, sizeof(kx));
270 return kx % map->map_length;
271}
struct GNUNET_HashCode key
The key used in the DHT.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static struct GNUNET_CONTAINER_MultiPeerMap * map
Peermap of PeerIdentities to "struct PeerEntry" (for fast lookup).
Definition: peer.c:63
unsigned int map_length
Length of the "map" array.

References GNUNET_assert, GNUNET_memcpy, key, map, and GNUNET_CONTAINER_MultiPeerMap::map_length.

Referenced by GNUNET_CONTAINER_multishortmap_contains(), GNUNET_CONTAINER_multishortmap_contains_value(), GNUNET_CONTAINER_multishortmap_get(), GNUNET_CONTAINER_multishortmap_get_multiple(), GNUNET_CONTAINER_multishortmap_put(), GNUNET_CONTAINER_multishortmap_remove(), GNUNET_CONTAINER_multishortmap_remove_all(), and grow().

Here is the caller graph for this function:

◆ update_next_cache_bme()

static void update_next_cache_bme ( struct GNUNET_CONTAINER_MultiShortmap map,
const struct BigMapEntry bme 
)
static

We are about to free() the bme, 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
bmethe entry that is about to be free'd

Definition at line 374 of file container_multishortmap.c.

376{
377 for (unsigned int i = 0; i < map->next_cache_off; i++)
378 if (map->next_cache[i].bme == bme)
379 map->next_cache[i].bme = bme->next;
380}
struct BigMapEntry * next
If there is a hash collision, we create a linked list.
unsigned int next_cache_off
Offset of next_cache entries in use, must be smaller than NEXT_CACHE_SIZE.
union MapEntry next_cache[16]
Map entries indicating iteration positions currently in use by GNUNET_CONTAINER_multihashmap_get_mult...
struct BigMapEntry * bme
Variant used if map entries contain the full key.

References MapEntry::bme, map, BigMapEntry::next, GNUNET_CONTAINER_MultiPeerMap::next_cache, and GNUNET_CONTAINER_MultiPeerMap::next_cache_off.

Referenced by GNUNET_CONTAINER_multishortmap_remove(), and GNUNET_CONTAINER_multishortmap_remove_all().

Here is the caller graph for this function:

◆ update_next_cache_sme()

static void update_next_cache_sme ( struct GNUNET_CONTAINER_MultiShortmap map,
const struct SmallMapEntry sme 
)
static

We are about to free() the sme, 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
smethe entry that is about to be free'd

Definition at line 391 of file container_multishortmap.c.

393{
394 for (unsigned int i = 0; i < map->next_cache_off; i++)
395 if (map->next_cache[i].sme == sme)
396 map->next_cache[i].sme = sme->next;
397}
struct SmallMapEntry * next
If there is a hash collision, we create a linked list.
struct SmallMapEntry * sme
Variant used if map entries only contain a pointer to the key.

References map, SmallMapEntry::next, GNUNET_CONTAINER_MultiPeerMap::next_cache, GNUNET_CONTAINER_MultiPeerMap::next_cache_off, and MapEntry::sme.

Referenced by GNUNET_CONTAINER_multishortmap_remove(), and GNUNET_CONTAINER_multishortmap_remove_all().

Here is the caller graph for this function:

◆ grow()

static void grow ( struct GNUNET_CONTAINER_MultiShortmap map)
static

Grow the given map to a more appropriate size.

Parameters
mapthe hash map to grow

Definition at line 591 of file container_multishortmap.c.

592{
593 union MapEntry *old_map;
594 union MapEntry *new_map;
595 unsigned int old_len;
596 unsigned int new_len;
597 unsigned int idx;
598
599 old_map = map->map;
600 old_len = map->map_length;
601 new_len = old_len * 2;
602 if (0 == new_len) /* 2^31 * 2 == 0 */
603 new_len = old_len; /* never use 0 */
604 if (new_len == old_len)
605 return; /* nothing changed */
606 new_map = GNUNET_malloc_large (new_len * sizeof(union MapEntry));
607 if (NULL == new_map)
608 return; /* grow not possible */
610 map->map_length = new_len;
611 map->map = new_map;
612 for (unsigned int i = 0; i < old_len; i++)
613 {
615 {
616 struct SmallMapEntry *sme;
617
618 while (NULL != (sme = old_map[i].sme))
619 {
620 old_map[i].sme = sme->next;
621 idx = idx_of (map, sme->key);
622 sme->next = new_map[idx].sme;
623 new_map[idx].sme = sme;
624 }
625 }
626 else
627 {
628 struct BigMapEntry *bme;
629
630 while (NULL != (bme = old_map[i].bme))
631 {
632 old_map[i].bme = bme->next;
633 idx = idx_of (map, &bme->key);
634 bme->next = new_map[idx].bme;
635 new_map[idx].bme = bme;
636 }
637 }
638 }
639 GNUNET_free (old_map);
640}
static unsigned int idx_of(const struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key)
Compute the index of the bucket for the given key.
#define GNUNET_malloc_large(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
An entry in the hash map with the full key.
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.
int use_small_entries
GNUNET_NO if the map entries are of type 'struct BigMapEntry', GNUNET_YES if the map entries are of t...
An entry in the hash map with just a pointer to the key.
Entry in the map.

References MapEntry::bme, GNUNET_free, GNUNET_malloc_large, idx_of(), BigMapEntry::key, SmallMapEntry::key, GNUNET_CONTAINER_MultiPeerMap::map, map, GNUNET_CONTAINER_MultiPeerMap::map_length, GNUNET_CONTAINER_MultiPeerMap::modification_counter, BigMapEntry::next, SmallMapEntry::next, MapEntry::sme, and GNUNET_CONTAINER_MultiPeerMap::use_small_entries.

Referenced by GNUNET_CONTAINER_multishortmap_put().

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