2 This file is part of GNUnet.
3 Copyright (C) 2001-2015 GNUnet e.V.
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.
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.
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/>.
18 SPDX-License-Identifier: AGPL3.0-or-later
22 * @author Christian Grothoff
26 * Container classes for GNUnet
28 * @defgroup hashmap Container library: MultiHashMap
29 * Hash map with multiple values per key.
31 * @see [Documentation](https://gnunet.org/util_multihashmap)
33 * @defgroup heap Container library: Heap
34 * Min- or max-heap with arbitrary element removal
36 * @defgroup bloomfilter Container library: Bloom filter
37 * Probabilistic set tests
39 * @defgroup dll Container library: Doubly-linked list
41 * @see [Documentation](https://gnunet.org/mdll-api)
43 * @defgroup metadata Container library: Metadata
44 * GNU libextractor key-value pairs
47 #ifndef GNUNET_CONTAINER_LIB_H
48 #define GNUNET_CONTAINER_LIB_H
50 /* add error and config prototypes */
51 #include "gnunet_crypto_lib.h"
55 * Try to compress the given block of data using libz. Only returns
56 * the compressed block if compression worked and the new block is
57 * actually smaller. Decompress using #GNUNET_decompress().
59 * @param data block to compress; if compression
60 * resulted in a smaller block, the first
61 * bytes of data are updated to the compressed
63 * @param old_size number of bytes in data
64 * @param[out] result set to the compressed data, if compression worked
65 * @param[out] new_size set to size of result, if compression worked
66 * @return #GNUNET_YES if compression reduce the size,
67 * #GNUNET_NO if compression did not help
70 GNUNET_try_compression (const char *data,
77 * Decompress input, return the decompressed data as output. Dual to
78 * #GNUNET_try_compression(). Caller must set @a output_size to the
79 * number of bytes that were originally compressed.
81 * @param input compressed data
82 * @param input_size number of bytes in input
83 * @param output_size expected size of the output
84 * @return NULL on error, buffer of @a output_size decompressed bytes otherwise
87 GNUNET_decompress (const char *input, size_t input_size, size_t output_size);
92 #include <extractor.h>
96 /* definitions from extractor.h we need for the build */
99 * Enumeration defining various sources of keywords. See also
100 * http://dublincore.org/documents/1998/09/dces/
102 enum EXTRACTOR_MetaType
104 EXTRACTOR_METATYPE_RESERVED = 0,
105 EXTRACTOR_METATYPE_MIMETYPE = 1,
106 EXTRACTOR_METATYPE_FILENAME = 2,
107 EXTRACTOR_METATYPE_COMMENT = 3,
108 EXTRACTOR_METATYPE_TITLE = 4,
109 EXTRACTOR_METATYPE_BOOK_TITLE = 5,
110 EXTRACTOR_METATYPE_JOURNAL_NAME = 8,
111 EXTRACTOR_METATYPE_AUTHOR_NAME = 13,
112 EXTRACTOR_METATYPE_PUBLICATION_DATE = 24,
113 EXTRACTOR_METATYPE_URL = 29,
114 EXTRACTOR_METATYPE_URI = 30,
115 EXTRACTOR_METATYPE_ISRC = 31,
116 EXTRACTOR_METATYPE_UNKNOWN = 45,
117 EXTRACTOR_METATYPE_DESCRIPTION = 46,
118 EXTRACTOR_METATYPE_KEYWORDS = 49,
119 EXTRACTOR_METATYPE_SUBJECT = 52,
120 EXTRACTOR_METATYPE_PACKAGE_NAME = 69,
121 EXTRACTOR_METATYPE_THUMBNAIL = 114,
122 EXTRACTOR_METATYPE_ALBUM = 129,
123 EXTRACTOR_METATYPE_ARTIST = 130,
124 EXTRACTOR_METATYPE_ORIGINAL_TITLE = 162,
125 EXTRACTOR_METATYPE_GNUNET_FULL_DATA = 174,
126 EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME = 180,
131 * Format in which the extracted meta data is presented.
133 enum EXTRACTOR_MetaFormat
138 EXTRACTOR_METAFORMAT_UNKNOWN = 0,
141 * 0-terminated, UTF-8 encoded string. "data_len"
144 EXTRACTOR_METAFORMAT_UTF8 = 1,
147 * Some kind of binary format, see given Mime type.
149 EXTRACTOR_METAFORMAT_BINARY = 2,
152 * 0-terminated string. The specific encoding is unknown.
153 * "data_len" is strlen (data)+1.
155 EXTRACTOR_METAFORMAT_C_STRING = 3
160 * Type of a function that libextractor calls for each
161 * meta data item found.
163 * @param cls closure (user-defined)
164 * @param plugin_name name of the plugin that produced this value;
165 * special values can be used (i.e. '<zlib>' for zlib being
166 * used in the main libextractor library and yielding
168 * @param type libextractor-type describing the meta data
169 * @param format basic format information about @a data
170 * @param data_mime_type mime-type of @a data (not of the original file);
171 * can be NULL (if mime-type is not known)
172 * @param data actual meta-data found
173 * @param data_len number of bytes in @a data
174 * @return 0 to continue extracting, 1 to abort
176 typedef int (*EXTRACTOR_MetaDataProcessor) (void *cls,
177 const char *plugin_name,
178 enum EXTRACTOR_MetaType type,
179 enum EXTRACTOR_MetaFormat format,
180 const char *data_mime_type,
186 #ifndef EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME
187 /* hack for LE < 0.6.3 */
188 #define EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME 180
193 #if 0 /* keep Emacsens' auto-indent happy */
199 /* ******************* bloomfilter ***************** */
202 * @brief bloomfilter representation (opaque)
203 * @ingroup bloomfilter
205 struct GNUNET_CONTAINER_BloomFilter;
209 * @ingroup bloomfilter
210 * Iterator over `struct GNUNET_HashCode`.
213 * @param next set to the next hash code
214 * @return #GNUNET_YES if next was updated
215 * #GNUNET_NO if there are no more entries
217 typedef int (*GNUNET_CONTAINER_HashCodeIterator) (void *cls,
218 struct GNUNET_HashCode *next);
222 * @ingroup bloomfilter
223 * Load a Bloom filter from a file.
225 * @param filename the name of the file (or the prefix)
226 * @param size the size of the bloom-filter (number of
227 * bytes of storage space to use); will be rounded up
229 * @param k the number of #GNUNET_CRYPTO_hash-functions to apply per
230 * element (number of bits set per element in the set)
231 * @return the bloomfilter
233 struct GNUNET_CONTAINER_BloomFilter *
234 GNUNET_CONTAINER_bloomfilter_load (const char *filename,
240 * @ingroup bloomfilter
241 * Create a Bloom filter from raw bits.
243 * @param data the raw bits in memory (maybe NULL,
244 * in which case all bits should be considered
246 * @param size the size of the bloom-filter (number of
247 * bytes of storage space to use); also size of @a data
248 * -- unless data is NULL. Must be a power of 2.
249 * @param k the number of #GNUNET_CRYPTO_hash-functions to apply per
250 * element (number of bits set per element in the set)
251 * @return the bloomfilter
253 struct GNUNET_CONTAINER_BloomFilter *
254 GNUNET_CONTAINER_bloomfilter_init (const char *data,
260 * @ingroup bloomfilter
261 * Copy the raw data of this Bloom filter into
262 * the given data array.
264 * @param data where to write the data
265 * @param size the size of the given @a data array
266 * @return #GNUNET_SYSERR if the data array of the wrong size
269 GNUNET_CONTAINER_bloomfilter_get_raw_data (
270 const struct GNUNET_CONTAINER_BloomFilter *bf,
276 * @ingroup bloomfilter
277 * Test if an element is in the filter.
279 * @param e the element
280 * @param bf the filter
281 * @return #GNUNET_YES if the element is in the filter, #GNUNET_NO if not
284 GNUNET_CONTAINER_bloomfilter_test (
285 const struct GNUNET_CONTAINER_BloomFilter *bf,
286 const struct GNUNET_HashCode *e);
290 * @ingroup bloomfilter
291 * Add an element to the filter.
293 * @param bf the filter
294 * @param e the element
297 GNUNET_CONTAINER_bloomfilter_add (struct GNUNET_CONTAINER_BloomFilter *bf,
298 const struct GNUNET_HashCode *e);
302 * @ingroup bloomfilter
303 * Remove an element from the filter.
305 * @param bf the filter
306 * @param e the element to remove
309 GNUNET_CONTAINER_bloomfilter_remove (struct GNUNET_CONTAINER_BloomFilter *bf,
310 const struct GNUNET_HashCode *e);
314 * @ingroup bloomfilter
315 * Create a copy of a bloomfilter.
317 * @param bf the filter
320 struct GNUNET_CONTAINER_BloomFilter *
321 GNUNET_CONTAINER_bloomfilter_copy (
322 const struct GNUNET_CONTAINER_BloomFilter *bf);
326 * @ingroup bloomfilter
327 * Free the space associcated with a filter
328 * in memory, flush to drive if needed (do not
329 * free the space on the drive).
331 * @param bf the filter
334 GNUNET_CONTAINER_bloomfilter_free (struct GNUNET_CONTAINER_BloomFilter *bf);
338 * Get the number of the addresses set per element in the bloom filter.
340 * @param bf the filter
341 * @return addresses set per element in the bf
344 GNUNET_CONTAINER_bloomfilter_get_element_addresses (
345 const struct GNUNET_CONTAINER_BloomFilter *bf);
349 * @ingroup bloomfilter
350 * Get size of the bloom filter.
352 * @param bf the filter
353 * @return number of bytes used for the data of the bloom filter
356 GNUNET_CONTAINER_bloomfilter_get_size (
357 const struct GNUNET_CONTAINER_BloomFilter *bf);
361 * @ingroup bloomfilter
362 * Reset a Bloom filter to empty.
364 * @param bf the filter
367 GNUNET_CONTAINER_bloomfilter_clear (struct GNUNET_CONTAINER_BloomFilter *bf);
371 * @ingroup bloomfilter
372 * "or" the entries of the given raw data array with the
373 * data of the given Bloom filter. Assumes that
374 * the @a size of the @a data array and the current filter
377 * @param bf the filter
378 * @param data data to OR-in
379 * @param size size of @a data
380 * @return #GNUNET_OK on success
383 GNUNET_CONTAINER_bloomfilter_or (struct GNUNET_CONTAINER_BloomFilter *bf,
389 * @ingroup bloomfilter
390 * "or" the entries of the given raw data array with the
391 * data of the given Bloom filter. Assumes that
392 * the size of the two filters matches.
394 * @param bf the filter
395 * @param to_or the bloomfilter to or-in
396 * @return #GNUNET_OK on success
399 GNUNET_CONTAINER_bloomfilter_or2 (
400 struct GNUNET_CONTAINER_BloomFilter *bf,
401 const struct GNUNET_CONTAINER_BloomFilter *to_or);
405 * @ingroup bloomfilter
406 * Resize a bloom filter. Note that this operation
407 * is pretty costly. Essentially, the Bloom filter
408 * needs to be completely re-build.
410 * @param bf the filter
411 * @param iterator an iterator over all elements stored in the BF
412 * @param iterator_cls closure for @a iterator
413 * @param size the new size for the filter
414 * @param k the new number of #GNUNET_CRYPTO_hash-function to apply per element
417 GNUNET_CONTAINER_bloomfilter_resize (struct GNUNET_CONTAINER_BloomFilter *bf,
418 GNUNET_CONTAINER_HashCodeIterator iterator,
424 /* ****************** metadata ******************* */
428 * Meta data to associate with a file, directory or namespace.
430 struct GNUNET_CONTAINER_MetaData;
435 * Create a fresh meta data container.
437 * @return empty meta-data container
439 struct GNUNET_CONTAINER_MetaData *
440 GNUNET_CONTAINER_meta_data_create (void);
445 * Duplicate a MetaData token.
447 * @param md what to duplicate
448 * @return duplicate meta-data container
450 struct GNUNET_CONTAINER_MetaData *
451 GNUNET_CONTAINER_meta_data_duplicate (
452 const struct GNUNET_CONTAINER_MetaData *md);
459 * @param md what to free
462 GNUNET_CONTAINER_meta_data_destroy (struct GNUNET_CONTAINER_MetaData *md);
467 * Test if two MDs are equal. We consider them equal if
468 * the meta types, formats and content match (we do not
469 * include the mime types and plugins names in this
472 * @param md1 first value to check
473 * @param md2 other value to check
474 * @return #GNUNET_YES if they are equal
477 GNUNET_CONTAINER_meta_data_test_equal (
478 const struct GNUNET_CONTAINER_MetaData *md1,
479 const struct GNUNET_CONTAINER_MetaData *md2);
486 * @param md metadata to extend
487 * @param plugin_name name of the plugin that produced this value;
488 * special values can be used (i.e. '<zlib>' for zlib being
489 * used in the main libextractor library and yielding
491 * @param type libextractor-type describing the meta data
492 * @param format basic format information about data
493 * @param data_mime_type mime-type of data (not of the original file);
494 * can be NULL (if mime-type is not known)
495 * @param data actual meta-data found
496 * @param data_size number of bytes in data
497 * @return #GNUNET_OK on success, #GNUNET_SYSERR if this entry already exists
498 * data_mime_type and plugin_name are not considered for "exists" checks
501 GNUNET_CONTAINER_meta_data_insert (struct GNUNET_CONTAINER_MetaData *md,
502 const char *plugin_name,
503 enum EXTRACTOR_MetaType type,
504 enum EXTRACTOR_MetaFormat format,
505 const char *data_mime_type,
512 * Extend metadata. Merges the meta data from the second argument
513 * into the first, discarding duplicate key-value pairs.
515 * @param md metadata to extend
516 * @param in metadata to merge
519 GNUNET_CONTAINER_meta_data_merge (struct GNUNET_CONTAINER_MetaData *md,
520 const struct GNUNET_CONTAINER_MetaData *in);
527 * @param md metadata to manipulate
528 * @param type type of the item to remove
529 * @param data specific value to remove, NULL to remove all
530 * entries of the given type
531 * @param data_size number of bytes in data
532 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the item does not exist in md
535 GNUNET_CONTAINER_meta_data_delete (struct GNUNET_CONTAINER_MetaData *md,
536 enum EXTRACTOR_MetaType type,
543 * Remove all items in the container.
545 * @param md metadata to manipulate
548 GNUNET_CONTAINER_meta_data_clear (struct GNUNET_CONTAINER_MetaData *md);
553 * Add the current time as the publication date
556 * @param md metadata to modify
559 GNUNET_CONTAINER_meta_data_add_publication_date (
560 struct GNUNET_CONTAINER_MetaData *md);
565 * Iterate over MD entries.
567 * @param md metadata to inspect
568 * @param iter function to call on each entry, return 0 to continue to iterate
569 * and 1 to abort iteration in this function (GNU libextractor API!)
570 * @param iter_cls closure for @a iter
571 * @return number of entries
574 GNUNET_CONTAINER_meta_data_iterate (const struct GNUNET_CONTAINER_MetaData *md,
575 EXTRACTOR_MetaDataProcessor iter,
581 * Get the first MD entry of the given type. Caller
582 * is responsible for freeing the return value.
583 * Also, only meta data items that are strings (0-terminated)
584 * are returned by this function.
586 * @param md metadata to inspect
587 * @param type type to look for
588 * @return NULL if no entry was found
591 GNUNET_CONTAINER_meta_data_get_by_type (
592 const struct GNUNET_CONTAINER_MetaData *md,
593 enum EXTRACTOR_MetaType type);
598 * Get the first matching MD entry of the given types. Caller is
599 * responsible for freeing the return value. Also, only meta data
600 * items that are strings (0-terminated) are returned by this
603 * @param md metadata to inspect
604 * @param ... -1-terminated list of types
605 * @return NULL if we do not have any such entry,
606 * otherwise client is responsible for freeing the value!
609 GNUNET_CONTAINER_meta_data_get_first_by_types (
610 const struct GNUNET_CONTAINER_MetaData *md,
615 * Get a thumbnail from the meta-data (if present). Only matches meta
616 * data with mime type "image" and binary format.
618 * @param md metadata to inspect
619 * @param thumb will be set to the thumbnail data. Must be
620 * freed by the caller!
621 * @return number of bytes in thumbnail, 0 if not available
624 GNUNET_CONTAINER_meta_data_get_thumbnail (
625 const struct GNUNET_CONTAINER_MetaData *md,
626 unsigned char **thumb);
631 * Options for metadata serialization.
633 enum GNUNET_CONTAINER_MetaDataSerializationOptions
637 * Serialize all of the data.
639 GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL = 0,
643 * If not enough space is available, it is acceptable
644 * to only serialize some of the metadata.
646 GNUNET_CONTAINER_META_DATA_SERIALIZE_PART = 1,
650 * Speed is of the essence, do not allow compression.
652 GNUNET_CONTAINER_META_DATA_SERIALIZE_NO_COMPRESS = 2
658 * Serialize meta-data to target.
660 * @param md metadata to serialize
661 * @param target where to write the serialized metadata;
662 * *target can be NULL, in which case memory is allocated
663 * @param max maximum number of bytes available
664 * @param opt is it ok to just write SOME of the
665 * meta-data to match the size constraint,
666 * possibly discarding some data?
667 * @return number of bytes written on success,
668 * -1 on error (typically: not enough
672 GNUNET_CONTAINER_meta_data_serialize (
673 const struct GNUNET_CONTAINER_MetaData *md,
676 enum GNUNET_CONTAINER_MetaDataSerializationOptions opt);
681 * Get the size of the full meta-data in serialized form.
683 * @param md metadata to inspect
684 * @return number of bytes needed for serialization, -1 on error
687 GNUNET_CONTAINER_meta_data_get_serialized_size (
688 const struct GNUNET_CONTAINER_MetaData *md);
693 * Deserialize meta-data. Initializes md.
695 * @param input serialized meta-data.
696 * @param size number of bytes available
697 * @return MD on success, NULL on error (i.e.
700 struct GNUNET_CONTAINER_MetaData *
701 GNUNET_CONTAINER_meta_data_deserialize (const char *input, size_t size);
704 /* ******************************* HashMap **************************** */
708 * Opaque handle for a HashMap.
710 struct GNUNET_CONTAINER_MultiHashMap;
714 * Opaque handle to an iterator over
717 struct GNUNET_CONTAINER_MultiHashMapIterator;
721 * Options for storing values in the HashMap.
723 enum GNUNET_CONTAINER_MultiHashMapOption
728 * If a value with the given key exists, replace it. Note that the
729 * old value would NOT be freed by replace (the application has to
730 * make sure that this happens if required).
732 GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE,
736 * Allow multiple values with the same key.
738 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE,
742 * There must only be one value per key; storing a value should fail
743 * if a value under the same key already exists.
745 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY,
748 * @ingroup hashmap There must only be one value per key, but don't
749 * bother checking if a value already exists (faster than
750 * #GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY; implemented
751 * just like #GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE but this
752 * option documents better what is intended if
753 * #GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY is what is
756 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST
762 * Iterator over hash map entries.
765 * @param key current key code
766 * @param value value in the hash map
767 * @return #GNUNET_YES if we should continue to
771 typedef int (*GNUNET_CONTAINER_MulitHashMapIteratorCallback) (
773 const struct GNUNET_HashCode *key,
779 * Create a multi hash map.
781 * @param len initial size (map will grow as needed)
782 * @param do_not_copy_keys #GNUNET_NO is always safe and should be used by default;
783 * #GNUNET_YES means that on 'put', the 'key' does not have
784 * to be copied as the destination of the pointer is
785 * guaranteed to be life as long as the value is stored in
786 * the hashmap. This can significantly reduce memory
787 * consumption, but of course is also a recipie for
788 * heap corruption if the assumption is not true. Only
789 * use this if (1) memory use is important in this case and
790 * (2) you have triple-checked that the invariant holds
791 * @return NULL on error
793 struct GNUNET_CONTAINER_MultiHashMap *
794 GNUNET_CONTAINER_multihashmap_create (unsigned int len, int do_not_copy_keys);
799 * Destroy a hash map. Will not free any values
800 * stored in the hash map!
805 GNUNET_CONTAINER_multihashmap_destroy (
806 struct GNUNET_CONTAINER_MultiHashMap *map);
811 * Given a key find a value in the map matching the key.
814 * @param key what to look for
815 * @return NULL if no value was found; note that
816 * this is indistinguishable from values that just
817 * happen to be NULL; use "contains" to test for
818 * key-value pairs with value NULL
821 GNUNET_CONTAINER_multihashmap_get (
822 const struct GNUNET_CONTAINER_MultiHashMap *map,
823 const struct GNUNET_HashCode *key);
828 * Remove the given key-value pair from the map. Note that if the
829 * key-value pair is in the map multiple times, only one of the pairs
833 * @param key key of the key-value pair
834 * @param value value of the key-value pair
835 * @return #GNUNET_YES on success, #GNUNET_NO if the key-value pair
839 GNUNET_CONTAINER_multihashmap_remove (struct GNUNET_CONTAINER_MultiHashMap *map,
840 const struct GNUNET_HashCode *key,
845 * Remove all entries for the given key from the map.
846 * Note that the values would not be "freed".
849 * @param key identifies values to be removed
850 * @return number of values removed
853 GNUNET_CONTAINER_multihashmap_remove_all (
854 struct GNUNET_CONTAINER_MultiHashMap *map,
855 const struct GNUNET_HashCode *key);
860 * Remove all entries from the map.
861 * Note that the values would not be "freed".
864 * @return number of values removed
867 GNUNET_CONTAINER_multihashmap_clear (struct GNUNET_CONTAINER_MultiHashMap *map);
872 * Check if the map contains any value under the given
873 * key (including values that are NULL).
876 * @param key the key to test if a value exists for it
877 * @return #GNUNET_YES if such a value exists,
881 GNUNET_CONTAINER_multihashmap_contains (
882 const struct GNUNET_CONTAINER_MultiHashMap *map,
883 const struct GNUNET_HashCode *key);
888 * Check if the map contains the given value under the given
892 * @param key the key to test if a value exists for it
893 * @param value value to test for
894 * @return #GNUNET_YES if such a value exists,
898 GNUNET_CONTAINER_multihashmap_contains_value (
899 const struct GNUNET_CONTAINER_MultiHashMap *map,
900 const struct GNUNET_HashCode *key,
906 * Store a key-value pair in the map.
909 * @param key key to use
910 * @param value value to use
911 * @param opt options for put
912 * @return #GNUNET_OK on success,
913 * #GNUNET_NO if a value was replaced (with REPLACE)
914 * #GNUNET_SYSERR if #GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY was the option and the
915 * value already exists
918 GNUNET_CONTAINER_multihashmap_put (
919 struct GNUNET_CONTAINER_MultiHashMap *map,
920 const struct GNUNET_HashCode *key,
922 enum GNUNET_CONTAINER_MultiHashMapOption opt);
926 * Get the number of key-value pairs in the map.
929 * @return the number of key value pairs
932 GNUNET_CONTAINER_multihashmap_size (
933 const struct GNUNET_CONTAINER_MultiHashMap *map);
938 * Iterate over all entries in the map.
941 * @param it function to call on each entry
942 * @param it_cls extra argument to @a it
943 * @return the number of key value pairs processed,
944 * #GNUNET_SYSERR if it aborted iteration
947 GNUNET_CONTAINER_multihashmap_iterate (
948 struct GNUNET_CONTAINER_MultiHashMap *map,
949 GNUNET_CONTAINER_MulitHashMapIteratorCallback it,
955 * Create an iterator for a multihashmap.
956 * The iterator can be used to retrieve all the elements in the multihashmap
957 * one by one, without having to handle all elements at once (in contrast to
958 * #GNUNET_CONTAINER_multihashmap_iterate). Note that the iterator can not be
959 * used anymore if elements have been removed from 'map' after the creation of
960 * the iterator, or 'map' has been destroyed. Adding elements to 'map' may
961 * result in skipped or repeated elements.
963 * @param map the map to create an iterator for
964 * @return an iterator over the given multihashmap @a map
966 struct GNUNET_CONTAINER_MultiHashMapIterator *
967 GNUNET_CONTAINER_multihashmap_iterator_create (
968 const struct GNUNET_CONTAINER_MultiHashMap *map);
973 * Retrieve the next element from the hash map at the iterator's
974 * position. If there are no elements left, #GNUNET_NO is returned,
975 * and @a key and @a value are not modified. This operation is only
976 * allowed if no elements have been removed from the multihashmap
977 * since the creation of @a iter, and the map has not been destroyed.
978 * Adding elements may result in repeating or skipping elements.
980 * @param iter the iterator to get the next element from
981 * @param key pointer to store the key in, can be NULL
982 * @param value pointer to store the value in, can be NULL
983 * @return #GNUNET_YES we returned an element,
984 * #GNUNET_NO if we are out of elements
987 GNUNET_CONTAINER_multihashmap_iterator_next (
988 struct GNUNET_CONTAINER_MultiHashMapIterator *iter,
989 struct GNUNET_HashCode *key,
995 * Destroy a multihashmap iterator.
997 * @param iter the iterator to destroy
1000 GNUNET_CONTAINER_multihashmap_iterator_destroy (
1001 struct GNUNET_CONTAINER_MultiHashMapIterator *iter);
1006 * Iterate over all entries in the map that match a particular key.
1008 * @param map the map
1009 * @param key key that the entries must correspond to
1010 * @param it function to call on each entry
1011 * @param it_cls extra argument to @a it
1012 * @return the number of key value pairs processed,
1013 * #GNUNET_SYSERR if it aborted iteration
1016 GNUNET_CONTAINER_multihashmap_get_multiple (
1017 struct GNUNET_CONTAINER_MultiHashMap *map,
1018 const struct GNUNET_HashCode *key,
1019 GNUNET_CONTAINER_MulitHashMapIteratorCallback it,
1025 * Call @a it on a random value from the map, or not at all
1026 * if the map is empty. Note that this function has linear
1027 * complexity (in the size of the map).
1029 * @param map the map
1030 * @param it function to call on a random entry
1031 * @param it_cls extra argument to @a it
1032 * @return the number of key value pairs processed, zero or one.
1035 GNUNET_CONTAINER_multihashmap_get_random (
1036 const struct GNUNET_CONTAINER_MultiHashMap *map,
1037 GNUNET_CONTAINER_MulitHashMapIteratorCallback it,
1041 /* ***************** Version of Multihashmap for peer identities ****************** */
1045 * Iterator over hash map entries.
1047 * @param cls closure
1048 * @param key current public key
1049 * @param value value in the hash map
1050 * @return #GNUNET_YES if we should continue to
1052 * #GNUNET_NO if not.
1054 typedef int (*GNUNET_CONTAINER_PeerMapIterator) (
1056 const struct GNUNET_PeerIdentity *key,
1061 * Hash map from peer identities to values.
1063 struct GNUNET_CONTAINER_MultiPeerMap;
1068 * Create a multi peer map (hash map for public keys of peers).
1070 * @param len initial size (map will grow as needed)
1071 * @param do_not_copy_keys #GNUNET_NO is always safe and should be used by default;
1072 * #GNUNET_YES means that on 'put', the 'key' does not have
1073 * to be copied as the destination of the pointer is
1074 * guaranteed to be life as long as the value is stored in
1075 * the hashmap. This can significantly reduce memory
1076 * consumption, but of course is also a recipie for
1077 * heap corruption if the assumption is not true. Only
1078 * use this if (1) memory use is important in this case and
1079 * (2) you have triple-checked that the invariant holds
1080 * @return NULL on error
1082 struct GNUNET_CONTAINER_MultiPeerMap *
1083 GNUNET_CONTAINER_multipeermap_create (unsigned int len, int do_not_copy_keys);
1088 * Destroy a hash map. Will not free any values
1089 * stored in the hash map!
1091 * @param map the map
1094 GNUNET_CONTAINER_multipeermap_destroy (
1095 struct GNUNET_CONTAINER_MultiPeerMap *map);
1100 * Given a key find a value in the map matching the key.
1102 * @param map the map
1103 * @param key what to look for
1104 * @return NULL if no value was found; note that
1105 * this is indistinguishable from values that just
1106 * happen to be NULL; use "contains" to test for
1107 * key-value pairs with value NULL
1110 GNUNET_CONTAINER_multipeermap_get (
1111 const struct GNUNET_CONTAINER_MultiPeerMap *map,
1112 const struct GNUNET_PeerIdentity *key);
1117 * Remove the given key-value pair from the map. Note that if the
1118 * key-value pair is in the map multiple times, only one of the pairs
1121 * @param map the map
1122 * @param key key of the key-value pair
1123 * @param value value of the key-value pair
1124 * @return #GNUNET_YES on success, #GNUNET_NO if the key-value pair
1128 GNUNET_CONTAINER_multipeermap_remove (struct GNUNET_CONTAINER_MultiPeerMap *map,
1129 const struct GNUNET_PeerIdentity *key,
1134 * Remove all entries for the given key from the map.
1135 * Note that the values would not be "freed".
1137 * @param map the map
1138 * @param key identifies values to be removed
1139 * @return number of values removed
1142 GNUNET_CONTAINER_multipeermap_remove_all (
1143 struct GNUNET_CONTAINER_MultiPeerMap *map,
1144 const struct GNUNET_PeerIdentity *key);
1149 * Check if the map contains any value under the given
1150 * key (including values that are NULL).
1152 * @param map the map
1153 * @param key the key to test if a value exists for it
1154 * @return #GNUNET_YES if such a value exists,
1158 GNUNET_CONTAINER_multipeermap_contains (
1159 const struct GNUNET_CONTAINER_MultiPeerMap *map,
1160 const struct GNUNET_PeerIdentity *key);
1165 * Check if the map contains the given value under the given
1168 * @param map the map
1169 * @param key the key to test if a value exists for it
1170 * @param value value to test for
1171 * @return #GNUNET_YES if such a value exists,
1175 GNUNET_CONTAINER_multipeermap_contains_value (
1176 const struct GNUNET_CONTAINER_MultiPeerMap *map,
1177 const struct GNUNET_PeerIdentity *key,
1183 * Store a key-value pair in the map.
1185 * @param map the map
1186 * @param key key to use
1187 * @param value value to use
1188 * @param opt options for put
1189 * @return #GNUNET_OK on success,
1190 * #GNUNET_NO if a value was replaced (with REPLACE)
1191 * #GNUNET_SYSERR if #GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY was the option and the
1192 * value already exists
1195 GNUNET_CONTAINER_multipeermap_put (
1196 struct GNUNET_CONTAINER_MultiPeerMap *map,
1197 const struct GNUNET_PeerIdentity *key,
1199 enum GNUNET_CONTAINER_MultiHashMapOption opt);
1204 * Get the number of key-value pairs in the map.
1206 * @param map the map
1207 * @return the number of key value pairs
1210 GNUNET_CONTAINER_multipeermap_size (
1211 const struct GNUNET_CONTAINER_MultiPeerMap *map);
1216 * Iterate over all entries in the map.
1218 * @param map the map
1219 * @param it function to call on each entry
1220 * @param it_cls extra argument to @a it
1221 * @return the number of key value pairs processed,
1222 * #GNUNET_SYSERR if it aborted iteration
1225 GNUNET_CONTAINER_multipeermap_iterate (
1226 struct GNUNET_CONTAINER_MultiPeerMap *map,
1227 GNUNET_CONTAINER_PeerMapIterator it,
1231 struct GNUNET_CONTAINER_MultiPeerMapIterator;
1234 * Create an iterator for a multihashmap.
1235 * The iterator can be used to retrieve all the elements in the multihashmap
1236 * one by one, without having to handle all elements at once (in contrast to
1237 * #GNUNET_CONTAINER_multipeermap_iterate). Note that the iterator can not be
1238 * used anymore if elements have been removed from @a map after the creation of
1239 * the iterator, or 'map' has been destroyed. Adding elements to @a map may
1240 * result in skipped or repeated elements.
1242 * @param map the map to create an iterator for
1243 * @return an iterator over the given multihashmap @a map
1245 struct GNUNET_CONTAINER_MultiPeerMapIterator *
1246 GNUNET_CONTAINER_multipeermap_iterator_create (
1247 const struct GNUNET_CONTAINER_MultiPeerMap *map);
1252 * Retrieve the next element from the hash map at the iterator's
1253 * position. If there are no elements left, #GNUNET_NO is returned,
1254 * and @a key and @a value are not modified. This operation is only
1255 * allowed if no elements have been removed from the multihashmap
1256 * since the creation of @a iter, and the map has not been destroyed.
1257 * Adding elements may result in repeating or skipping elements.
1259 * @param iter the iterator to get the next element from
1260 * @param key pointer to store the key in, can be NULL
1261 * @param value pointer to store the value in, can be NULL
1262 * @return #GNUNET_YES we returned an element,
1263 * #GNUNET_NO if we are out of elements
1266 GNUNET_CONTAINER_multipeermap_iterator_next (
1267 struct GNUNET_CONTAINER_MultiPeerMapIterator *iter,
1268 struct GNUNET_PeerIdentity *key,
1269 const void **value);
1274 * Destroy a multipeermap iterator.
1276 * @param iter the iterator to destroy
1279 GNUNET_CONTAINER_multipeermap_iterator_destroy (
1280 struct GNUNET_CONTAINER_MultiPeerMapIterator *iter);
1285 * Iterate over all entries in the map that match a particular key.
1287 * @param map the map
1288 * @param key public key that the entries must correspond to
1289 * @param it function to call on each entry
1290 * @param it_cls extra argument to @a it
1291 * @return the number of key value pairs processed,
1292 * #GNUNET_SYSERR if it aborted iteration
1295 GNUNET_CONTAINER_multipeermap_get_multiple (
1296 struct GNUNET_CONTAINER_MultiPeerMap *map,
1297 const struct GNUNET_PeerIdentity *key,
1298 GNUNET_CONTAINER_PeerMapIterator it,
1304 * Call @a it on a random value from the map, or not at all
1305 * if the map is empty. Note that this function has linear
1306 * complexity (in the size of the map).
1308 * @param map the map
1309 * @param it function to call on a random entry
1310 * @param it_cls extra argument to @a it
1311 * @return the number of key value pairs processed, zero or one.
1314 GNUNET_CONTAINER_multipeermap_get_random (
1315 const struct GNUNET_CONTAINER_MultiPeerMap *map,
1316 GNUNET_CONTAINER_PeerMapIterator it,
1320 /* ***************** Version of Multihashmap for short hashes ****************** */
1324 * Iterator over hash map entries.
1326 * @param cls closure
1327 * @param key current public key
1328 * @param value value in the hash map
1329 * @return #GNUNET_YES if we should continue to
1331 * #GNUNET_NO if not.
1333 typedef int (*GNUNET_CONTAINER_ShortmapIterator) (
1335 const struct GNUNET_ShortHashCode *key,
1340 * Hash map from peer identities to values.
1342 struct GNUNET_CONTAINER_MultiShortmap;
1347 * Create a multi peer map (hash map for public keys of peers).
1349 * @param len initial size (map will grow as needed)
1350 * @param do_not_copy_keys #GNUNET_NO is always safe and should be used by default;
1351 * #GNUNET_YES means that on 'put', the 'key' does not have
1352 * to be copied as the destination of the pointer is
1353 * guaranteed to be life as long as the value is stored in
1354 * the hashmap. This can significantly reduce memory
1355 * consumption, but of course is also a recipie for
1356 * heap corruption if the assumption is not true. Only
1357 * use this if (1) memory use is important in this case and
1358 * (2) you have triple-checked that the invariant holds
1359 * @return NULL on error
1361 struct GNUNET_CONTAINER_MultiShortmap *
1362 GNUNET_CONTAINER_multishortmap_create (unsigned int len, int do_not_copy_keys);
1367 * Destroy a hash map. Will not free any values
1368 * stored in the hash map!
1370 * @param map the map
1373 GNUNET_CONTAINER_multishortmap_destroy (
1374 struct GNUNET_CONTAINER_MultiShortmap *map);
1379 * Given a key find a value in the map matching the key.
1381 * @param map the map
1382 * @param key what to look for
1383 * @return NULL if no value was found; note that
1384 * this is indistinguishable from values that just
1385 * happen to be NULL; use "contains" to test for
1386 * key-value pairs with value NULL
1389 GNUNET_CONTAINER_multishortmap_get (
1390 const struct GNUNET_CONTAINER_MultiShortmap *map,
1391 const struct GNUNET_ShortHashCode *key);
1396 * Remove the given key-value pair from the map. Note that if the
1397 * key-value pair is in the map multiple times, only one of the pairs
1400 * @param map the map
1401 * @param key key of the key-value pair
1402 * @param value value of the key-value pair
1403 * @return #GNUNET_YES on success, #GNUNET_NO if the key-value pair
1407 GNUNET_CONTAINER_multishortmap_remove (
1408 struct GNUNET_CONTAINER_MultiShortmap *map,
1409 const struct GNUNET_ShortHashCode *key,
1414 * Remove all entries for the given key from the map.
1415 * Note that the values would not be "freed".
1417 * @param map the map
1418 * @param key identifies values to be removed
1419 * @return number of values removed
1422 GNUNET_CONTAINER_multishortmap_remove_all (
1423 struct GNUNET_CONTAINER_MultiShortmap *map,
1424 const struct GNUNET_ShortHashCode *key);
1429 * Check if the map contains any value under the given
1430 * key (including values that are NULL).
1432 * @param map the map
1433 * @param key the key to test if a value exists for it
1434 * @return #GNUNET_YES if such a value exists,
1438 GNUNET_CONTAINER_multishortmap_contains (
1439 const struct GNUNET_CONTAINER_MultiShortmap *map,
1440 const struct GNUNET_ShortHashCode *key);
1445 * Check if the map contains the given value under the given
1448 * @param map the map
1449 * @param key the key to test if a value exists for it
1450 * @param value value to test for
1451 * @return #GNUNET_YES if such a value exists,
1455 GNUNET_CONTAINER_multishortmap_contains_value (
1456 const struct GNUNET_CONTAINER_MultiShortmap *map,
1457 const struct GNUNET_ShortHashCode *key,
1463 * Store a key-value pair in the map.
1465 * @param map the map
1466 * @param key key to use
1467 * @param value value to use
1468 * @param opt options for put
1469 * @return #GNUNET_OK on success,
1470 * #GNUNET_NO if a value was replaced (with REPLACE)
1471 * #GNUNET_SYSERR if #GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY was the option and the
1472 * value already exists
1475 GNUNET_CONTAINER_multishortmap_put (
1476 struct GNUNET_CONTAINER_MultiShortmap *map,
1477 const struct GNUNET_ShortHashCode *key,
1479 enum GNUNET_CONTAINER_MultiHashMapOption opt);
1484 * Get the number of key-value pairs in the map.
1486 * @param map the map
1487 * @return the number of key value pairs
1490 GNUNET_CONTAINER_multishortmap_size (
1491 const struct GNUNET_CONTAINER_MultiShortmap *map);
1496 * Iterate over all entries in the map.
1498 * @param map the map
1499 * @param it function to call on each entry
1500 * @param it_cls extra argument to @a it
1501 * @return the number of key value pairs processed,
1502 * #GNUNET_SYSERR if it aborted iteration
1505 GNUNET_CONTAINER_multishortmap_iterate (
1506 struct GNUNET_CONTAINER_MultiShortmap *map,
1507 GNUNET_CONTAINER_ShortmapIterator it,
1511 struct GNUNET_CONTAINER_MultiShortmapIterator;
1516 * Create an iterator for a multihashmap.
1517 * The iterator can be used to retrieve all the elements in the multihashmap
1518 * one by one, without having to handle all elements at once (in contrast to
1519 * #GNUNET_CONTAINER_multishortmap_iterate). Note that the iterator can not be
1520 * used anymore if elements have been removed from @a map after the creation of
1521 * the iterator, or 'map' has been destroyed. Adding elements to @a map may
1522 * result in skipped or repeated elements.
1524 * @param map the map to create an iterator for
1525 * @return an iterator over the given multihashmap @a map
1527 struct GNUNET_CONTAINER_MultiShortmapIterator *
1528 GNUNET_CONTAINER_multishortmap_iterator_create (
1529 const struct GNUNET_CONTAINER_MultiShortmap *map);
1534 * Retrieve the next element from the hash map at the iterator's
1535 * position. If there are no elements left, #GNUNET_NO is returned,
1536 * and @a key and @a value are not modified. This operation is only
1537 * allowed if no elements have been removed from the multihashmap
1538 * since the creation of @a iter, and the map has not been destroyed.
1539 * Adding elements may result in repeating or skipping elements.
1541 * @param iter the iterator to get the next element from
1542 * @param key pointer to store the key in, can be NULL
1543 * @param value pointer to store the value in, can be NULL
1544 * @return #GNUNET_YES we returned an element,
1545 * #GNUNET_NO if we are out of elements
1548 GNUNET_CONTAINER_multishortmap_iterator_next (
1549 struct GNUNET_CONTAINER_MultiShortmapIterator *iter,
1550 struct GNUNET_ShortHashCode *key,
1551 const void **value);
1556 * Destroy a multishortmap iterator.
1558 * @param iter the iterator to destroy
1561 GNUNET_CONTAINER_multishortmap_iterator_destroy (
1562 struct GNUNET_CONTAINER_MultiShortmapIterator *iter);
1567 * Iterate over all entries in the map that match a particular key.
1569 * @param map the map
1570 * @param key public key that the entries must correspond to
1571 * @param it function to call on each entry
1572 * @param it_cls extra argument to @a it
1573 * @return the number of key value pairs processed,
1574 * #GNUNET_SYSERR if it aborted iteration
1577 GNUNET_CONTAINER_multishortmap_get_multiple (
1578 struct GNUNET_CONTAINER_MultiShortmap *map,
1579 const struct GNUNET_ShortHashCode *key,
1580 GNUNET_CONTAINER_ShortmapIterator it,
1586 * Call @a it on a random value from the map, or not at all
1587 * if the map is empty. Note that this function has linear
1588 * complexity (in the size of the map).
1590 * @param map the map
1591 * @param it function to call on a random entry
1592 * @param it_cls extra argument to @a it
1593 * @return the number of key value pairs processed, zero or one.
1596 GNUNET_CONTAINER_multishortmap_get_random (
1597 const struct GNUNET_CONTAINER_MultiShortmap *map,
1598 GNUNET_CONTAINER_ShortmapIterator it,
1602 /* ***************** Version of Multihashmap for UUIDs ****************** */
1607 * Iterator over uuid map entries.
1609 * @param cls closure
1610 * @param key current public key
1611 * @param value value in the hash map
1612 * @return #GNUNET_YES if we should continue to
1614 * #GNUNET_NO if not.
1616 typedef int (*GNUNET_CONTAINER_MultiUuidmapIteratorCallback) (
1618 const struct GNUNET_Uuid *key,
1623 * Hash map from peer identities to values.
1625 struct GNUNET_CONTAINER_MultiUuidmap;
1630 * Create a multi peer map (hash map for public keys of peers).
1632 * @param len initial size (map will grow as needed)
1633 * @param do_not_copy_keys #GNUNET_NO is always safe and should be used by default;
1634 * #GNUNET_YES means that on 'put', the 'key' does not have
1635 * to be copied as the destination of the pointer is
1636 * guaranteed to be life as long as the value is stored in
1637 * the hashmap. This can significantly reduce memory
1638 * consumption, but of course is also a recipie for
1639 * heap corruption if the assumption is not true. Only
1640 * use this if (1) memory use is important in this case and
1641 * (2) you have triple-checked that the invariant holds
1642 * @return NULL on error
1644 struct GNUNET_CONTAINER_MultiUuidmap *
1645 GNUNET_CONTAINER_multiuuidmap_create (unsigned int len, int do_not_copy_keys);
1650 * Destroy a hash map. Will not free any values
1651 * stored in the hash map!
1653 * @param map the map
1656 GNUNET_CONTAINER_multiuuidmap_destroy (
1657 struct GNUNET_CONTAINER_MultiUuidmap *map);
1662 * Given a key find a value in the map matching the key.
1664 * @param map the map
1665 * @param key what to look for
1666 * @return NULL if no value was found; note that
1667 * this is indistinguishable from values that just
1668 * happen to be NULL; use "contains" to test for
1669 * key-value pairs with value NULL
1672 GNUNET_CONTAINER_multiuuidmap_get (
1673 const struct GNUNET_CONTAINER_MultiUuidmap *map,
1674 const struct GNUNET_Uuid *key);
1679 * Remove the given key-value pair from the map. Note that if the
1680 * key-value pair is in the map multiple times, only one of the pairs
1683 * @param map the map
1684 * @param key key of the key-value pair
1685 * @param value value of the key-value pair
1686 * @return #GNUNET_YES on success, #GNUNET_NO if the key-value pair
1690 GNUNET_CONTAINER_multiuuidmap_remove (struct GNUNET_CONTAINER_MultiUuidmap *map,
1691 const struct GNUNET_Uuid *key,
1696 * Remove all entries for the given key from the map.
1697 * Note that the values would not be "freed".
1699 * @param map the map
1700 * @param key identifies values to be removed
1701 * @return number of values removed
1704 GNUNET_CONTAINER_multiuuidmap_remove_all (
1705 struct GNUNET_CONTAINER_MultiUuidmap *map,
1706 const struct GNUNET_Uuid *key);
1711 * Check if the map contains any value under the given
1712 * key (including values that are NULL).
1714 * @param map the map
1715 * @param key the key to test if a value exists for it
1716 * @return #GNUNET_YES if such a value exists,
1720 GNUNET_CONTAINER_multiuuidmap_contains (
1721 const struct GNUNET_CONTAINER_MultiUuidmap *map,
1722 const struct GNUNET_Uuid *key);
1727 * Check if the map contains the given value under the given
1730 * @param map the map
1731 * @param key the key to test if a value exists for it
1732 * @param value value to test for
1733 * @return #GNUNET_YES if such a value exists,
1737 GNUNET_CONTAINER_multiuuidmap_contains_value (
1738 const struct GNUNET_CONTAINER_MultiUuidmap *map,
1739 const struct GNUNET_Uuid *key,
1745 * Store a key-value pair in the map.
1747 * @param map the map
1748 * @param key key to use
1749 * @param value value to use
1750 * @param opt options for put
1751 * @return #GNUNET_OK on success,
1752 * #GNUNET_NO if a value was replaced (with REPLACE)
1753 * #GNUNET_SYSERR if #GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY was the option and the
1754 * value already exists
1757 GNUNET_CONTAINER_multiuuidmap_put (
1758 struct GNUNET_CONTAINER_MultiUuidmap *map,
1759 const struct GNUNET_Uuid *key,
1761 enum GNUNET_CONTAINER_MultiHashMapOption opt);
1766 * Get the number of key-value pairs in the map.
1768 * @param map the map
1769 * @return the number of key value pairs
1772 GNUNET_CONTAINER_multiuuidmap_size (
1773 const struct GNUNET_CONTAINER_MultiUuidmap *map);
1778 * Iterate over all entries in the map.
1780 * @param map the map
1781 * @param it function to call on each entry
1782 * @param it_cls extra argument to @a it
1783 * @return the number of key value pairs processed,
1784 * #GNUNET_SYSERR if it aborted iteration
1787 GNUNET_CONTAINER_multiuuidmap_iterate (
1788 struct GNUNET_CONTAINER_MultiUuidmap *map,
1789 GNUNET_CONTAINER_MultiUuidmapIteratorCallback it,
1793 struct GNUNET_CONTAINER_MultiUuidmapIterator;
1798 * Create an iterator for a multihashmap.
1799 * The iterator can be used to retrieve all the elements in the multihashmap
1800 * one by one, without having to handle all elements at once (in contrast to
1801 * #GNUNET_CONTAINER_multiuuidmap_iterate). Note that the iterator can not be
1802 * used anymore if elements have been removed from @a map after the creation of
1803 * the iterator, or 'map' has been destroyed. Adding elements to @a map may
1804 * result in skipped or repeated elements.
1806 * @param map the map to create an iterator for
1807 * @return an iterator over the given multihashmap @a map
1809 struct GNUNET_CONTAINER_MultiUuidmapIterator *
1810 GNUNET_CONTAINER_multiuuidmap_iterator_create (
1811 const struct GNUNET_CONTAINER_MultiUuidmap *map);
1816 * Retrieve the next element from the hash map at the iterator's
1817 * position. If there are no elements left, #GNUNET_NO is returned,
1818 * and @a key and @a value are not modified. This operation is only
1819 * allowed if no elements have been removed from the multihashmap
1820 * since the creation of @a iter, and the map has not been destroyed.
1821 * Adding elements may result in repeating or skipping elements.
1823 * @param iter the iterator to get the next element from
1824 * @param key pointer to store the key in, can be NULL
1825 * @param value pointer to store the value in, can be NULL
1826 * @return #GNUNET_YES we returned an element,
1827 * #GNUNET_NO if we are out of elements
1830 GNUNET_CONTAINER_multiuuidmap_iterator_next (
1831 struct GNUNET_CONTAINER_MultiUuidmapIterator *iter,
1832 struct GNUNET_Uuid *key,
1833 const void **value);
1838 * Destroy a multiuuidmap iterator.
1840 * @param iter the iterator to destroy
1843 GNUNET_CONTAINER_multiuuidmap_iterator_destroy (
1844 struct GNUNET_CONTAINER_MultiUuidmapIterator *iter);
1849 * Iterate over all entries in the map that match a particular key.
1851 * @param map the map
1852 * @param key public key that the entries must correspond to
1853 * @param it function to call on each entry
1854 * @param it_cls extra argument to @a it
1855 * @return the number of key value pairs processed,
1856 * #GNUNET_SYSERR if it aborted iteration
1859 GNUNET_CONTAINER_multiuuidmap_get_multiple (
1860 struct GNUNET_CONTAINER_MultiUuidmap *map,
1861 const struct GNUNET_Uuid *key,
1862 GNUNET_CONTAINER_MultiUuidmapIteratorCallback it,
1868 * Call @a it on a random value from the map, or not at all
1869 * if the map is empty. Note that this function has linear
1870 * complexity (in the size of the map).
1872 * @param map the map
1873 * @param it function to call on a random entry
1874 * @param it_cls extra argument to @a it
1875 * @return the number of key value pairs processed, zero or one.
1878 GNUNET_CONTAINER_multiuuidmap_get_random (
1879 const struct GNUNET_CONTAINER_MultiUuidmap *map,
1880 GNUNET_CONTAINER_MultiUuidmapIteratorCallback it,
1884 /* Version of multihashmap with 32 bit keys */
1888 * Opaque handle for the 32-bit key HashMap.
1890 struct GNUNET_CONTAINER_MultiHashMap32;
1895 * Opaque handle to an iterator over
1896 * a 32-bit key multihashmap.
1898 struct GNUNET_CONTAINER_MultiHashMap32Iterator;
1903 * Iterator over hash map entries.
1905 * @param cls closure
1906 * @param key current key code
1907 * @param value value in the hash map
1908 * @return #GNUNET_YES if we should continue to
1910 * #GNUNET_NO if not.
1912 typedef int (*GNUNET_CONTAINER_MulitHashMapIterator32Callback) (void *cls,
1919 * Create a 32-bit key multi hash map.
1921 * @param len initial size (map will grow as needed)
1922 * @return NULL on error
1924 struct GNUNET_CONTAINER_MultiHashMap32 *
1925 GNUNET_CONTAINER_multihashmap32_create (unsigned int len);
1930 * Destroy a 32-bit key hash map. Will not free any values
1931 * stored in the hash map!
1933 * @param map the map
1936 GNUNET_CONTAINER_multihashmap32_destroy (
1937 struct GNUNET_CONTAINER_MultiHashMap32 *map);
1942 * Get the number of key-value pairs in the map.
1944 * @param map the map
1945 * @return the number of key value pairs
1948 GNUNET_CONTAINER_multihashmap32_size (
1949 const struct GNUNET_CONTAINER_MultiHashMap32 *map);
1954 * Given a key find a value in the map matching the key.
1956 * @param map the map
1957 * @param key what to look for
1958 * @return NULL if no value was found; note that
1959 * this is indistinguishable from values that just
1960 * happen to be NULL; use "contains" to test for
1961 * key-value pairs with value NULL
1964 GNUNET_CONTAINER_multihashmap32_get (
1965 const struct GNUNET_CONTAINER_MultiHashMap32 *map,
1971 * Iterate over all entries in the map.
1973 * @param map the map
1974 * @param it function to call on each entry
1975 * @param it_cls extra argument to @a it
1976 * @return the number of key value pairs processed,
1977 * #GNUNET_SYSERR if it aborted iteration
1980 GNUNET_CONTAINER_multihashmap32_iterate (
1981 struct GNUNET_CONTAINER_MultiHashMap32 *map,
1982 GNUNET_CONTAINER_MulitHashMapIterator32Callback it,
1988 * Remove the given key-value pair from the map. Note that if the
1989 * key-value pair is in the map multiple times, only one of the pairs
1992 * @param map the map
1993 * @param key key of the key-value pair
1994 * @param value value of the key-value pair
1995 * @return #GNUNET_YES on success, #GNUNET_NO if the key-value pair
1999 GNUNET_CONTAINER_multihashmap32_remove (
2000 struct GNUNET_CONTAINER_MultiHashMap32 *map,
2007 * Remove all entries for the given key from the map.
2008 * Note that the values would not be "freed".
2010 * @param map the map
2011 * @param key identifies values to be removed
2012 * @return number of values removed
2015 GNUNET_CONTAINER_multihashmap32_remove_all (
2016 struct GNUNET_CONTAINER_MultiHashMap32 *map,
2022 * Check if the map contains any value under the given
2023 * key (including values that are NULL).
2025 * @param map the map
2026 * @param key the key to test if a value exists for it
2027 * @return #GNUNET_YES if such a value exists,
2031 GNUNET_CONTAINER_multihashmap32_contains (
2032 const struct GNUNET_CONTAINER_MultiHashMap32 *map,
2038 * Check if the map contains the given value under the given
2041 * @param map the map
2042 * @param key the key to test if a value exists for it
2043 * @param value value to test for
2044 * @return #GNUNET_YES if such a value exists,
2048 GNUNET_CONTAINER_multihashmap32_contains_value (
2049 const struct GNUNET_CONTAINER_MultiHashMap32 *map,
2056 * Store a key-value pair in the map.
2058 * @param map the map
2059 * @param key key to use
2060 * @param value value to use
2061 * @param opt options for put
2062 * @return #GNUNET_OK on success,
2063 * #GNUNET_NO if a value was replaced (with REPLACE)
2064 * #GNUNET_SYSERR if #GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY was the option and the
2065 * value already exists
2068 GNUNET_CONTAINER_multihashmap32_put (
2069 struct GNUNET_CONTAINER_MultiHashMap32 *map,
2072 enum GNUNET_CONTAINER_MultiHashMapOption opt);
2077 * Iterate over all entries in the map that match a particular key.
2079 * @param map the map
2080 * @param key key that the entries must correspond to
2081 * @param it function to call on each entry
2082 * @param it_cls extra argument to @a it
2083 * @return the number of key value pairs processed,
2084 * #GNUNET_SYSERR if it aborted iteration
2087 GNUNET_CONTAINER_multihashmap32_get_multiple (
2088 struct GNUNET_CONTAINER_MultiHashMap32 *map,
2090 GNUNET_CONTAINER_MulitHashMapIterator32Callback it,
2095 * Create an iterator for a 32-bit multihashmap.
2096 * The iterator can be used to retrieve all the elements in the multihashmap
2097 * one by one, without having to handle all elements at once (in contrast to
2098 * #GNUNET_CONTAINER_multihashmap32_iterate). Note that the iterator can not be
2099 * used anymore if elements have been removed from 'map' after the creation of
2100 * the iterator, or 'map' has been destroyed. Adding elements to 'map' may
2101 * result in skipped or repeated elements.
2103 * @param map the map to create an iterator for
2104 * @return an iterator over the given multihashmap map
2106 struct GNUNET_CONTAINER_MultiHashMap32Iterator *
2107 GNUNET_CONTAINER_multihashmap32_iterator_create (
2108 const struct GNUNET_CONTAINER_MultiHashMap32 *map);
2112 * Retrieve the next element from the hash map at the iterator's position.
2113 * If there are no elements left, GNUNET_NO is returned, and 'key' and 'value'
2115 * This operation is only allowed if no elements have been removed from the
2116 * multihashmap since the creation of 'iter', and the map has not been destroyed.
2117 * Adding elements may result in repeating or skipping elements.
2119 * @param iter the iterator to get the next element from
2120 * @param key pointer to store the key in, can be NULL
2121 * @param value pointer to store the value in, can be NULL
2122 * @return #GNUNET_YES we returned an element,
2123 * #GNUNET_NO if we are out of elements
2126 GNUNET_CONTAINER_multihashmap32_iterator_next (
2127 struct GNUNET_CONTAINER_MultiHashMap32Iterator *iter,
2129 const void **value);
2133 * Destroy a 32-bit multihashmap iterator.
2135 * @param iter the iterator to destroy
2138 GNUNET_CONTAINER_multihashmap32_iterator_destroy (
2139 struct GNUNET_CONTAINER_MultiHashMapIterator *iter);
2142 /* ******************** doubly-linked list *************** */
2143 /* To avoid mistakes: head->prev == tail->next == NULL */
2147 * Insert an element at the head of a DLL. Assumes that head, tail and
2148 * element are structs with prev and next fields.
2150 * @param head pointer to the head of the DLL
2151 * @param tail pointer to the tail of the DLL
2152 * @param element element to insert
2154 #define GNUNET_CONTAINER_DLL_insert(head, tail, element) \
2157 GNUNET_assert (((element)->prev == NULL) && ((head) != (element))); \
2158 GNUNET_assert (((element)->next == NULL) && ((tail) != (element))); \
2159 (element)->next = (head); \
2160 (element)->prev = NULL; \
2161 if ((tail) == NULL) \
2164 (head)->prev = element; \
2165 (head) = (element); \
2171 * Insert an element at the tail of a DLL. Assumes that head, tail and
2172 * element are structs with prev and next fields.
2174 * @param head pointer to the head of the DLL
2175 * @param tail pointer to the tail of the DLL
2176 * @param element element to insert
2178 #define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element) \
2181 GNUNET_assert (((element)->prev == NULL) && ((head) != (element))); \
2182 GNUNET_assert (((element)->next == NULL) && ((tail) != (element))); \
2183 (element)->prev = (tail); \
2184 (element)->next = NULL; \
2185 if ((head) == NULL) \
2188 (tail)->next = element; \
2189 (tail) = (element); \
2195 * Insert an element into a DLL after the given other element. Insert
2196 * at the head if the other element is NULL.
2198 * @param head pointer to the head of the DLL
2199 * @param tail pointer to the tail of the DLL
2200 * @param other prior element, NULL for insertion at head of DLL
2201 * @param element element to insert
2203 #define GNUNET_CONTAINER_DLL_insert_after(head, tail, other, element) \
2206 GNUNET_assert (((element)->prev == NULL) && ((head) != (element))); \
2207 GNUNET_assert (((element)->next == NULL) && ((tail) != (element))); \
2208 (element)->prev = (other); \
2209 if (NULL == other) \
2211 (element)->next = (head); \
2212 (head) = (element); \
2216 (element)->next = (other)->next; \
2217 (other)->next = (element); \
2219 if (NULL == (element)->next) \
2220 (tail) = (element); \
2222 (element)->next->prev = (element); \
2228 * Insert an element into a DLL before the given other element. Insert
2229 * at the tail if the other element is NULL.
2231 * @param head pointer to the head of the DLL
2232 * @param tail pointer to the tail of the DLL
2233 * @param other prior element, NULL for insertion at head of DLL
2234 * @param element element to insert
2236 #define GNUNET_CONTAINER_DLL_insert_before(head, tail, other, element) \
2239 GNUNET_assert (((element)->prev == NULL) && ((head) != (element))); \
2240 GNUNET_assert (((element)->next == NULL) && ((tail) != (element))); \
2241 (element)->next = (other); \
2242 if (NULL == other) \
2244 (element)->prev = (tail); \
2245 (tail) = (element); \
2249 (element)->prev = (other)->prev; \
2250 (other)->prev = (element); \
2252 if (NULL == (element)->prev) \
2253 (head) = (element); \
2255 (element)->prev->next = (element); \
2261 * Remove an element from a DLL. Assumes that head, tail and
2262 * element point to structs with prev and next fields.
2264 * Using the head or tail pointer as the element
2265 * argument does NOT work with this macro.
2266 * Make sure to store head/tail in another pointer
2267 * and use it to remove the head or tail of the list.
2269 * @param head pointer to the head of the DLL
2270 * @param tail pointer to the tail of the DLL
2271 * @param element element to remove
2273 #define GNUNET_CONTAINER_DLL_remove(head, tail, element) \
2276 GNUNET_assert (((element)->prev != NULL) || ((head) == (element))); \
2277 GNUNET_assert (((element)->next != NULL) || ((tail) == (element))); \
2278 if ((element)->prev == NULL) \
2279 (head) = (element)->next; \
2281 (element)->prev->next = (element)->next; \
2282 if ((element)->next == NULL) \
2283 (tail) = (element)->prev; \
2285 (element)->next->prev = (element)->prev; \
2286 (element)->next = NULL; \
2287 (element)->prev = NULL; \
2291 /* ************ Multi-DLL interface, allows DLL elements to be
2292 in multiple lists at the same time *********************** */
2296 * Insert an element at the head of a MDLL. Assumes that head, tail and
2297 * element are structs with prev and next fields.
2299 * @param mdll suffix name for the next and prev pointers in the element
2300 * @param head pointer to the head of the MDLL
2301 * @param tail pointer to the tail of the MDLL
2302 * @param element element to insert
2304 #define GNUNET_CONTAINER_MDLL_insert(mdll, head, tail, element) \
2307 GNUNET_assert (((element)->prev_##mdll == NULL) && ((head) != (element))); \
2308 GNUNET_assert (((element)->next_##mdll == NULL) && ((tail) != (element))); \
2309 (element)->next_##mdll = (head); \
2310 (element)->prev_##mdll = NULL; \
2311 if ((tail) == NULL) \
2314 (head)->prev_##mdll = element; \
2315 (head) = (element); \
2321 * Insert an element at the tail of a MDLL. Assumes that head, tail and
2322 * element are structs with prev and next fields.
2324 * @param mdll suffix name for the next and prev pointers in the element
2325 * @param head pointer to the head of the MDLL
2326 * @param tail pointer to the tail of the MDLL
2327 * @param element element to insert
2329 #define GNUNET_CONTAINER_MDLL_insert_tail(mdll, head, tail, element) \
2332 GNUNET_assert (((element)->prev_##mdll == NULL) && ((head) != (element))); \
2333 GNUNET_assert (((element)->next_##mdll == NULL) && ((tail) != (element))); \
2334 (element)->prev_##mdll = (tail); \
2335 (element)->next_##mdll = NULL; \
2336 if ((head) == NULL) \
2339 (tail)->next_##mdll = element; \
2340 (tail) = (element); \
2346 * Insert an element into a MDLL after the given other element. Insert
2347 * at the head if the other element is NULL.
2349 * @param mdll suffix name for the next and prev pointers in the element
2350 * @param head pointer to the head of the MDLL
2351 * @param tail pointer to the tail of the MDLL
2352 * @param other prior element, NULL for insertion at head of MDLL
2353 * @param element element to insert
2355 #define GNUNET_CONTAINER_MDLL_insert_after(mdll, head, tail, other, element) \
2358 GNUNET_assert (((element)->prev_##mdll == NULL) && ((head) != (element))); \
2359 GNUNET_assert (((element)->next_##mdll == NULL) && ((tail) != (element))); \
2360 (element)->prev_##mdll = (other); \
2361 if (NULL == other) \
2363 (element)->next_##mdll = (head); \
2364 (head) = (element); \
2368 (element)->next_##mdll = (other)->next_##mdll; \
2369 (other)->next_##mdll = (element); \
2371 if (NULL == (element)->next_##mdll) \
2372 (tail) = (element); \
2374 (element)->next_##mdll->prev_##mdll = (element); \
2380 * Insert an element into a MDLL before the given other element. Insert
2381 * at the tail if the other element is NULL.
2383 * @param mdll suffix name for the next and prev pointers in the element
2384 * @param head pointer to the head of the MDLL
2385 * @param tail pointer to the tail of the MDLL
2386 * @param other prior element, NULL for insertion at head of MDLL
2387 * @param element element to insert
2389 #define GNUNET_CONTAINER_MDLL_insert_before(mdll, head, tail, other, element) \
2392 GNUNET_assert (((element)->prev_##mdll == NULL) && ((head) != (element))); \
2393 GNUNET_assert (((element)->next_##mdll == NULL) && ((tail) != (element))); \
2394 (element)->next_##mdll = (other); \
2395 if (NULL == other) \
2397 (element)->prev = (tail); \
2398 (tail) = (element); \
2402 (element)->prev_##mdll = (other)->prev_##mdll; \
2403 (other)->prev_##mdll = (element); \
2405 if (NULL == (element)->prev_##mdll) \
2406 (head) = (element); \
2408 (element)->prev_##mdll->next_##mdll = (element); \
2414 * Remove an element from a MDLL. Assumes
2415 * that head, tail and element are structs
2416 * with prev and next fields.
2418 * @param mdll suffix name for the next and prev pointers in the element
2419 * @param head pointer to the head of the MDLL
2420 * @param tail pointer to the tail of the MDLL
2421 * @param element element to remove
2423 #define GNUNET_CONTAINER_MDLL_remove(mdll, head, tail, element) \
2426 GNUNET_assert (((element)->prev_##mdll != NULL) || ((head) == (element))); \
2427 GNUNET_assert (((element)->next_##mdll != NULL) || ((tail) == (element))); \
2428 if ((element)->prev_##mdll == NULL) \
2429 (head) = (element)->next_##mdll; \
2431 (element)->prev_##mdll->next_##mdll = (element)->next_##mdll; \
2432 if ((element)->next_##mdll == NULL) \
2433 (tail) = (element)->prev_##mdll; \
2435 (element)->next_##mdll->prev_##mdll = (element)->prev_##mdll; \
2436 (element)->next_##mdll = NULL; \
2437 (element)->prev_##mdll = NULL; \
2442 * Insertion sort of @a element into DLL from @a head to @a tail
2443 * sorted by @a comparator.
2445 * @param TYPE element type of the elements, i.e. `struct ListElement`
2446 * @param comparator function like memcmp() to compare elements; takes
2447 * three arguments, the @a comparator_cls and two elements,
2448 * returns an `int` (-1, 0 or 1)
2449 * @param comparator_cls closure for @a comparator
2450 * @param[in,out] head head of DLL
2451 * @param[in,out] tail tail of DLL
2452 * @param element element to insert
2454 #define GNUNET_CONTAINER_DLL_insert_sorted(TYPE, \
2462 if ((NULL == head) || (0 < comparator (comparator_cls, element, head))) \
2464 /* insert at head, element < head */ \
2465 GNUNET_CONTAINER_DLL_insert (head, tail, element); \
2471 for (pos = head; NULL != pos; pos = pos->next) \
2472 if (0 < comparator (comparator_cls, element, pos)) \
2473 break; /* element < pos */ \
2474 if (NULL == pos) /* => element > tail */ \
2476 GNUNET_CONTAINER_DLL_insert_tail (head, tail, element); \
2478 else /* prev < element < pos */ \
2480 GNUNET_CONTAINER_DLL_insert_after (head, tail, pos->prev, element); \
2486 /* ******************** Heap *************** */
2491 * Cost by which elements in a heap can be ordered.
2493 typedef uint64_t GNUNET_CONTAINER_HeapCostType;
2498 * Heap type, either max or min.
2500 enum GNUNET_CONTAINER_HeapOrder
2504 * Heap with the maximum cost at the root.
2506 GNUNET_CONTAINER_HEAP_ORDER_MAX,
2510 * Heap with the minimum cost at the root.
2512 GNUNET_CONTAINER_HEAP_ORDER_MIN
2520 struct GNUNET_CONTAINER_Heap;
2525 * Handle to a node in a heap.
2527 struct GNUNET_CONTAINER_HeapNode;
2532 * Create a new heap.
2534 * @param order how should the heap be sorted?
2535 * @return handle to the heap
2537 struct GNUNET_CONTAINER_Heap *
2538 GNUNET_CONTAINER_heap_create (enum GNUNET_CONTAINER_HeapOrder order);
2543 * Destroys the heap. Only call on a heap that
2546 * @param heap heap to destroy
2549 GNUNET_CONTAINER_heap_destroy (struct GNUNET_CONTAINER_Heap *heap);
2554 * Get element stored at the root of @a heap.
2556 * @param heap Heap to inspect.
2557 * @return Element at the root, or NULL if heap is empty.
2560 GNUNET_CONTAINER_heap_peek (const struct GNUNET_CONTAINER_Heap *heap);
2564 * Get @a element and @a cost stored at the root of @a heap.
2566 * @param[in] heap Heap to inspect.
2567 * @param[out] element Root element is returned here.
2568 * @param[out] cost Cost of @a element is returned here.
2569 * @return #GNUNET_YES if an element is returned,
2570 * #GNUNET_NO if the heap is empty.
2573 GNUNET_CONTAINER_heap_peek2 (const struct GNUNET_CONTAINER_Heap *heap,
2575 GNUNET_CONTAINER_HeapCostType *cost);
2580 * Get the current size of the heap
2582 * @param heap the heap to get the size of
2583 * @return number of elements stored
2586 GNUNET_CONTAINER_heap_get_size (const struct GNUNET_CONTAINER_Heap *heap);
2591 * Get the current cost of the node
2593 * @param node the node to get the cost of
2594 * @return cost of the node
2596 GNUNET_CONTAINER_HeapCostType
2597 GNUNET_CONTAINER_heap_node_get_cost (
2598 const struct GNUNET_CONTAINER_HeapNode *node);
2605 * @param cls closure
2606 * @param node internal node of the heap
2607 * @param element value stored at the node
2608 * @param cost cost associated with the node
2609 * @return #GNUNET_YES if we should continue to iterate,
2610 * #GNUNET_NO if not.
2612 typedef int (*GNUNET_CONTAINER_HeapIterator) (
2614 struct GNUNET_CONTAINER_HeapNode *node,
2616 GNUNET_CONTAINER_HeapCostType cost);
2621 * Iterate over all entries in the heap.
2623 * @param heap the heap
2624 * @param iterator function to call on each entry
2625 * @param iterator_cls closure for @a iterator
2628 GNUNET_CONTAINER_heap_iterate (const struct GNUNET_CONTAINER_Heap *heap,
2629 GNUNET_CONTAINER_HeapIterator iterator,
2630 void *iterator_cls);
2634 * Perform a random walk of the tree. The walk is biased
2635 * towards elements closer to the root of the tree (since
2636 * each walk starts at the root and ends at a random leaf).
2637 * The heap internally tracks the current position of the
2640 * @param heap heap to walk
2641 * @return data stored at the next random node in the walk;
2642 * NULL if the tree is empty.
2645 GNUNET_CONTAINER_heap_walk_get_next (struct GNUNET_CONTAINER_Heap *heap);
2650 * Inserts a new element into the heap.
2652 * @param heap heap to modify
2653 * @param element element to insert
2654 * @param cost cost for the element
2655 * @return node for the new element
2657 struct GNUNET_CONTAINER_HeapNode *
2658 GNUNET_CONTAINER_heap_insert (struct GNUNET_CONTAINER_Heap *heap,
2660 GNUNET_CONTAINER_HeapCostType cost);
2665 * Remove root of the heap.
2667 * @param heap heap to modify
2668 * @return element data stored at the root node
2671 GNUNET_CONTAINER_heap_remove_root (struct GNUNET_CONTAINER_Heap *heap);
2676 * Removes a node from the heap.
2678 * @param node node to remove
2679 * @return element data stored at the node, NULL if heap is empty
2682 GNUNET_CONTAINER_heap_remove_node (struct GNUNET_CONTAINER_HeapNode *node);
2687 * Updates the cost of any node in the tree
2689 * @param node node for which the cost is to be changed
2690 * @param new_cost new cost for the node
2693 GNUNET_CONTAINER_heap_update_cost (struct GNUNET_CONTAINER_HeapNode *node,
2694 GNUNET_CONTAINER_HeapCostType new_cost);
2697 #if 0 /* keep Emacsens' auto-indent happy */
2705 /* ifndef GNUNET_CONTAINER_LIB_H */
2707 /* end of gnunet_container_lib.h */