GNUnet  0.19.4
container_multishortmap.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  */
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 
30 #define LOG(kind, ...) \
31  GNUNET_log_from (kind, "util-container-multishortmap", __VA_ARGS__)
32 
39 #define NEXT_CACHE_SIZE 16
40 
41 
45 struct BigMapEntry
46 {
50  void *value;
51 
55  struct BigMapEntry *next;
56 
61 };
62 
63 
67 struct SmallMapEntry
68 {
72  void *value;
73 
77  struct SmallMapEntry *next;
78 
82  const struct GNUNET_ShortHashCode *key;
83 };
84 
85 
89 union MapEntry
90 {
94  struct SmallMapEntry *sme;
95 
99  struct BigMapEntry *bme;
100 };
101 
102 
107 {
111  union MapEntry *map;
112 
116  unsigned int size;
117 
121  unsigned int map_length;
122 
128 
133  unsigned int modification_counter;
134 
141 
146  unsigned int next_cache_off;
147 };
148 
149 
155 {
159  union MapEntry me;
160 
164  unsigned int idx;
165 
170  unsigned int modification_counter;
171 
176 };
177 
178 
195 GNUNET_CONTAINER_multishortmap_create (unsigned int len, int do_not_copy_keys)
196 {
198 
199  GNUNET_assert (len > 0);
201  map->map = GNUNET_malloc_large (len * sizeof(union MapEntry));
202  if (NULL == map->map)
203  {
204  GNUNET_free (map);
205  return NULL;
206  }
207  map->map_length = len;
208  map->use_small_entries = do_not_copy_keys;
209  return map;
210 }
211 
212 
213 void
216 {
218  for (unsigned int i = 0; i < map->map_length; i++)
219  {
220  union MapEntry me;
221 
222  me = map->map[i];
223  if (map->use_small_entries)
224  {
225  struct SmallMapEntry *sme;
226  struct SmallMapEntry *nxt;
227 
228  nxt = me.sme;
229  while (NULL != (sme = nxt))
230  {
231  nxt = sme->next;
232  GNUNET_free (sme);
233  }
234  me.sme = NULL;
235  }
236  else
237  {
238  struct BigMapEntry *bme;
239  struct BigMapEntry *nxt;
240 
241  nxt = me.bme;
242  while (NULL != (bme = nxt))
243  {
244  nxt = bme->next;
245  GNUNET_free (bme);
246  }
247  me.bme = NULL;
248  }
249  }
250  GNUNET_free (map->map);
251  GNUNET_free (map);
252 }
253 
254 
262 static unsigned int
264  const struct GNUNET_ShortHashCode *key)
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 }
272 
273 
274 unsigned int
276  const struct GNUNET_CONTAINER_MultiShortmap *map)
277 {
278  return map->size;
279 }
280 
281 
282 void *
284  const struct GNUNET_CONTAINER_MultiShortmap *map,
285  const struct GNUNET_ShortHashCode *key)
286 {
287  union MapEntry me;
288 
289  me = map->map[idx_of (map, key)];
290  if (map->use_small_entries)
291  {
292  for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
293  if (0 == GNUNET_memcmp (key, sme->key))
294  return sme->value;
295  }
296  else
297  {
298  for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
299  if (0 == GNUNET_memcmp (key, &bme->key))
300  return bme->value;
301  }
302  return NULL;
303 }
304 
305 
306 int
310  void *it_cls)
311 {
312  int count;
313  union MapEntry me;
314  union MapEntry *ce;
315  struct GNUNET_ShortHashCode kc;
316 
317  count = 0;
318  GNUNET_assert (NULL != map);
319  ce = &map->next_cache[map->next_cache_off];
321  for (unsigned int i = 0; i < map->map_length; i++)
322  {
323  me = map->map[i];
324  if (map->use_small_entries)
325  {
326  struct SmallMapEntry *sme;
327 
328  ce->sme = me.sme;
329  while (NULL != (sme = ce->sme))
330  {
331  ce->sme = sme->next;
332  if ((NULL != it) && (GNUNET_OK != it (it_cls, sme->key, sme->value)))
333  {
335  return GNUNET_SYSERR;
336  }
337  count++;
338  }
339  }
340  else
341  {
342  struct BigMapEntry *bme;
343 
344  ce->bme = me.bme;
345  while (NULL != (bme = ce->bme))
346  {
347  ce->bme = bme->next;
348  if (NULL != it)
349  {
350  kc = bme->key;
351  if (GNUNET_OK != it (it_cls, &kc, bme->value))
352  {
354  return GNUNET_SYSERR;
355  }
356  }
357  count++;
358  }
359  }
360  }
362  return count;
363 }
364 
365 
373 static void
375  const struct BigMapEntry *bme)
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 }
381 
382 
390 static void
392  const struct SmallMapEntry *sme)
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 }
398 
399 
400 int
403  const struct GNUNET_ShortHashCode *key,
404  const void *value)
405 {
406  union MapEntry me;
407  unsigned int i;
408 
410  i = idx_of (map, key);
411  me = map->map[i];
412  if (map->use_small_entries)
413  {
414  struct SmallMapEntry *p = NULL;
415 
416  for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
417  {
418  if ((0 == GNUNET_memcmp (key, sme->key)) && (value == sme->value))
419  {
420  if (NULL == p)
421  map->map[i].sme = sme->next;
422  else
423  p->next = sme->next;
424  update_next_cache_sme (map, sme);
425  GNUNET_free (sme);
426  map->size--;
427  return GNUNET_YES;
428  }
429  p = sme;
430  }
431  }
432  else
433  {
434  struct BigMapEntry *p = NULL;
435 
436  for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
437  {
438  if ((0 == GNUNET_memcmp (key, &bme->key)) && (value == bme->value))
439  {
440  if (NULL == p)
441  map->map[i].bme = bme->next;
442  else
443  p->next = bme->next;
444  update_next_cache_bme (map, bme);
445  GNUNET_free (bme);
446  map->size--;
447  return GNUNET_YES;
448  }
449  p = bme;
450  }
451  }
452  return GNUNET_NO;
453 }
454 
455 
456 int
459  const struct GNUNET_ShortHashCode *key)
460 {
461  union MapEntry me;
462  unsigned int i;
463  int ret;
464 
466 
467  ret = 0;
468  i = idx_of (map, key);
469  me = map->map[i];
470  if (map->use_small_entries)
471  {
472  struct SmallMapEntry *sme;
473  struct SmallMapEntry *p;
474 
475  p = NULL;
476  sme = me.sme;
477  while (NULL != sme)
478  {
479  if (0 == GNUNET_memcmp (key, sme->key))
480  {
481  if (NULL == p)
482  map->map[i].sme = sme->next;
483  else
484  p->next = sme->next;
485  update_next_cache_sme (map, sme);
486  GNUNET_free (sme);
487  map->size--;
488  if (NULL == p)
489  sme = map->map[i].sme;
490  else
491  sme = p->next;
492  ret++;
493  }
494  else
495  {
496  p = sme;
497  sme = sme->next;
498  }
499  }
500  }
501  else
502  {
503  struct BigMapEntry *bme;
504  struct BigMapEntry *p;
505 
506  p = NULL;
507  bme = me.bme;
508  while (NULL != bme)
509  {
510  if (0 == GNUNET_memcmp (key, &bme->key))
511  {
512  if (NULL == p)
513  map->map[i].bme = bme->next;
514  else
515  p->next = bme->next;
516  update_next_cache_bme (map, bme);
517  GNUNET_free (bme);
518  map->size--;
519  if (NULL == p)
520  bme = map->map[i].bme;
521  else
522  bme = p->next;
523  ret++;
524  }
525  else
526  {
527  p = bme;
528  bme = bme->next;
529  }
530  }
531  }
532  return ret;
533 }
534 
535 
536 int
538  const struct GNUNET_CONTAINER_MultiShortmap *map,
539  const struct GNUNET_ShortHashCode *key)
540 {
541  union MapEntry me;
542 
543  me = map->map[idx_of (map, key)];
544  if (map->use_small_entries)
545  {
546  for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
547  if (0 == GNUNET_memcmp (key, sme->key))
548  return GNUNET_YES;
549  }
550  else
551  {
552  for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
553  if (0 == GNUNET_memcmp (key, &bme->key))
554  return GNUNET_YES;
555  }
556  return GNUNET_NO;
557 }
558 
559 
560 int
562  const struct GNUNET_CONTAINER_MultiShortmap *map,
563  const struct GNUNET_ShortHashCode *key,
564  const void *value)
565 {
566  union MapEntry me;
567 
568  me = map->map[idx_of (map, key)];
569  if (map->use_small_entries)
570  {
571  for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
572  if ((0 == GNUNET_memcmp (key, sme->key)) && (sme->value == value))
573  return GNUNET_YES;
574  }
575  else
576  {
577  for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
578  if ((0 == GNUNET_memcmp (key, &bme->key)) && (bme->value == value))
579  return GNUNET_YES;
580  }
581  return GNUNET_NO;
582 }
583 
584 
590 static void
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  {
614  if (map->use_small_entries)
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 }
641 
642 
643 int
646  const struct GNUNET_ShortHashCode *key,
647  void *value,
649 {
650  union MapEntry me;
651  unsigned int i;
652 
653  i = idx_of (map, key);
656  {
657  me = map->map[i];
658  if (map->use_small_entries)
659  {
660  for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
661  if (0 == GNUNET_memcmp (key, sme->key))
662  {
664  return GNUNET_SYSERR;
665  sme->value = value;
666  return GNUNET_NO;
667  }
668  }
669  else
670  {
671  for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
672  if (0 == GNUNET_memcmp (key, &bme->key))
673  {
675  return GNUNET_SYSERR;
676  bme->value = value;
677  return GNUNET_NO;
678  }
679  }
680  }
681  if (map->size / 3 >= map->map_length / 4)
682  {
683  grow (map);
684  i = idx_of (map, key);
685  }
686  if (map->use_small_entries)
687  {
688  struct SmallMapEntry *sme;
689 
690  sme = GNUNET_new (struct SmallMapEntry);
691  sme->key = key;
692  sme->value = value;
693  sme->next = map->map[i].sme;
694  map->map[i].sme = sme;
695  }
696  else
697  {
698  struct BigMapEntry *bme;
699 
700  bme = GNUNET_new (struct BigMapEntry);
701  bme->key = *key;
702  bme->value = value;
703  bme->next = map->map[i].bme;
704  map->map[i].bme = bme;
705  }
706  map->size++;
707  return GNUNET_OK;
708 }
709 
710 
721 int
724  const struct GNUNET_ShortHashCode *key,
726  void *it_cls)
727 {
728  int count;
729  union MapEntry me;
730  union MapEntry *ce;
731 
732  ce = &map->next_cache[map->next_cache_off];
734  count = 0;
735  me = map->map[idx_of (map, key)];
736  if (map->use_small_entries)
737  {
738  struct SmallMapEntry *sme;
739 
740  ce->sme = me.sme;
741  while (NULL != (sme = ce->sme))
742  {
743  ce->sme = sme->next;
744  if (0 != GNUNET_memcmp (key, sme->key))
745  continue;
746  if ((NULL != it) && (GNUNET_OK != it (it_cls, key, sme->value)))
747  {
749  return GNUNET_SYSERR;
750  }
751  count++;
752  }
753  }
754  else
755  {
756  struct BigMapEntry *bme;
757 
758  ce->bme = me.bme;
759  while (NULL != (bme = ce->bme))
760  {
761  ce->bme = bme->next;
762  if (0 != GNUNET_memcmp (key, &bme->key))
763  continue;
764  if ((NULL != it) && (GNUNET_OK != it (it_cls, key, bme->value)))
765  {
767  return GNUNET_SYSERR;
768  }
769  count++;
770  }
771  }
773  return count;
774 }
775 
776 
788 unsigned int
790  const struct GNUNET_CONTAINER_MultiShortmap *map,
792  void *it_cls)
793 {
794  unsigned int off;
795  union MapEntry me;
796 
797  if (0 == map->size)
798  return 0;
799  if (NULL == it)
800  return 1;
802  for (unsigned int idx = 0; idx < map->map_length; idx++)
803  {
804  me = map->map[idx];
805  if (map->use_small_entries)
806  {
807  for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
808  {
809  if (0 == off)
810  {
811  if (GNUNET_OK != it (it_cls, sme->key, sme->value))
812  return GNUNET_SYSERR;
813  return 1;
814  }
815  off--;
816  }
817  }
818  else
819  {
820  for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
821  {
822  if (0 == off)
823  {
824  if (GNUNET_OK != it (it_cls, &bme->key, bme->value))
825  return GNUNET_SYSERR;
826  return 1;
827  }
828  off--;
829  }
830  }
831  }
832  GNUNET_break (0);
833  return GNUNET_SYSERR;
834 }
835 
836 
839  const struct GNUNET_CONTAINER_MultiShortmap *map)
840 {
842 
844  iter->map = map;
846  iter->me = map->map[0];
847  return iter;
848 }
849 
850 
851 int
854  struct GNUNET_ShortHashCode *key,
855  const void **value)
856 {
857  /* make sure the map has not been modified */
859 
860  /* look for the next entry, skipping empty buckets */
861  while (1)
862  {
863  if (iter->idx >= iter->map->map_length)
864  return GNUNET_NO;
865  if (GNUNET_YES == iter->map->use_small_entries)
866  {
867  if (NULL != iter->me.sme)
868  {
869  if (NULL != key)
870  *key = *iter->me.sme->key;
871  if (NULL != value)
872  *value = iter->me.sme->value;
873  iter->me.sme = iter->me.sme->next;
874  return GNUNET_YES;
875  }
876  }
877  else
878  {
879  if (NULL != iter->me.bme)
880  {
881  if (NULL != key)
882  *key = iter->me.bme->key;
883  if (NULL != value)
884  *value = iter->me.bme->value;
885  iter->me.bme = iter->me.bme->next;
886  return GNUNET_YES;
887  }
888  }
889  iter->idx += 1;
890  if (iter->idx < iter->map->map_length)
891  iter->me = iter->map->map[iter->idx];
892  }
893 }
894 
895 
896 void
899 {
900  GNUNET_free (iter);
901 }
902 
903 
904 /* end of container_multishortmap.c */
#define NEXT_CACHE_SIZE
Maximum recursion depth for callbacks of GNUNET_CONTAINER_multihashmap_get_multiple() themselves s ag...
static void grow(struct GNUNET_CONTAINER_MultiShortmap *map)
Grow the given map to a more appropriate size.
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 th...
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 th...
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.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static GNUNET_NETWORK_STRUCT_END struct GNUNET_PeerIdentity me
Our own peer identity.
static struct GNUNET_CONTAINER_MultiPeerMap * map
Handle to the map used to store old latency values for peers.
struct GNUNET_HashCode key
The key used in the DHT.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
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
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
@ GNUNET_CRYPTO_QUALITY_NONCE
Randomness for IVs etc.
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.
enum GNUNET_GenericReturnValue(* GNUNET_CONTAINER_ShortmapIterator)(void *cls, const struct GNUNET_ShortHashCode *key, void *value)
Iterator over hash map entries.
void GNUNET_CONTAINER_multishortmap_iterator_destroy(struct GNUNET_CONTAINER_MultiShortmapIterator *iter)
Destroy a multishortmap iterator.
int 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.
struct GNUNET_CONTAINER_MultiShortmapIterator * GNUNET_CONTAINER_multishortmap_iterator_create(const struct GNUNET_CONTAINER_MultiShortmap *map)
Create an iterator for a multihashmap.
int 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.
int GNUNET_CONTAINER_multishortmap_iterate(struct GNUNET_CONTAINER_MultiShortmap *map, GNUNET_CONTAINER_ShortmapIterator it, void *it_cls)
Iterate over all entries in the map.
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.
GNUNET_CONTAINER_MultiHashMapOption
Options for storing values in the HashMap.
struct GNUNET_CONTAINER_MultiShortmap * GNUNET_CONTAINER_multishortmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
void GNUNET_CONTAINER_multishortmap_destroy(struct GNUNET_CONTAINER_MultiShortmap *map)
Destroy a hash map.
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.
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.
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.
unsigned int GNUNET_CONTAINER_multishortmap_size(const struct GNUNET_CONTAINER_MultiShortmap *map)
Get the number of key-value pairs in the map.
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.
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).
@ 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...
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
#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.
An entry in the hash map with the full key.
struct BigMapEntry * next
If there is a hash collision, we create a linked list.
void * value
Value of the entry.
struct GNUNET_HashCode key
Key for the entry.
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.
int use_small_entries
GNUNET_NO if the map entries are of type 'struct BigMapEntry', GNUNET_YES if the map entries are of t...
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...
unsigned int idx
Current bucket index.
union 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_MultiShortmap * map
Map that we are iterating over.
Internal representation of the hash map.
int use_small_entries
GNUNET_NO if the map entries are of type 'struct BigMapEntry', GNUNET_YES if the map entries are of t...
unsigned int map_length
Length of the "map" array.
union MapEntry next_cache[16]
Map entries indicating iteration positions currently in use by GNUNET_CONTAINER_multihashmap_get_mult...
unsigned int size
Number of entries in the map.
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 next_cache_off
Offset of next_cache entries in use, must be smaller than NEXT_CACHE_SIZE.
A 256-bit hashcode.
An entry in the hash map with just a pointer to the key.
const struct GNUNET_ShortHashCode * key
Key for the entry.
struct SmallMapEntry * next
If there is a hash collision, we create a linked list.
void * value
Value of the entry.
const struct GNUNET_HashCode * key
Key for the entry.
Entry in the map.
struct SmallMapEntry * sme
Variant used if map entries only contain a pointer to the key.
struct BigMapEntry * bme
Variant used if map entries contain the full key.