diff options
author | Florian Dold <florian.dold@gmail.com> | 2013-11-05 00:08:13 +0000 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2013-11-05 00:08:13 +0000 |
commit | ca2c7bdfa64a30c0013598f0718dcfe7e6d98b2a (patch) | |
tree | 3bedd0e18f88371c2e75bd1953e0bc321629c828 /src/util/container_multihashmap32.c | |
parent | 6c3bf6b3486fd31402ab991f5ddef76bf9cd93c4 (diff) | |
download | gnunet-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.c | 121 |
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 | */ | ||
89 | struct 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 | */ | ||
548 | struct GNUNET_CONTAINER_MultiHashMap32Iterator * | ||
549 | GNUNET_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 | */ | ||
575 | int | ||
576 | GNUNET_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 | */ | ||
609 | void | ||
610 | GNUNET_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 */ |