aboutsummaryrefslogtreecommitdiff
path: root/src/util/container_multihashmap32.c
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2013-11-05 00:08:13 +0000
committerFlorian Dold <florian.dold@gmail.com>2013-11-05 00:08:13 +0000
commitca2c7bdfa64a30c0013598f0718dcfe7e6d98b2a (patch)
tree3bedd0e18f88371c2e75bd1953e0bc321629c828 /src/util/container_multihashmap32.c
parent6c3bf6b3486fd31402ab991f5ddef76bf9cd93c4 (diff)
downloadgnunet-ca2c7bdfa64a30c0013598f0718dcfe7e6d98b2a.tar.gz
gnunet-ca2c7bdfa64a30c0013598f0718dcfe7e6d98b2a.zip
- implemented missing set functionality
- secretsharing api changes
Diffstat (limited to 'src/util/container_multihashmap32.c')
-rw-r--r--src/util/container_multihashmap32.c121
1 files changed, 121 insertions, 0 deletions
diff --git a/src/util/container_multihashmap32.c b/src/util/container_multihashmap32.c
index afb0e3653..365333de2 100644
--- a/src/util/container_multihashmap32.c
+++ b/src/util/container_multihashmap32.c
@@ -73,6 +73,41 @@ struct GNUNET_CONTAINER_MultiHashMap32
73 * Length of the "map" array. 73 * Length of the "map" array.
74 */ 74 */
75 unsigned int map_length; 75 unsigned int map_length;
76
77 /**
78 * Counts the destructive modifications (grow, remove)
79 * to the map, so that iterators can check if they are still valid.
80 */
81 unsigned int modification_counter;
82};
83
84
85/**
86 * Cursor into a multihashmap.
87 * Allows to enumerate elements asynchronously.
88 */
89struct GNUNET_CONTAINER_MultiHashMap32Iterator
90{
91 /**
92 * Position in the bucket 'idx'
93 */
94 struct MapEntry *me;
95
96 /**
97 * Current bucket index.
98 */
99 unsigned int idx;
100
101 /**
102 * Modification counter as observed on the map when the iterator
103 * was created.
104 */
105 unsigned int modification_counter;
106
107 /**
108 * Map that we are iterating over.
109 */
110 const struct GNUNET_CONTAINER_MultiHashMap32 *map;
76}; 111};
77 112
78 113
@@ -239,6 +274,8 @@ GNUNET_CONTAINER_multihashmap32_remove (struct GNUNET_CONTAINER_MultiHashMap32
239 struct MapEntry *p; 274 struct MapEntry *p;
240 unsigned int i; 275 unsigned int i;
241 276
277 map->modification_counter++;
278
242 i = idx_of (map, key); 279 i = idx_of (map, key);
243 p = NULL; 280 p = NULL;
244 e = map->map[i]; 281 e = map->map[i];
@@ -280,6 +317,8 @@ GNUNET_CONTAINER_multihashmap32_remove_all (struct
280 unsigned int i; 317 unsigned int i;
281 int ret; 318 int ret;
282 319
320 map->modification_counter++;
321
283 ret = 0; 322 ret = 0;
284 i = idx_of (map, key); 323 i = idx_of (map, key);
285 p = NULL; 324 p = NULL;
@@ -383,6 +422,8 @@ grow (struct GNUNET_CONTAINER_MultiHashMap32 *map)
383 unsigned int idx; 422 unsigned int idx;
384 unsigned int i; 423 unsigned int i;
385 424
425 map->modification_counter++;
426
386 old_map = map->map; 427 old_map = map->map;
387 old_len = map->map_length; 428 old_len = map->map_length;
388 new_len = old_len * 2; 429 new_len = old_len * 2;
@@ -492,4 +533,84 @@ GNUNET_CONTAINER_multihashmap32_get_multiple (const struct
492} 533}
493 534
494 535
536/**
537 * Create an iterator for a multihashmap.
538 * The iterator can be used to retrieve all the elements in the multihashmap
539 * one by one, without having to handle all elements at once (in contrast to
540 * GNUNET_CONTAINER_multihashmap_iterate()). Note that the iterator can not be
541 * used anymore if elements have been removed from 'map' after the creation of
542 * the iterator, or 'map' has been destroyed. Adding elements to 'map' may
543 * result in skipped or repeated elements.
544 *
545 * @param map the map to create an iterator for
546 * @return an iterator over the given multihashmap 'map'
547 */
548struct GNUNET_CONTAINER_MultiHashMap32Iterator *
549GNUNET_CONTAINER_multihashmap32_iterator_create (const struct GNUNET_CONTAINER_MultiHashMap32 *map)
550{
551 struct GNUNET_CONTAINER_MultiHashMap32Iterator *iter;
552
553 iter = GNUNET_new (struct GNUNET_CONTAINER_MultiHashMap32Iterator);
554 iter->map = map;
555 iter->modification_counter = map->modification_counter;
556 iter->me = map->map[0];
557 return iter;
558}
559
560
561/**
562 * Retrieve the next element from the hash map at the iterator's position.
563 * If there are no elements left, GNUNET_NO is returned, and 'key' and 'value'
564 * are not modified.
565 * This operation is only allowed if no elements have been removed from the
566 * multihashmap since the creation of 'iter', and the map has not been destroyed.
567 * Adding elements may result in repeating or skipping elements.
568 *
569 * @param iter the iterator to get the next element from
570 * @param key pointer to store the key in, can be NULL
571 * @param value pointer to store the value in, can be NULL
572 * @return #GNUNET_YES we returned an element,
573 * #GNUNET_NO if we are out of elements
574 */
575int
576GNUNET_CONTAINER_multihashmap32_iterator_next (struct GNUNET_CONTAINER_MultiHashMap32Iterator *iter,
577 uint32_t *key,
578 const void **value)
579{
580 /* make sure the map has not been modified */
581 GNUNET_assert (iter->modification_counter == iter->map->modification_counter);
582
583 /* look for the next entry, skipping empty buckets */
584 while (1)
585 {
586 if (iter->idx >= iter->map->map_length)
587 return GNUNET_NO;
588 if (NULL != iter->me)
589 {
590 if (NULL != key)
591 *key = iter->me->key;
592 if (NULL != value)
593 *value = iter->me->value;
594 iter->me = iter->me->next;
595 return GNUNET_YES;
596 }
597 iter->idx += 1;
598 if (iter->idx < iter->map->map_length)
599 iter->me = iter->map->map[iter->idx];
600 }
601}
602
603
604/**
605 * Destroy a multihashmap iterator.
606 *
607 * @param iter the iterator to destroy
608 */
609void
610GNUNET_CONTAINER_multihashmap32_iterator_destroy (struct GNUNET_CONTAINER_MultiHashMapIterator *iter)
611{
612 GNUNET_free (iter);
613}
614
615
495/* end of container_multihashmap.c */ 616/* end of container_multihashmap.c */