From ca2c7bdfa64a30c0013598f0718dcfe7e6d98b2a Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Tue, 5 Nov 2013 00:08:13 +0000 Subject: - implemented missing set functionality - secretsharing api changes --- src/util/container_multihashmap32.c | 121 ++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) (limited to 'src/util/container_multihashmap32.c') 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 * Length of the "map" array. */ unsigned int map_length; + + /** + * Counts the destructive modifications (grow, remove) + * to the map, so that iterators can check if they are still valid. + */ + unsigned int modification_counter; +}; + + +/** + * Cursor into a multihashmap. + * Allows to enumerate elements asynchronously. + */ +struct GNUNET_CONTAINER_MultiHashMap32Iterator +{ + /** + * Position in the bucket 'idx' + */ + struct MapEntry *me; + + /** + * Current bucket index. + */ + unsigned int idx; + + /** + * Modification counter as observed on the map when the iterator + * was created. + */ + unsigned int modification_counter; + + /** + * Map that we are iterating over. + */ + const struct GNUNET_CONTAINER_MultiHashMap32 *map; }; @@ -239,6 +274,8 @@ GNUNET_CONTAINER_multihashmap32_remove (struct GNUNET_CONTAINER_MultiHashMap32 struct MapEntry *p; unsigned int i; + map->modification_counter++; + i = idx_of (map, key); p = NULL; e = map->map[i]; @@ -280,6 +317,8 @@ GNUNET_CONTAINER_multihashmap32_remove_all (struct unsigned int i; int ret; + map->modification_counter++; + ret = 0; i = idx_of (map, key); p = NULL; @@ -383,6 +422,8 @@ grow (struct GNUNET_CONTAINER_MultiHashMap32 *map) unsigned int idx; unsigned int i; + map->modification_counter++; + old_map = map->map; old_len = map->map_length; new_len = old_len * 2; @@ -492,4 +533,84 @@ GNUNET_CONTAINER_multihashmap32_get_multiple (const struct } +/** + * Create an iterator for a multihashmap. + * The iterator can be used to retrieve all the elements in the multihashmap + * one by one, without having to handle all elements at once (in contrast to + * GNUNET_CONTAINER_multihashmap_iterate()). Note that the iterator can not be + * used anymore if elements have been removed from 'map' after the creation of + * the iterator, or 'map' has been destroyed. Adding elements to 'map' may + * result in skipped or repeated elements. + * + * @param map the map to create an iterator for + * @return an iterator over the given multihashmap 'map' + */ +struct GNUNET_CONTAINER_MultiHashMap32Iterator * +GNUNET_CONTAINER_multihashmap32_iterator_create (const struct GNUNET_CONTAINER_MultiHashMap32 *map) +{ + struct GNUNET_CONTAINER_MultiHashMap32Iterator *iter; + + iter = GNUNET_new (struct GNUNET_CONTAINER_MultiHashMap32Iterator); + iter->map = map; + iter->modification_counter = map->modification_counter; + iter->me = map->map[0]; + return iter; +} + + +/** + * Retrieve the next element from the hash map at the iterator's position. + * If there are no elements left, GNUNET_NO is returned, and 'key' and 'value' + * are not modified. + * This operation is only allowed if no elements have been removed from the + * multihashmap since the creation of 'iter', and the map has not been destroyed. + * Adding elements may result in repeating or skipping elements. + * + * @param iter the iterator to get the next element from + * @param key pointer to store the key in, can be NULL + * @param value pointer to store the value in, can be NULL + * @return #GNUNET_YES we returned an element, + * #GNUNET_NO if we are out of elements + */ +int +GNUNET_CONTAINER_multihashmap32_iterator_next (struct GNUNET_CONTAINER_MultiHashMap32Iterator *iter, + uint32_t *key, + const void **value) +{ + /* make sure the map has not been modified */ + GNUNET_assert (iter->modification_counter == iter->map->modification_counter); + + /* look for the next entry, skipping empty buckets */ + while (1) + { + if (iter->idx >= iter->map->map_length) + return GNUNET_NO; + if (NULL != iter->me) + { + if (NULL != key) + *key = iter->me->key; + if (NULL != value) + *value = iter->me->value; + iter->me = iter->me->next; + return GNUNET_YES; + } + iter->idx += 1; + if (iter->idx < iter->map->map_length) + iter->me = iter->map->map[iter->idx]; + } +} + + +/** + * Destroy a multihashmap iterator. + * + * @param iter the iterator to destroy + */ +void +GNUNET_CONTAINER_multihashmap32_iterator_destroy (struct GNUNET_CONTAINER_MultiHashMapIterator *iter) +{ + GNUNET_free (iter); +} + + /* end of container_multihashmap.c */ -- cgit v1.2.3