GNUnet  0.11.x
container_multiuuidmap.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2008, 2012 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
28 
29 #define LOG(kind, ...) \
30  GNUNET_log_from (kind, "util-container-multiuuidmap", __VA_ARGS__)
31 
38 #define NEXT_CACHE_SIZE 16
39 
40 
44 struct BigMapEntry
45 {
49  void *value;
50 
54  struct BigMapEntry *next;
55 
59  struct GNUNET_Uuid key;
60 };
61 
62 
66 struct SmallMapEntry
67 {
71  void *value;
72 
76  struct SmallMapEntry *next;
77 
81  const struct GNUNET_Uuid *key;
82 };
83 
84 
88 union MapEntry
89 {
93  struct SmallMapEntry *sme;
94 
98  struct BigMapEntry *bme;
99 };
100 
101 
106 {
110  union MapEntry *map;
111 
115  unsigned int size;
116 
120  unsigned int map_length;
121 
127 
132  unsigned int modification_counter;
133 
139  union MapEntry next_cache[NEXT_CACHE_SIZE];
140 
145  unsigned int next_cache_off;
146 };
147 
148 
154 {
158  union MapEntry me;
159 
163  unsigned int idx;
164 
169  unsigned int modification_counter;
170 
175 };
176 
177 
194 GNUNET_CONTAINER_multiuuidmap_create (unsigned int len, int do_not_copy_keys)
195 {
197 
198  GNUNET_assert (len > 0);
200  map->map = GNUNET_malloc_large (len * sizeof(union MapEntry));
201  if (NULL == map->map)
202  {
203  GNUNET_free (map);
204  return NULL;
205  }
206  map->map_length = len;
207  map->use_small_entries = do_not_copy_keys;
208  return map;
209 }
210 
211 
218 void
221 {
222  GNUNET_assert (0 == map->next_cache_off);
223  for (unsigned int i = 0; i < map->map_length; i++)
224  {
225  union MapEntry me;
226 
227  me = map->map[i];
228  if (map->use_small_entries)
229  {
230  struct SmallMapEntry *sme;
231  struct SmallMapEntry *nxt;
232 
233  nxt = me.sme;
234  while (NULL != (sme = nxt))
235  {
236  nxt = sme->next;
237  GNUNET_free (sme);
238  }
239  me.sme = NULL;
240  }
241  else
242  {
243  struct BigMapEntry *bme;
244  struct BigMapEntry *nxt;
245 
246  nxt = me.bme;
247  while (NULL != (bme = nxt))
248  {
249  nxt = bme->next;
250  GNUNET_free (bme);
251  }
252  me.bme = NULL;
253  }
254  }
255  GNUNET_free (map->map);
256  GNUNET_free (map);
257 }
258 
259 
267 static unsigned int
269  const struct GNUNET_Uuid *key)
270 {
271  unsigned int kx;
272 
273  GNUNET_assert (NULL != map);
274  GNUNET_memcpy (&kx, key, sizeof(kx));
275  return kx % map->map_length;
276 }
277 
278 
285 unsigned int
287  const struct GNUNET_CONTAINER_MultiUuidmap *map)
288 {
289  return map->size;
290 }
291 
292 
303 void *
305  const struct GNUNET_CONTAINER_MultiUuidmap *map,
306  const struct GNUNET_Uuid *key)
307 {
308  union MapEntry me;
309 
310  me = map->map[idx_of (map, key)];
311  if (map->use_small_entries)
312  {
313  for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
314  if (0 == GNUNET_memcmp (key, sme->key))
315  return sme->value;
316  }
317  else
318  {
319  for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
320  if (0 == GNUNET_memcmp (key, &bme->key))
321  return bme->value;
322  }
323  return NULL;
324 }
325 
326 
336 int
340  void *it_cls)
341 {
342  int count;
343  union MapEntry me;
344  union MapEntry *ce;
345  struct GNUNET_Uuid kc;
346 
347  count = 0;
348  GNUNET_assert (NULL != map);
349  ce = &map->next_cache[map->next_cache_off];
351  for (unsigned int i = 0; i < map->map_length; i++)
352  {
353  me = map->map[i];
354  if (map->use_small_entries)
355  {
356  struct SmallMapEntry *sme;
357 
358  ce->sme = me.sme;
359  while (NULL != (sme = ce->sme))
360  {
361  ce->sme = sme->next;
362  if ((NULL != it) && (GNUNET_OK != it (it_cls, sme->key, sme->value)))
363  {
365  return GNUNET_SYSERR;
366  }
367  count++;
368  }
369  }
370  else
371  {
372  struct BigMapEntry *bme;
373 
374  ce->bme = me.bme;
375  while (NULL != (bme = ce->bme))
376  {
377  ce->bme = bme->next;
378  if (NULL != it)
379  {
380  kc = bme->key;
381  if (GNUNET_OK != it (it_cls, &kc, bme->value))
382  {
384  return GNUNET_SYSERR;
385  }
386  }
387  count++;
388  }
389  }
390  }
392  return count;
393 }
394 
395 
403 static void
405  const struct BigMapEntry *bme)
406 {
407  for (unsigned int i = 0; i < map->next_cache_off; i++)
408  if (map->next_cache[i].bme == bme)
409  map->next_cache[i].bme = bme->next;
410 }
411 
412 
420 static void
422  const struct SmallMapEntry *sme)
423 {
424  for (unsigned int i = 0; i < map->next_cache_off; i++)
425  if (map->next_cache[i].sme == sme)
426  map->next_cache[i].sme = sme->next;
427 }
428 
429 
441 int
443  const struct GNUNET_Uuid *key,
444  const void *value)
445 {
446  union MapEntry me;
447  unsigned int i;
448 
449  map->modification_counter++;
450  i = idx_of (map, key);
451  me = map->map[i];
452  if (map->use_small_entries)
453  {
454  struct SmallMapEntry *p = NULL;
455 
456  for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
457  {
458  if ((0 == GNUNET_memcmp (key, sme->key)) && (value == sme->value))
459  {
460  if (NULL == p)
461  map->map[i].sme = sme->next;
462  else
463  p->next = sme->next;
464  update_next_cache_sme (map, sme);
465  GNUNET_free (sme);
466  map->size--;
467  return GNUNET_YES;
468  }
469  p = sme;
470  }
471  }
472  else
473  {
474  struct BigMapEntry *p = NULL;
475 
476  for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
477  {
478  if ((0 == GNUNET_memcmp (key, &bme->key)) && (value == bme->value))
479  {
480  if (NULL == p)
481  map->map[i].bme = bme->next;
482  else
483  p->next = bme->next;
484  update_next_cache_bme (map, bme);
485  GNUNET_free (bme);
486  map->size--;
487  return GNUNET_YES;
488  }
489  p = bme;
490  }
491  }
492  return GNUNET_NO;
493 }
494 
495 
504 int
507  const struct GNUNET_Uuid *key)
508 {
509  union MapEntry me;
510  unsigned int i;
511  int ret;
512 
513  map->modification_counter++;
514 
515  ret = 0;
516  i = idx_of (map, key);
517  me = map->map[i];
518  if (map->use_small_entries)
519  {
520  struct SmallMapEntry *sme;
521  struct SmallMapEntry *p;
522 
523  p = NULL;
524  sme = me.sme;
525  while (NULL != sme)
526  {
527  if (0 == GNUNET_memcmp (key, sme->key))
528  {
529  if (NULL == p)
530  map->map[i].sme = sme->next;
531  else
532  p->next = sme->next;
533  update_next_cache_sme (map, sme);
534  GNUNET_free (sme);
535  map->size--;
536  if (NULL == p)
537  sme = map->map[i].sme;
538  else
539  sme = p->next;
540  ret++;
541  }
542  else
543  {
544  p = sme;
545  sme = sme->next;
546  }
547  }
548  }
549  else
550  {
551  struct BigMapEntry *bme;
552  struct BigMapEntry *p;
553 
554  p = NULL;
555  bme = me.bme;
556  while (NULL != bme)
557  {
558  if (0 == GNUNET_memcmp (key, &bme->key))
559  {
560  if (NULL == p)
561  map->map[i].bme = bme->next;
562  else
563  p->next = bme->next;
564  update_next_cache_bme (map, bme);
565  GNUNET_free (bme);
566  map->size--;
567  if (NULL == p)
568  bme = map->map[i].bme;
569  else
570  bme = p->next;
571  ret++;
572  }
573  else
574  {
575  p = bme;
576  bme = bme->next;
577  }
578  }
579  }
580  return ret;
581 }
582 
583 
593 int
595  const struct GNUNET_CONTAINER_MultiUuidmap *map,
596  const struct GNUNET_Uuid *key)
597 {
598  union MapEntry me;
599 
600  me = map->map[idx_of (map, key)];
601  if (map->use_small_entries)
602  {
603  for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
604  if (0 == GNUNET_memcmp (key, sme->key))
605  return GNUNET_YES;
606  }
607  else
608  {
609  for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
610  if (0 == GNUNET_memcmp (key, &bme->key))
611  return GNUNET_YES;
612  }
613  return GNUNET_NO;
614 }
615 
616 
627 int
629  const struct GNUNET_CONTAINER_MultiUuidmap *map,
630  const struct GNUNET_Uuid *key,
631  const void *value)
632 {
633  union MapEntry me;
634 
635  me = map->map[idx_of (map, key)];
636  if (map->use_small_entries)
637  {
638  for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
639  if ((0 == GNUNET_memcmp (key, sme->key)) && (sme->value == value))
640  return GNUNET_YES;
641  }
642  else
643  {
644  for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
645  if ((0 == GNUNET_memcmp (key, &bme->key)) && (bme->value == value))
646  return GNUNET_YES;
647  }
648  return GNUNET_NO;
649 }
650 
651 
657 static void
659 {
660  union MapEntry *old_map;
661  union MapEntry *new_map;
662  unsigned int old_len;
663  unsigned int new_len;
664  unsigned int idx;
665 
666  old_map = map->map;
667  old_len = map->map_length;
668  new_len = old_len * 2;
669  if (0 == new_len) /* 2^31 * 2 == 0 */
670  new_len = old_len; /* never use 0 */
671  if (new_len == old_len)
672  return; /* nothing changed */
673  new_map = GNUNET_malloc_large (new_len * sizeof(union MapEntry));
674  if (NULL == new_map)
675  return; /* grow not possible */
676  map->modification_counter++;
677  map->map_length = new_len;
678  map->map = new_map;
679  for (unsigned int i = 0; i < old_len; i++)
680  {
681  if (map->use_small_entries)
682  {
683  struct SmallMapEntry *sme;
684 
685  while (NULL != (sme = old_map[i].sme))
686  {
687  old_map[i].sme = sme->next;
688  idx = idx_of (map, sme->key);
689  sme->next = new_map[idx].sme;
690  new_map[idx].sme = sme;
691  }
692  }
693  else
694  {
695  struct BigMapEntry *bme;
696 
697  while (NULL != (bme = old_map[i].bme))
698  {
699  old_map[i].bme = bme->next;
700  idx = idx_of (map, &bme->key);
701  bme->next = new_map[idx].bme;
702  new_map[idx].bme = bme;
703  }
704  }
705  }
706  GNUNET_free (old_map);
707 }
708 
709 
722 int
724  const struct GNUNET_Uuid *key,
725  void *value,
727 {
728  union MapEntry me;
729  unsigned int i;
730 
731  i = idx_of (map, key);
734  {
735  me = map->map[i];
736  if (map->use_small_entries)
737  {
738  for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
739  if (0 == GNUNET_memcmp (key, sme->key))
740  {
742  return GNUNET_SYSERR;
743  sme->value = value;
744  return GNUNET_NO;
745  }
746  }
747  else
748  {
749  for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
750  if (0 == GNUNET_memcmp (key, &bme->key))
751  {
753  return GNUNET_SYSERR;
754  bme->value = value;
755  return GNUNET_NO;
756  }
757  }
758  }
759  if (map->size / 3 >= map->map_length / 4)
760  {
761  grow (map);
762  i = idx_of (map, key);
763  }
764  if (map->use_small_entries)
765  {
766  struct SmallMapEntry *sme;
767 
768  sme = GNUNET_new (struct SmallMapEntry);
769  sme->key = key;
770  sme->value = value;
771  sme->next = map->map[i].sme;
772  map->map[i].sme = sme;
773  }
774  else
775  {
776  struct BigMapEntry *bme;
777 
778  bme = GNUNET_new (struct BigMapEntry);
779  bme->key = *key;
780  bme->value = value;
781  bme->next = map->map[i].bme;
782  map->map[i].bme = bme;
783  }
784  map->size++;
785  return GNUNET_OK;
786 }
787 
788 
799 int
802  const struct GNUNET_Uuid *key,
804  void *it_cls)
805 {
806  int count;
807  union MapEntry me;
808  union MapEntry *ce;
809 
810  ce = &map->next_cache[map->next_cache_off];
812  count = 0;
813  me = map->map[idx_of (map, key)];
814  if (map->use_small_entries)
815  {
816  struct SmallMapEntry *sme;
817 
818  ce->sme = me.sme;
819  while (NULL != (sme = ce->sme))
820  {
821  ce->sme = sme->next;
822  if (0 != GNUNET_memcmp (key, sme->key))
823  continue;
824  if ((NULL != it) && (GNUNET_OK != it (it_cls, key, sme->value)))
825  {
827  return GNUNET_SYSERR;
828  }
829  count++;
830  }
831  }
832  else
833  {
834  struct BigMapEntry *bme;
835 
836  ce->bme = me.bme;
837  while (NULL != (bme = ce->bme))
838  {
839  ce->bme = bme->next;
840  if (0 != GNUNET_memcmp (key, &bme->key))
841  continue;
842  if ((NULL != it) && (GNUNET_OK != it (it_cls, key, bme->value)))
843  {
845  return GNUNET_SYSERR;
846  }
847  count++;
848  }
849  }
851  return count;
852 }
853 
854 
866 unsigned int
868  const struct GNUNET_CONTAINER_MultiUuidmap *map,
870  void *it_cls)
871 {
872  unsigned int off;
873  union MapEntry me;
874 
875  if (0 == map->size)
876  return 0;
877  if (NULL == it)
878  return 1;
880  for (unsigned int idx = 0; idx < map->map_length; idx++)
881  {
882  me = map->map[idx];
883  if (map->use_small_entries)
884  {
885  for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
886  {
887  if (0 == off)
888  {
889  if (GNUNET_OK != it (it_cls, sme->key, sme->value))
890  return GNUNET_SYSERR;
891  return 1;
892  }
893  off--;
894  }
895  }
896  else
897  {
898  for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
899  {
900  if (0 == off)
901  {
902  if (GNUNET_OK != it (it_cls, &bme->key, bme->value))
903  return GNUNET_SYSERR;
904  return 1;
905  }
906  off--;
907  }
908  }
909  }
910  GNUNET_break (0);
911  return GNUNET_SYSERR;
912 }
913 
914 
929  const struct GNUNET_CONTAINER_MultiUuidmap *map)
930 {
932 
934  iter->map = map;
936  iter->me = map->map[0];
937  return iter;
938 }
939 
940 
955 int
958  struct GNUNET_Uuid *key,
959  const void **value)
960 {
961  /* make sure the map has not been modified */
963 
964  /* look for the next entry, skipping empty buckets */
965  while (1)
966  {
967  if (iter->idx >= iter->map->map_length)
968  return GNUNET_NO;
969  if (GNUNET_YES == iter->map->use_small_entries)
970  {
971  if (NULL != iter->me.sme)
972  {
973  if (NULL != key)
974  *key = *iter->me.sme->key;
975  if (NULL != value)
976  *value = iter->me.sme->value;
977  iter->me.sme = iter->me.sme->next;
978  return GNUNET_YES;
979  }
980  }
981  else
982  {
983  if (NULL != iter->me.bme)
984  {
985  if (NULL != key)
986  *key = iter->me.bme->key;
987  if (NULL != value)
988  *value = iter->me.bme->value;
989  iter->me.bme = iter->me.bme->next;
990  return GNUNET_YES;
991  }
992  }
993  iter->idx += 1;
994  if (iter->idx < iter->map->map_length)
995  iter->me = iter->map->map[iter->idx];
996  }
997 }
998 
999 
1005 void
1008 {
1009  GNUNET_free (iter);
1010 }
1011 
1012 
1013 /* end of container_multiuuidmap.c */
static void update_next_cache_sme(struct GNUNET_CONTAINER_MultiUuidmap *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 th...
void GNUNET_CONTAINER_multiuuidmap_iterator_destroy(struct GNUNET_CONTAINER_MultiUuidmapIterator *iter)
Destroy a multiuuidmap iterator.
static GNUNET_NETWORK_STRUCT_END struct GNUNET_PeerIdentity me
Our own peer identity.
GNUNET_CONTAINER_MultiHashMapOption
Options for storing values in the HashMap.
struct SmallMapEntry * next
If there is a hash collision, we create a linked list.
int GNUNET_CONTAINER_multiuuidmap_iterate(struct GNUNET_CONTAINER_MultiUuidmap *map, GNUNET_CONTAINER_MultiUuidmapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
void * value
Value of the entry.
int GNUNET_CONTAINER_multiuuidmap_remove_all(struct GNUNET_CONTAINER_MultiUuidmap *map, const struct GNUNET_Uuid *key)
Remove all entries for the given key from the map.
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static void grow(struct GNUNET_CONTAINER_MultiUuidmap *map)
Grow the given map to a more appropriate size.
int GNUNET_CONTAINER_multiuuidmap_put(struct GNUNET_CONTAINER_MultiUuidmap *map, const struct GNUNET_Uuid *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
void GNUNET_CONTAINER_multiuuidmap_destroy(struct GNUNET_CONTAINER_MultiUuidmap *map)
Destroy a hash map.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
const struct GNUNET_HashCode * key
Key for the entry.
#define GNUNET_NO
Definition: gnunet_common.h:78
void * value
Value of the entry.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_new(type)
Allocate a struct or union of the given type.
unsigned int modification_counter
Modification counter as observed on the map when the iterator was created.
struct SmallMapEntry * sme
Variant used if map entries only contain a pointer to the key.
int GNUNET_CONTAINER_multiuuidmap_remove(struct GNUNET_CONTAINER_MultiUuidmap *map, const struct GNUNET_Uuid *key, const void *value)
Remove the given key-value pair from the map.
Internal representation of the hash map.
#define GNUNET_malloc_large(size)
Wrapper around malloc.
#define NEXT_CACHE_SIZE
Maximum recursion depth for callbacks of GNUNET_CONTAINER_multihashmap_get_multiple() themselve s aga...
const struct GNUNET_CONTAINER_MultiUuidmap * map
Map that we are iterating over.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
unsigned int size
Number of entries in the map.
struct BigMapEntry * next
If there is a hash collision, we create a linked list.
static struct GNUNET_CONTAINER_MultiPeerMap * map
Handle to the map used to store old latency values for peers.
int GNUNET_CONTAINER_multiuuidmap_get_multiple(struct GNUNET_CONTAINER_MultiUuidmap *map, const struct GNUNET_Uuid *key, GNUNET_CONTAINER_MultiUuidmapIteratorCallback it, void *it_cls)
Iterate over all entries in the map that match a particular key.
unsigned int idx
Current bucket index.
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-qr.c:59
, &#39; bother checking if a value already exists (faster than GNUNET_CONTAINER_MULTIHASHMAPOPTION_...
Entry in the map.
unsigned int GNUNET_CONTAINER_multiuuidmap_get_random(const struct GNUNET_CONTAINER_MultiUuidmap *map, GNUNET_CONTAINER_MultiUuidmapIteratorCallback it, void *it_cls)
Call it on a random value from the map, or not at all if the map is empty.
Randomness for IVs etc.
A UUID, a 128 bit random value.
struct GNUNET_CONTAINER_MultiUuidmap * GNUNET_CONTAINER_multiuuidmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
union MapEntry me
Position in the bucket &#39;idx&#39;.
unsigned int GNUNET_CONTAINER_multiuuidmap_size(const struct GNUNET_CONTAINER_MultiUuidmap *map)
Get the number of key-value pairs in the map.
There must only be one value per key; storing a value should fail if a value under the same key alrea...
unsigned int modification_counter
Counts the destructive modifications (grow, remove) to the map, so that iterators can check if they a...
int GNUNET_CONTAINER_multiuuidmap_contains(const struct GNUNET_CONTAINER_MultiUuidmap *map, const struct GNUNET_Uuid *key)
Check if the map contains any value under the given key (including values that are NULL)...
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
struct GNUNET_CONTAINER_MultiUuidmapIterator * GNUNET_CONTAINER_multiuuidmap_iterator_create(const struct GNUNET_CONTAINER_MultiUuidmap *map)
Create an iterator for a multiuuidmap.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
int(* GNUNET_CONTAINER_MultiUuidmapIteratorCallback)(void *cls, const struct GNUNET_Uuid *key, void *value)
Iterator over uuid map entries.
Allow multiple values with the same key.
static void update_next_cache_bme(struct GNUNET_CONTAINER_MultiUuidmap *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 th...
An entry in the hash map with just a pointer to the key.
const struct GNUNET_Uuid * key
Key for the entry.
int GNUNET_CONTAINER_multiuuidmap_contains_value(const struct GNUNET_CONTAINER_MultiUuidmap *map, const struct GNUNET_Uuid *key, const void *value)
Check if the map contains the given value under the given key.
int GNUNET_CONTAINER_multiuuidmap_iterator_next(struct GNUNET_CONTAINER_MultiUuidmapIterator *iter, struct GNUNET_Uuid *key, const void **value)
Retrieve the next element from the hash map at the iterator&#39;s position.
static unsigned int idx_of(const struct GNUNET_CONTAINER_MultiUuidmap *map, const struct GNUNET_Uuid *key)
Compute the index of the bucket for the given key.
unsigned int next_cache_off
Offset of next_cache entries in use, must be smaller than NEXT_CACHE_SIZE.
int use_small_entries
GNUNET_NO if the map entries are of type &#39;struct BigMapEntry&#39;, GNUNET_YES if the map entries are of t...
An entry in the hash map with the full key.
union MapEntry next_cache[16]
Map entries indicating iteration positions currently in use by GNUNET_CONTAINER_multihashmap_get_mult...
#define GNUNET_YES
Definition: gnunet_common.h:77
struct BigMapEntry * bme
Variant used if map entries contain the full key.
unsigned int map_length
Length of the "map" array.
union MapEntry * map
All of our buckets.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_HashCode key
Key for the entry.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
void * GNUNET_CONTAINER_multiuuidmap_get(const struct GNUNET_CONTAINER_MultiUuidmap *map, const struct GNUNET_Uuid *key)
Given a key find a value in the map matching the key.