GNUnet  0.10.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 {
46 
50  void *value;
51 
55  struct BigMapEntry *next;
56 
60  struct GNUNET_Uuid key;
61 };
62 
63 
67 struct SmallMapEntry
68 {
69 
73  void *value;
74 
78  struct SmallMapEntry *next;
79 
83  const struct GNUNET_Uuid *key;
84 };
85 
86 
90 union MapEntry
91 {
95  struct SmallMapEntry *sme;
96 
100  struct BigMapEntry *bme;
101 };
102 
103 
108 {
112  union MapEntry *map;
113 
117  unsigned int size;
118 
122  unsigned int map_length;
123 
129 
134  unsigned int modification_counter;
135 
141  union MapEntry next_cache[NEXT_CACHE_SIZE];
142 
147  unsigned int next_cache_off;
148 };
149 
150 
156 {
160  union MapEntry me;
161 
165  unsigned int idx;
166 
171  unsigned int modification_counter;
172 
177 };
178 
179 
196 GNUNET_CONTAINER_multiuuidmap_create (unsigned int len, int do_not_copy_keys)
197 {
199 
200  GNUNET_assert (len > 0);
202  map->map = GNUNET_malloc_large (len * sizeof (union MapEntry));
203  if (NULL == map->map)
204  {
205  GNUNET_free (map);
206  return NULL;
207  }
208  map->map_length = len;
209  map->use_small_entries = do_not_copy_keys;
210  return map;
211 }
212 
213 
220 void
223 {
224  GNUNET_assert (0 == map->next_cache_off);
225  for (unsigned int i = 0; i < map->map_length; i++)
226  {
227  union MapEntry me;
228 
229  me = map->map[i];
230  if (map->use_small_entries)
231  {
232  struct SmallMapEntry *sme;
233  struct SmallMapEntry *nxt;
234 
235  nxt = me.sme;
236  while (NULL != (sme = nxt))
237  {
238  nxt = sme->next;
239  GNUNET_free (sme);
240  }
241  me.sme = NULL;
242  }
243  else
244  {
245  struct BigMapEntry *bme;
246  struct BigMapEntry *nxt;
247 
248  nxt = me.bme;
249  while (NULL != (bme = nxt))
250  {
251  nxt = bme->next;
252  GNUNET_free (bme);
253  }
254  me.bme = NULL;
255  }
256  }
257  GNUNET_free (map->map);
258  GNUNET_free (map);
259 }
260 
261 
269 static unsigned int
271  const struct GNUNET_Uuid *key)
272 {
273  unsigned int kx;
274 
275  GNUNET_assert (NULL != map);
276  GNUNET_memcpy (&kx, key, sizeof (kx));
277  return kx % map->map_length;
278 }
279 
280 
287 unsigned int
289  const struct GNUNET_CONTAINER_MultiUuidmap *map)
290 {
291  return map->size;
292 }
293 
294 
305 void *
307  const struct GNUNET_CONTAINER_MultiUuidmap *map,
308  const struct GNUNET_Uuid *key)
309 {
310  union MapEntry me;
311 
312  me = map->map[idx_of (map, key)];
313  if (map->use_small_entries)
314  {
315  for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
316  if (0 == GNUNET_memcmp (key, sme->key))
317  return sme->value;
318  }
319  else
320  {
321  for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
322  if (0 == GNUNET_memcmp (key, &bme->key))
323  return bme->value;
324  }
325  return NULL;
326 }
327 
328 
338 int
342  void *it_cls)
343 {
344  int count;
345  union MapEntry me;
346  union MapEntry *ce;
347  struct GNUNET_Uuid kc;
348 
349  count = 0;
350  GNUNET_assert (NULL != map);
351  ce = &map->next_cache[map->next_cache_off];
353  for (unsigned int i = 0; i < map->map_length; i++)
354  {
355  me = map->map[i];
356  if (map->use_small_entries)
357  {
358  struct SmallMapEntry *sme;
359 
360  ce->sme = me.sme;
361  while (NULL != (sme = ce->sme))
362  {
363  ce->sme = sme->next;
364  if ((NULL != it) && (GNUNET_OK != it (it_cls, sme->key, sme->value)))
365  {
367  return GNUNET_SYSERR;
368  }
369  count++;
370  }
371  }
372  else
373  {
374  struct BigMapEntry *bme;
375 
376  ce->bme = me.bme;
377  while (NULL != (bme = ce->bme))
378  {
379  ce->bme = bme->next;
380  if (NULL != it)
381  {
382  kc = bme->key;
383  if (GNUNET_OK != it (it_cls, &kc, bme->value))
384  {
386  return GNUNET_SYSERR;
387  }
388  }
389  count++;
390  }
391  }
392  }
394  return count;
395 }
396 
397 
405 static void
407  const struct BigMapEntry *bme)
408 {
409  for (unsigned int i = 0; i < map->next_cache_off; i++)
410  if (map->next_cache[i].bme == bme)
411  map->next_cache[i].bme = bme->next;
412 }
413 
414 
422 static void
424  const struct SmallMapEntry *sme)
425 {
426  for (unsigned int i = 0; i < map->next_cache_off; i++)
427  if (map->next_cache[i].sme == sme)
428  map->next_cache[i].sme = sme->next;
429 }
430 
431 
443 int
445  const struct GNUNET_Uuid *key,
446  const void *value)
447 {
448  union MapEntry me;
449  unsigned int i;
450 
451  map->modification_counter++;
452  i = idx_of (map, key);
453  me = map->map[i];
454  if (map->use_small_entries)
455  {
456  struct SmallMapEntry *p = NULL;
457 
458  for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
459  {
460  if ((0 == GNUNET_memcmp (key, sme->key)) && (value == sme->value))
461  {
462  if (NULL == p)
463  map->map[i].sme = sme->next;
464  else
465  p->next = sme->next;
466  update_next_cache_sme (map, sme);
467  GNUNET_free (sme);
468  map->size--;
469  return GNUNET_YES;
470  }
471  p = sme;
472  }
473  }
474  else
475  {
476  struct BigMapEntry *p = NULL;
477 
478  for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
479  {
480  if ((0 == GNUNET_memcmp (key, &bme->key)) && (value == bme->value))
481  {
482  if (NULL == p)
483  map->map[i].bme = bme->next;
484  else
485  p->next = bme->next;
486  update_next_cache_bme (map, bme);
487  GNUNET_free (bme);
488  map->size--;
489  return GNUNET_YES;
490  }
491  p = bme;
492  }
493  }
494  return GNUNET_NO;
495 }
496 
497 
506 int
509  const struct GNUNET_Uuid *key)
510 {
511  union MapEntry me;
512  unsigned int i;
513  int ret;
514 
515  map->modification_counter++;
516 
517  ret = 0;
518  i = idx_of (map, key);
519  me = map->map[i];
520  if (map->use_small_entries)
521  {
522  struct SmallMapEntry *sme;
523  struct SmallMapEntry *p;
524 
525  p = NULL;
526  sme = me.sme;
527  while (NULL != sme)
528  {
529  if (0 == GNUNET_memcmp (key, sme->key))
530  {
531  if (NULL == p)
532  map->map[i].sme = sme->next;
533  else
534  p->next = sme->next;
535  update_next_cache_sme (map, sme);
536  GNUNET_free (sme);
537  map->size--;
538  if (NULL == p)
539  sme = map->map[i].sme;
540  else
541  sme = p->next;
542  ret++;
543  }
544  else
545  {
546  p = sme;
547  sme = sme->next;
548  }
549  }
550  }
551  else
552  {
553  struct BigMapEntry *bme;
554  struct BigMapEntry *p;
555 
556  p = NULL;
557  bme = me.bme;
558  while (NULL != bme)
559  {
560  if (0 == GNUNET_memcmp (key, &bme->key))
561  {
562  if (NULL == p)
563  map->map[i].bme = bme->next;
564  else
565  p->next = bme->next;
566  update_next_cache_bme (map, bme);
567  GNUNET_free (bme);
568  map->size--;
569  if (NULL == p)
570  bme = map->map[i].bme;
571  else
572  bme = p->next;
573  ret++;
574  }
575  else
576  {
577  p = bme;
578  bme = bme->next;
579  }
580  }
581  }
582  return ret;
583 }
584 
585 
595 int
597  const struct GNUNET_CONTAINER_MultiUuidmap *map,
598  const struct GNUNET_Uuid *key)
599 {
600  union MapEntry me;
601 
602  me = map->map[idx_of (map, key)];
603  if (map->use_small_entries)
604  {
605  for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
606  if (0 == GNUNET_memcmp (key, sme->key))
607  return GNUNET_YES;
608  }
609  else
610  {
611  for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
612  if (0 == GNUNET_memcmp (key, &bme->key))
613  return GNUNET_YES;
614  }
615  return GNUNET_NO;
616 }
617 
618 
629 int
631  const struct GNUNET_CONTAINER_MultiUuidmap *map,
632  const struct GNUNET_Uuid *key,
633  const void *value)
634 {
635  union MapEntry me;
636 
637  me = map->map[idx_of (map, key)];
638  if (map->use_small_entries)
639  {
640  for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
641  if ((0 == GNUNET_memcmp (key, sme->key)) && (sme->value == value))
642  return GNUNET_YES;
643  }
644  else
645  {
646  for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
647  if ((0 == GNUNET_memcmp (key, &bme->key)) && (bme->value == value))
648  return GNUNET_YES;
649  }
650  return GNUNET_NO;
651 }
652 
653 
659 static void
661 {
662  union MapEntry *old_map;
663  union MapEntry *new_map;
664  unsigned int old_len;
665  unsigned int new_len;
666  unsigned int idx;
667 
668  old_map = map->map;
669  old_len = map->map_length;
670  new_len = old_len * 2;
671  if (0 == new_len) /* 2^31 * 2 == 0 */
672  new_len = old_len; /* never use 0 */
673  if (new_len == old_len)
674  return; /* nothing changed */
675  new_map = GNUNET_malloc_large (new_len * sizeof (union MapEntry));
676  if (NULL == new_map)
677  return; /* grow not possible */
678  map->modification_counter++;
679  map->map_length = new_len;
680  map->map = new_map;
681  for (unsigned int i = 0; i < old_len; i++)
682  {
683  if (map->use_small_entries)
684  {
685  struct SmallMapEntry *sme;
686 
687  while (NULL != (sme = old_map[i].sme))
688  {
689  old_map[i].sme = sme->next;
690  idx = idx_of (map, sme->key);
691  sme->next = new_map[idx].sme;
692  new_map[idx].sme = sme;
693  }
694  }
695  else
696  {
697  struct BigMapEntry *bme;
698 
699  while (NULL != (bme = old_map[i].bme))
700  {
701  old_map[i].bme = bme->next;
702  idx = idx_of (map, &bme->key);
703  bme->next = new_map[idx].bme;
704  new_map[idx].bme = bme;
705  }
706  }
707  }
708  GNUNET_free (old_map);
709 }
710 
711 
724 int
726  const struct GNUNET_Uuid *key,
727  void *value,
729 {
730  union MapEntry me;
731  unsigned int i;
732 
733  i = idx_of (map, key);
736  {
737  me = map->map[i];
738  if (map->use_small_entries)
739  {
740  for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
741  if (0 == GNUNET_memcmp (key, sme->key))
742  {
744  return GNUNET_SYSERR;
745  sme->value = value;
746  return GNUNET_NO;
747  }
748  }
749  else
750  {
751  for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
752  if (0 == GNUNET_memcmp (key, &bme->key))
753  {
755  return GNUNET_SYSERR;
756  bme->value = value;
757  return GNUNET_NO;
758  }
759  }
760  }
761  if (map->size / 3 >= map->map_length / 4)
762  {
763  grow (map);
764  i = idx_of (map, key);
765  }
766  if (map->use_small_entries)
767  {
768  struct SmallMapEntry *sme;
769 
770  sme = GNUNET_new (struct SmallMapEntry);
771  sme->key = key;
772  sme->value = value;
773  sme->next = map->map[i].sme;
774  map->map[i].sme = sme;
775  }
776  else
777  {
778  struct BigMapEntry *bme;
779 
780  bme = GNUNET_new (struct BigMapEntry);
781  bme->key = *key;
782  bme->value = value;
783  bme->next = map->map[i].bme;
784  map->map[i].bme = bme;
785  }
786  map->size++;
787  return GNUNET_OK;
788 }
789 
790 
801 int
804  const struct GNUNET_Uuid *key,
806  void *it_cls)
807 {
808  int count;
809  union MapEntry me;
810  union MapEntry *ce;
811 
812  ce = &map->next_cache[map->next_cache_off];
814  count = 0;
815  me = map->map[idx_of (map, key)];
816  if (map->use_small_entries)
817  {
818  struct SmallMapEntry *sme;
819 
820  ce->sme = me.sme;
821  while (NULL != (sme = ce->sme))
822  {
823  ce->sme = sme->next;
824  if (0 != GNUNET_memcmp (key, sme->key))
825  continue;
826  if ((NULL != it) && (GNUNET_OK != it (it_cls, key, sme->value)))
827  {
829  return GNUNET_SYSERR;
830  }
831  count++;
832  }
833  }
834  else
835  {
836  struct BigMapEntry *bme;
837 
838  ce->bme = me.bme;
839  while (NULL != (bme = ce->bme))
840  {
841  ce->bme = bme->next;
842  if (0 != GNUNET_memcmp (key, &bme->key))
843  continue;
844  if ((NULL != it) && (GNUNET_OK != it (it_cls, key, bme->value)))
845  {
847  return GNUNET_SYSERR;
848  }
849  count++;
850  }
851  }
853  return count;
854 }
855 
856 
868 unsigned int
870  const struct GNUNET_CONTAINER_MultiUuidmap *map,
872  void *it_cls)
873 {
874  unsigned int off;
875  union MapEntry me;
876 
877  if (0 == map->size)
878  return 0;
879  if (NULL == it)
880  return 1;
882  for (unsigned int idx = 0; idx < map->map_length; idx++)
883  {
884  me = map->map[idx];
885  if (map->use_small_entries)
886  {
887  for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
888  {
889  if (0 == off)
890  {
891  if (GNUNET_OK != it (it_cls, sme->key, sme->value))
892  return GNUNET_SYSERR;
893  return 1;
894  }
895  off--;
896  }
897  }
898  else
899  {
900  for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
901  {
902  if (0 == off)
903  {
904  if (GNUNET_OK != it (it_cls, &bme->key, bme->value))
905  return GNUNET_SYSERR;
906  return 1;
907  }
908  off--;
909  }
910  }
911  }
912  GNUNET_break (0);
913  return GNUNET_SYSERR;
914 }
915 
916 
931  const struct GNUNET_CONTAINER_MultiUuidmap *map)
932 {
934 
936  iter->map = map;
938  iter->me = map->map[0];
939  return iter;
940 }
941 
942 
957 int
960  struct GNUNET_Uuid *key,
961  const void **value)
962 {
963  /* make sure the map has not been modified */
965 
966  /* look for the next entry, skipping empty buckets */
967  while (1)
968  {
969  if (iter->idx >= iter->map->map_length)
970  return GNUNET_NO;
971  if (GNUNET_YES == iter->map->use_small_entries)
972  {
973  if (NULL != iter->me.sme)
974  {
975  if (NULL != key)
976  *key = *iter->me.sme->key;
977  if (NULL != value)
978  *value = iter->me.sme->value;
979  iter->me.sme = iter->me.sme->next;
980  return GNUNET_YES;
981  }
982  }
983  else
984  {
985  if (NULL != iter->me.bme)
986  {
987  if (NULL != key)
988  *key = iter->me.bme->key;
989  if (NULL != value)
990  *value = iter->me.bme->value;
991  iter->me.bme = iter->me.bme->next;
992  return GNUNET_YES;
993  }
994  }
995  iter->idx += 1;
996  if (iter->idx < iter->map->map_length)
997  iter->me = iter->map->map[iter->idx];
998  }
999 }
1000 
1001 
1007 void
1010 {
1011  GNUNET_free (iter);
1012 }
1013 
1014 
1015 /* 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.
const struct GNUNET_HashCode * key
Key for the entry.
#define GNUNET_NO
Definition: gnunet_common.h:81
void * value
Value of the entry.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#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.
static int ret
Final status code.
Definition: gnunet-arm.c:89
#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.
#define GNUNET_memcpy(dst, src, n)
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:79
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:80
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.