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 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.
17 * @author Christian Grothoff
21 * Container classes for GNUnet
23 * @defgroup hashmap Container library: MultiHashMap
24 * Hash map with multiple values per key.
26 * @see [Documentation](https://gnunet.org/util_multihashmap)
28 * @defgroup heap Container library: Heap
29 * Min- or max-heap with arbitrary element removal
31 * @defgroup bloomfilter Container library: Bloom filter
32 * Probabilistic set tests
34 * @defgroup dll Container library: Doubly-linked list
36 * @see [Documentation](https://gnunet.org/mdll-api)
38 * @defgroup metadata Container library: Metadata
39 * GNU libextractor key-value pairs
42 #ifndef GNUNET_CONTAINER_LIB_H
43 #define GNUNET_CONTAINER_LIB_H
45 /* add error and config prototypes */
46 #include "gnunet_crypto_lib.h"
50 * Try to compress the given block of data using libz. Only returns
51 * the compressed block if compression worked and the new block is
52 * actually smaller. Decompress using #GNUNET_decompress().
54 * @param data block to compress; if compression
55 * resulted in a smaller block, the first
56 * bytes of data are updated to the compressed
58 * @param old_size number of bytes in data
59 * @param[out] result set to the compressed data, if compression worked
60 * @param[out] new_size set to size of result, if compression worked
61 * @return #GNUNET_YES if compression reduce the size,
62 * #GNUNET_NO if compression did not help
65 GNUNET_try_compression (const char *data,
72 * Decompress input, return the decompressed data as output. Dual to
73 * #GNUNET_try_compression(). Caller must set @a output_size to the
74 * number of bytes that were originally compressed.
76 * @param input compressed data
77 * @param input_size number of bytes in input
78 * @param output_size expected size of the output
79 * @return NULL on error, buffer of @a output_size decompressed bytes otherwise
82 GNUNET_decompress (const char *input,
89 #include <extractor.h>
93 /* definitions from extractor.h we need for the build */
96 * Enumeration defining various sources of keywords. See also
97 * http://dublincore.org/documents/1998/09/dces/
99 enum EXTRACTOR_MetaType {
100 EXTRACTOR_METATYPE_RESERVED = 0,
101 EXTRACTOR_METATYPE_MIMETYPE = 1,
102 EXTRACTOR_METATYPE_FILENAME = 2,
103 EXTRACTOR_METATYPE_COMMENT = 3,
104 EXTRACTOR_METATYPE_TITLE = 4,
105 EXTRACTOR_METATYPE_BOOK_TITLE = 5,
106 EXTRACTOR_METATYPE_JOURNAL_NAME = 8,
107 EXTRACTOR_METATYPE_AUTHOR_NAME = 13,
108 EXTRACTOR_METATYPE_PUBLICATION_DATE = 24,
109 EXTRACTOR_METATYPE_URL = 29,
110 EXTRACTOR_METATYPE_URI = 30,
111 EXTRACTOR_METATYPE_ISRC = 31,
112 EXTRACTOR_METATYPE_UNKNOWN = 45,
113 EXTRACTOR_METATYPE_DESCRIPTION = 46,
114 EXTRACTOR_METATYPE_KEYWORDS = 49,
115 EXTRACTOR_METATYPE_SUBJECT = 52,
116 EXTRACTOR_METATYPE_PACKAGE_NAME = 69,
117 EXTRACTOR_METATYPE_THUMBNAIL = 114,
118 EXTRACTOR_METATYPE_ALBUM = 129,
119 EXTRACTOR_METATYPE_ARTIST = 130,
120 EXTRACTOR_METATYPE_ORIGINAL_TITLE = 162,
121 EXTRACTOR_METATYPE_GNUNET_FULL_DATA = 174,
122 EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME = 180,
127 * Format in which the extracted meta data is presented.
129 enum EXTRACTOR_MetaFormat {
133 EXTRACTOR_METAFORMAT_UNKNOWN = 0,
136 * 0-terminated, UTF-8 encoded string. "data_len"
139 EXTRACTOR_METAFORMAT_UTF8 = 1,
142 * Some kind of binary format, see given Mime type.
144 EXTRACTOR_METAFORMAT_BINARY = 2,
147 * 0-terminated string. The specific encoding is unknown.
148 * "data_len" is strlen (data)+1.
150 EXTRACTOR_METAFORMAT_C_STRING = 3
155 * Type of a function that libextractor calls for each
156 * meta data item found.
158 * @param cls closure (user-defined)
159 * @param plugin_name name of the plugin that produced this value;
160 * special values can be used (i.e. '<zlib>' for zlib being
161 * used in the main libextractor library and yielding
163 * @param type libextractor-type describing the meta data
164 * @param format basic format information about @a data
165 * @param data_mime_type mime-type of @a data (not of the original file);
166 * can be NULL (if mime-type is not known)
167 * @param data actual meta-data found
168 * @param data_len number of bytes in @a data
169 * @return 0 to continue extracting, 1 to abort
172 (*EXTRACTOR_MetaDataProcessor) (void *cls,
173 const char *plugin_name,
174 enum EXTRACTOR_MetaType type,
175 enum EXTRACTOR_MetaFormat format,
176 const char *data_mime_type,
182 #ifndef EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME
183 /* hack for LE < 0.6.3 */
184 #define EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME 180
190 #if 0 /* keep Emacsens' auto-indent happy */
196 /* ******************* bloomfilter ***************** */
199 * @brief bloomfilter representation (opaque)
200 * @ingroup bloomfilter
202 struct GNUNET_CONTAINER_BloomFilter;
206 * @ingroup bloomfilter
207 * Iterator over `struct GNUNET_HashCode`.
210 * @param next set to the next hash code
211 * @return #GNUNET_YES if next was updated
212 * #GNUNET_NO if there are no more entries
215 (*GNUNET_CONTAINER_HashCodeIterator) (void *cls,
216 struct GNUNET_HashCode *next);
220 * @ingroup bloomfilter
221 * Load a Bloom filter from a file.
223 * @param filename the name of the file (or the prefix)
224 * @param size the size of the bloom-filter (number of
225 * bytes of storage space to use); will be rounded up
227 * @param k the number of #GNUNET_CRYPTO_hash-functions to apply per
228 * element (number of bits set per element in the set)
229 * @return the bloomfilter
231 struct GNUNET_CONTAINER_BloomFilter *
232 GNUNET_CONTAINER_bloomfilter_load (const char *filename,
238 * @ingroup bloomfilter
239 * Create a Bloom filter from raw bits.
241 * @param data the raw bits in memory (maybe NULL,
242 * in which case all bits should be considered
244 * @param size the size of the bloom-filter (number of
245 * bytes of storage space to use); also size of @a data
246 * -- unless data is NULL. Must be a power of 2.
247 * @param k the number of #GNUNET_CRYPTO_hash-functions to apply per
248 * element (number of bits set per element in the set)
249 * @return the bloomfilter
251 struct GNUNET_CONTAINER_BloomFilter *
252 GNUNET_CONTAINER_bloomfilter_init (const char *data,
258 * @ingroup bloomfilter
259 * Copy the raw data of this Bloom filter into
260 * the given data array.
262 * @param data where to write the data
263 * @param size the size of the given @a data array
264 * @return #GNUNET_SYSERR if the data array of the wrong size
267 GNUNET_CONTAINER_bloomfilter_get_raw_data (const struct GNUNET_CONTAINER_BloomFilter *bf,
273 * @ingroup bloomfilter
274 * Test if an element is in the filter.
276 * @param e the element
277 * @param bf the filter
278 * @return #GNUNET_YES if the element is in the filter, #GNUNET_NO if not
281 GNUNET_CONTAINER_bloomfilter_test (const struct GNUNET_CONTAINER_BloomFilter *bf,
282 const struct GNUNET_HashCode *e);
286 * @ingroup bloomfilter
287 * Add an element to the filter.
289 * @param bf the filter
290 * @param e the element
293 GNUNET_CONTAINER_bloomfilter_add (struct GNUNET_CONTAINER_BloomFilter *bf,
294 const struct GNUNET_HashCode *e);
298 * @ingroup bloomfilter
299 * Remove an element from the filter.
301 * @param bf the filter
302 * @param e the element to remove
305 GNUNET_CONTAINER_bloomfilter_remove (struct GNUNET_CONTAINER_BloomFilter *bf,
306 const struct GNUNET_HashCode *e);
310 * @ingroup bloomfilter
311 * Create a copy of a bloomfilter.
313 * @param bf the filter
316 struct GNUNET_CONTAINER_BloomFilter *
317 GNUNET_CONTAINER_bloomfilter_copy (const struct GNUNET_CONTAINER_BloomFilter *bf);
322 * @ingroup bloomfilter
323 * Free the space associcated with a filter
324 * in memory, flush to drive if needed (do not
325 * free the space on the drive).
327 * @param bf the filter
330 GNUNET_CONTAINER_bloomfilter_free (struct GNUNET_CONTAINER_BloomFilter *bf);
334 * Get the number of the addresses set per element in the bloom filter.
336 * @param bf the filter
337 * @return addresses set per element in the bf
340 GNUNET_CONTAINER_bloomfilter_get_element_addresses (const struct GNUNET_CONTAINER_BloomFilter *bf);
344 * @ingroup bloomfilter
345 * Get size of the bloom filter.
347 * @param bf the filter
348 * @return number of bytes used for the data of the bloom filter
351 GNUNET_CONTAINER_bloomfilter_get_size (const struct GNUNET_CONTAINER_BloomFilter *bf);
355 * @ingroup bloomfilter
356 * Reset a Bloom filter to empty.
358 * @param bf the filter
361 GNUNET_CONTAINER_bloomfilter_clear (struct GNUNET_CONTAINER_BloomFilter *bf);
365 * @ingroup bloomfilter
366 * "or" the entries of the given raw data array with the
367 * data of the given Bloom filter. Assumes that
368 * the @a size of the @a data array and the current filter
371 * @param bf the filter
372 * @param data data to OR-in
373 * @param size size of @a data
374 * @return #GNUNET_OK on success
377 GNUNET_CONTAINER_bloomfilter_or (struct GNUNET_CONTAINER_BloomFilter *bf,
378 const char *data, size_t size);
382 * @ingroup bloomfilter
383 * "or" the entries of the given raw data array with the
384 * data of the given Bloom filter. Assumes that
385 * the size of the two filters matches.
387 * @param bf the filter
388 * @param to_or the bloomfilter to or-in
389 * @return #GNUNET_OK on success
392 GNUNET_CONTAINER_bloomfilter_or2 (struct GNUNET_CONTAINER_BloomFilter *bf,
393 const struct GNUNET_CONTAINER_BloomFilter *to_or);
397 * @ingroup bloomfilter
398 * Resize a bloom filter. Note that this operation
399 * is pretty costly. Essentially, the Bloom filter
400 * needs to be completely re-build.
402 * @param bf the filter
403 * @param iterator an iterator over all elements stored in the BF
404 * @param iterator_cls closure for @a iterator
405 * @param size the new size for the filter
406 * @param k the new number of #GNUNET_CRYPTO_hash-function to apply per element
409 GNUNET_CONTAINER_bloomfilter_resize (struct GNUNET_CONTAINER_BloomFilter *bf,
410 GNUNET_CONTAINER_HashCodeIterator iterator,
416 /* ****************** metadata ******************* */
420 * Meta data to associate with a file, directory or namespace.
422 struct GNUNET_CONTAINER_MetaData;
427 * Create a fresh meta data container.
429 * @return empty meta-data container
431 struct GNUNET_CONTAINER_MetaData *
432 GNUNET_CONTAINER_meta_data_create (void);
437 * Duplicate a MetaData token.
439 * @param md what to duplicate
440 * @return duplicate meta-data container
442 struct GNUNET_CONTAINER_MetaData *
443 GNUNET_CONTAINER_meta_data_duplicate (const struct GNUNET_CONTAINER_MetaData *md);
450 * @param md what to free
453 GNUNET_CONTAINER_meta_data_destroy (struct GNUNET_CONTAINER_MetaData *md);
458 * Test if two MDs are equal. We consider them equal if
459 * the meta types, formats and content match (we do not
460 * include the mime types and plugins names in this
463 * @param md1 first value to check
464 * @param md2 other value to check
465 * @return #GNUNET_YES if they are equal
468 GNUNET_CONTAINER_meta_data_test_equal (const struct GNUNET_CONTAINER_MetaData *md1,
469 const struct GNUNET_CONTAINER_MetaData *md2);
476 * @param md metadata to extend
477 * @param plugin_name name of the plugin that produced this value;
478 * special values can be used (i.e. '<zlib>' for zlib being
479 * used in the main libextractor library and yielding
481 * @param type libextractor-type describing the meta data
482 * @param format basic format information about data
483 * @param data_mime_type mime-type of data (not of the original file);
484 * can be NULL (if mime-type is not known)
485 * @param data actual meta-data found
486 * @param data_size number of bytes in data
487 * @return #GNUNET_OK on success, #GNUNET_SYSERR if this entry already exists
488 * data_mime_type and plugin_name are not considered for "exists" checks
491 GNUNET_CONTAINER_meta_data_insert (struct GNUNET_CONTAINER_MetaData *md,
492 const char *plugin_name,
493 enum EXTRACTOR_MetaType type,
494 enum EXTRACTOR_MetaFormat format,
495 const char *data_mime_type,
502 * Extend metadata. Merges the meta data from the second argument
503 * into the first, discarding duplicate key-value pairs.
505 * @param md metadata to extend
506 * @param in metadata to merge
509 GNUNET_CONTAINER_meta_data_merge (struct GNUNET_CONTAINER_MetaData *md,
510 const struct GNUNET_CONTAINER_MetaData *in);
517 * @param md metadata to manipulate
518 * @param type type of the item to remove
519 * @param data specific value to remove, NULL to remove all
520 * entries of the given type
521 * @param data_size number of bytes in data
522 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the item does not exist in md
525 GNUNET_CONTAINER_meta_data_delete (struct GNUNET_CONTAINER_MetaData *md,
526 enum EXTRACTOR_MetaType type,
533 * Remove all items in the container.
535 * @param md metadata to manipulate
538 GNUNET_CONTAINER_meta_data_clear (struct GNUNET_CONTAINER_MetaData *md);
543 * Add the current time as the publication date
546 * @param md metadata to modify
549 GNUNET_CONTAINER_meta_data_add_publication_date (struct GNUNET_CONTAINER_MetaData *md);
554 * Iterate over MD entries.
556 * @param md metadata to inspect
557 * @param iter function to call on each entry, return 0 to continue to iterate
558 * and 1 to abort iteration in this function (GNU libextractor API!)
559 * @param iter_cls closure for @a iter
560 * @return number of entries
563 GNUNET_CONTAINER_meta_data_iterate (const struct GNUNET_CONTAINER_MetaData *md,
564 EXTRACTOR_MetaDataProcessor iter,
570 * Get the first MD entry of the given type. Caller
571 * is responsible for freeing the return value.
572 * Also, only meta data items that are strings (0-terminated)
573 * are returned by this function.
575 * @param md metadata to inspect
576 * @param type type to look for
577 * @return NULL if no entry was found
580 GNUNET_CONTAINER_meta_data_get_by_type (const struct GNUNET_CONTAINER_MetaData *md,
581 enum EXTRACTOR_MetaType type);
586 * Get the first matching MD entry of the given types. Caller is
587 * responsible for freeing the return value. Also, only meta data
588 * items that are strings (0-terminated) are returned by this
591 * @param md metadata to inspect
592 * @param ... -1-terminated list of types
593 * @return NULL if we do not have any such entry,
594 * otherwise client is responsible for freeing the value!
597 GNUNET_CONTAINER_meta_data_get_first_by_types (const struct GNUNET_CONTAINER_MetaData *md,
602 * Get a thumbnail from the meta-data (if present). Only matches meta
603 * data with mime type "image" and binary format.
605 * @param md metadata to inspect
606 * @param thumb will be set to the thumbnail data. Must be
607 * freed by the caller!
608 * @return number of bytes in thumbnail, 0 if not available
611 GNUNET_CONTAINER_meta_data_get_thumbnail (const struct GNUNET_CONTAINER_MetaData *md,
612 unsigned char **thumb);
618 * Options for metadata serialization.
620 enum GNUNET_CONTAINER_MetaDataSerializationOptions
624 * Serialize all of the data.
626 GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL = 0,
630 * If not enough space is available, it is acceptable
631 * to only serialize some of the metadata.
633 GNUNET_CONTAINER_META_DATA_SERIALIZE_PART = 1,
637 * Speed is of the essence, do not allow compression.
639 GNUNET_CONTAINER_META_DATA_SERIALIZE_NO_COMPRESS = 2
645 * Serialize meta-data to target.
647 * @param md metadata to serialize
648 * @param target where to write the serialized metadata;
649 * *target can be NULL, in which case memory is allocated
650 * @param max maximum number of bytes available
651 * @param opt is it ok to just write SOME of the
652 * meta-data to match the size constraint,
653 * possibly discarding some data?
654 * @return number of bytes written on success,
655 * -1 on error (typically: not enough
659 GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData *md,
662 enum GNUNET_CONTAINER_MetaDataSerializationOptions opt);
667 * Get the size of the full meta-data in serialized form.
669 * @param md metadata to inspect
670 * @return number of bytes needed for serialization, -1 on error
673 GNUNET_CONTAINER_meta_data_get_serialized_size (const struct GNUNET_CONTAINER_MetaData *md);
678 * Deserialize meta-data. Initializes md.
680 * @param input serialized meta-data.
681 * @param size number of bytes available
682 * @return MD on success, NULL on error (i.e.
685 struct GNUNET_CONTAINER_MetaData *
686 GNUNET_CONTAINER_meta_data_deserialize (const char *input,
690 /* ******************************* HashMap **************************** */
694 * Opaque handle for a HashMap.
696 struct GNUNET_CONTAINER_MultiHashMap;
700 * Opaque handle to an iterator over
703 struct GNUNET_CONTAINER_MultiHashMapIterator;
707 * Options for storing values in the HashMap.
709 enum GNUNET_CONTAINER_MultiHashMapOption
714 * If a value with the given key exists, replace it. Note that the
715 * old value would NOT be freed by replace (the application has to
716 * make sure that this happens if required).
718 GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE,
722 * Allow multiple values with the same key.
724 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE,
728 * There must only be one value per key; storing a value should fail
729 * if a value under the same key already exists.
731 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY,
734 * @ingroup hashmap There must only be one value per key, but don't
735 * bother checking if a value already exists (faster than
736 * #GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY; implemented
737 * just like #GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE but this
738 * option documents better what is intended if
739 * #GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY is what is
742 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST
748 * Iterator over hash map entries.
751 * @param key current key code
752 * @param value value in the hash map
753 * @return #GNUNET_YES if we should continue to
758 (*GNUNET_CONTAINER_HashMapIterator) (void *cls,
759 const struct GNUNET_HashCode *key,
765 * Create a multi hash map.
767 * @param len initial size (map will grow as needed)
768 * @param do_not_copy_keys #GNUNET_NO is always safe and should be used by default;
769 * #GNUNET_YES means that on 'put', the 'key' does not have
770 * to be copied as the destination of the pointer is
771 * guaranteed to be life as long as the value is stored in
772 * the hashmap. This can significantly reduce memory
773 * consumption, but of course is also a recipie for
774 * heap corruption if the assumption is not true. Only
775 * use this if (1) memory use is important in this case and
776 * (2) you have triple-checked that the invariant holds
777 * @return NULL on error
779 struct GNUNET_CONTAINER_MultiHashMap *
780 GNUNET_CONTAINER_multihashmap_create (unsigned int len,
781 int do_not_copy_keys);
786 * Destroy a hash map. Will not free any values
787 * stored in the hash map!
792 GNUNET_CONTAINER_multihashmap_destroy (struct GNUNET_CONTAINER_MultiHashMap *map);
797 * Given a key find a value in the map matching the key.
800 * @param key what to look for
801 * @return NULL if no value was found; note that
802 * this is indistinguishable from values that just
803 * happen to be NULL; use "contains" to test for
804 * key-value pairs with value NULL
807 GNUNET_CONTAINER_multihashmap_get (const struct GNUNET_CONTAINER_MultiHashMap *map,
808 const struct GNUNET_HashCode *key);
813 * Remove the given key-value pair from the map. Note that if the
814 * key-value pair is in the map multiple times, only one of the pairs
818 * @param key key of the key-value pair
819 * @param value value of the key-value pair
820 * @return #GNUNET_YES on success, #GNUNET_NO if the key-value pair
824 GNUNET_CONTAINER_multihashmap_remove (struct GNUNET_CONTAINER_MultiHashMap *map,
825 const struct GNUNET_HashCode *key,
830 * Remove all entries for the given key from the map.
831 * Note that the values would not be "freed".
834 * @param key identifies values to be removed
835 * @return number of values removed
838 GNUNET_CONTAINER_multihashmap_remove_all (struct GNUNET_CONTAINER_MultiHashMap *map,
839 const struct GNUNET_HashCode *key);
844 * Remove all entries from the map.
845 * Note that the values would not be "freed".
848 * @return number of values removed
851 GNUNET_CONTAINER_multihashmap_clear (struct GNUNET_CONTAINER_MultiHashMap *map);
856 * Check if the map contains any value under the given
857 * key (including values that are NULL).
860 * @param key the key to test if a value exists for it
861 * @return #GNUNET_YES if such a value exists,
865 GNUNET_CONTAINER_multihashmap_contains (const struct GNUNET_CONTAINER_MultiHashMap *map,
866 const struct GNUNET_HashCode * key);
871 * Check if the map contains the given value under the given
875 * @param key the key to test if a value exists for it
876 * @param value value to test for
877 * @return #GNUNET_YES if such a value exists,
881 GNUNET_CONTAINER_multihashmap_contains_value (const struct GNUNET_CONTAINER_MultiHashMap *map,
882 const struct GNUNET_HashCode *key,
888 * Store a key-value pair in the map.
891 * @param key key to use
892 * @param value value to use
893 * @param opt options for put
894 * @return #GNUNET_OK on success,
895 * #GNUNET_NO if a value was replaced (with REPLACE)
896 * #GNUNET_SYSERR if #GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY was the option and the
897 * value already exists
900 GNUNET_CONTAINER_multihashmap_put (struct GNUNET_CONTAINER_MultiHashMap *map,
901 const struct GNUNET_HashCode *key,
903 enum GNUNET_CONTAINER_MultiHashMapOption
908 * Get the number of key-value pairs in the map.
911 * @return the number of key value pairs
914 GNUNET_CONTAINER_multihashmap_size (const struct GNUNET_CONTAINER_MultiHashMap *map);
919 * Iterate over all entries in the map.
922 * @param it function to call on each entry
923 * @param it_cls extra argument to @a it
924 * @return the number of key value pairs processed,
925 * #GNUNET_SYSERR if it aborted iteration
928 GNUNET_CONTAINER_multihashmap_iterate (const struct GNUNET_CONTAINER_MultiHashMap *map,
929 GNUNET_CONTAINER_HashMapIterator it,
935 * Create an iterator for a multihashmap.
936 * The iterator can be used to retrieve all the elements in the multihashmap
937 * one by one, without having to handle all elements at once (in contrast to
938 * #GNUNET_CONTAINER_multihashmap_iterate). Note that the iterator can not be
939 * used anymore if elements have been removed from 'map' after the creation of
940 * the iterator, or 'map' has been destroyed. Adding elements to 'map' may
941 * result in skipped or repeated elements.
943 * @param map the map to create an iterator for
944 * @return an iterator over the given multihashmap @a map
946 struct GNUNET_CONTAINER_MultiHashMapIterator *
947 GNUNET_CONTAINER_multihashmap_iterator_create (const struct GNUNET_CONTAINER_MultiHashMap *map);
952 * Retrieve the next element from the hash map at the iterator's
953 * position. If there are no elements left, #GNUNET_NO is returned,
954 * and @a key and @a value are not modified. This operation is only
955 * allowed if no elements have been removed from the multihashmap
956 * since the creation of @a iter, and the map has not been destroyed.
957 * Adding elements may result in repeating or skipping elements.
959 * @param iter the iterator to get the next element from
960 * @param key pointer to store the key in, can be NULL
961 * @param value pointer to store the value in, can be NULL
962 * @return #GNUNET_YES we returned an element,
963 * #GNUNET_NO if we are out of elements
966 GNUNET_CONTAINER_multihashmap_iterator_next (struct GNUNET_CONTAINER_MultiHashMapIterator *iter,
967 struct GNUNET_HashCode *key,
973 * Destroy a multihashmap iterator.
975 * @param iter the iterator to destroy
978 GNUNET_CONTAINER_multihashmap_iterator_destroy (struct GNUNET_CONTAINER_MultiHashMapIterator *iter);
983 * Iterate over all entries in the map that match a particular key.
986 * @param key key that the entries must correspond to
987 * @param it function to call on each entry
988 * @param it_cls extra argument to @a it
989 * @return the number of key value pairs processed,
990 * #GNUNET_SYSERR if it aborted iteration
993 GNUNET_CONTAINER_multihashmap_get_multiple (const struct GNUNET_CONTAINER_MultiHashMap *map,
994 const struct GNUNET_HashCode *key,
995 GNUNET_CONTAINER_HashMapIterator it,
1001 * Call @a it on a random value from the map, or not at all
1002 * if the map is empty. Note that this function has linear
1003 * complexity (in the size of the map).
1005 * @param map the map
1006 * @param it function to call on a random entry
1007 * @param it_cls extra argument to @a it
1008 * @return the number of key value pairs processed, zero or one.
1011 GNUNET_CONTAINER_multihashmap_get_random (const struct GNUNET_CONTAINER_MultiHashMap *map,
1012 GNUNET_CONTAINER_HashMapIterator it,
1016 /* ***************** Version of Multihashmap for peer identities ****************** */
1020 * Iterator over hash map entries.
1022 * @param cls closure
1023 * @param key current public key
1024 * @param value value in the hash map
1025 * @return #GNUNET_YES if we should continue to
1027 * #GNUNET_NO if not.
1030 (*GNUNET_CONTAINER_PeerMapIterator) (void *cls,
1031 const struct GNUNET_PeerIdentity *key,
1036 * Hash map from peer identities to values.
1038 struct GNUNET_CONTAINER_MultiPeerMap;
1043 * Create a multi peer map (hash map for public keys of peers).
1045 * @param len initial size (map will grow as needed)
1046 * @param do_not_copy_keys #GNUNET_NO is always safe and should be used by default;
1047 * #GNUNET_YES means that on 'put', the 'key' does not have
1048 * to be copied as the destination of the pointer is
1049 * guaranteed to be life as long as the value is stored in
1050 * the hashmap. This can significantly reduce memory
1051 * consumption, but of course is also a recipie for
1052 * heap corruption if the assumption is not true. Only
1053 * use this if (1) memory use is important in this case and
1054 * (2) you have triple-checked that the invariant holds
1055 * @return NULL on error
1057 struct GNUNET_CONTAINER_MultiPeerMap *
1058 GNUNET_CONTAINER_multipeermap_create (unsigned int len,
1059 int do_not_copy_keys);
1064 * Destroy a hash map. Will not free any values
1065 * stored in the hash map!
1067 * @param map the map
1070 GNUNET_CONTAINER_multipeermap_destroy (struct GNUNET_CONTAINER_MultiPeerMap *map);
1075 * Given a key find a value in the map matching the key.
1077 * @param map the map
1078 * @param key what to look for
1079 * @return NULL if no value was found; note that
1080 * this is indistinguishable from values that just
1081 * happen to be NULL; use "contains" to test for
1082 * key-value pairs with value NULL
1085 GNUNET_CONTAINER_multipeermap_get (const struct GNUNET_CONTAINER_MultiPeerMap *map,
1086 const struct GNUNET_PeerIdentity *key);
1091 * Remove the given key-value pair from the map. Note that if the
1092 * key-value pair is in the map multiple times, only one of the pairs
1095 * @param map the map
1096 * @param key key of the key-value pair
1097 * @param value value of the key-value pair
1098 * @return #GNUNET_YES on success, #GNUNET_NO if the key-value pair
1102 GNUNET_CONTAINER_multipeermap_remove (struct GNUNET_CONTAINER_MultiPeerMap *map,
1103 const struct GNUNET_PeerIdentity * key,
1108 * Remove all entries for the given key from the map.
1109 * Note that the values would not be "freed".
1111 * @param map the map
1112 * @param key identifies values to be removed
1113 * @return number of values removed
1116 GNUNET_CONTAINER_multipeermap_remove_all (struct GNUNET_CONTAINER_MultiPeerMap *map,
1117 const struct GNUNET_PeerIdentity *key);
1122 * Check if the map contains any value under the given
1123 * key (including values that are NULL).
1125 * @param map the map
1126 * @param key the key to test if a value exists for it
1127 * @return #GNUNET_YES if such a value exists,
1131 GNUNET_CONTAINER_multipeermap_contains (const struct GNUNET_CONTAINER_MultiPeerMap *map,
1132 const struct GNUNET_PeerIdentity *key);
1137 * Check if the map contains the given value under the given
1140 * @param map the map
1141 * @param key the key to test if a value exists for it
1142 * @param value value to test for
1143 * @return #GNUNET_YES if such a value exists,
1147 GNUNET_CONTAINER_multipeermap_contains_value (const struct GNUNET_CONTAINER_MultiPeerMap *map,
1148 const struct GNUNET_PeerIdentity * key,
1154 * Store a key-value pair in the map.
1156 * @param map the map
1157 * @param key key to use
1158 * @param value value to use
1159 * @param opt options for put
1160 * @return #GNUNET_OK on success,
1161 * #GNUNET_NO if a value was replaced (with REPLACE)
1162 * #GNUNET_SYSERR if #GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY was the option and the
1163 * value already exists
1166 GNUNET_CONTAINER_multipeermap_put (struct GNUNET_CONTAINER_MultiPeerMap *map,
1167 const struct GNUNET_PeerIdentity *key,
1169 enum GNUNET_CONTAINER_MultiHashMapOption opt);
1174 * Get the number of key-value pairs in the map.
1176 * @param map the map
1177 * @return the number of key value pairs
1180 GNUNET_CONTAINER_multipeermap_size (const struct GNUNET_CONTAINER_MultiPeerMap *map);
1185 * Iterate over all entries in the map.
1187 * @param map the map
1188 * @param it function to call on each entry
1189 * @param it_cls extra argument to @a it
1190 * @return the number of key value pairs processed,
1191 * #GNUNET_SYSERR if it aborted iteration
1194 GNUNET_CONTAINER_multipeermap_iterate (const struct GNUNET_CONTAINER_MultiPeerMap *map,
1195 GNUNET_CONTAINER_PeerMapIterator it,
1199 struct GNUNET_CONTAINER_MultiPeerMapIterator;
1202 * Create an iterator for a multihashmap.
1203 * The iterator can be used to retrieve all the elements in the multihashmap
1204 * one by one, without having to handle all elements at once (in contrast to
1205 * #GNUNET_CONTAINER_multipeermap_iterate). Note that the iterator can not be
1206 * used anymore if elements have been removed from @a map after the creation of
1207 * the iterator, or 'map' has been destroyed. Adding elements to @a map may
1208 * result in skipped or repeated elements.
1210 * @param map the map to create an iterator for
1211 * @return an iterator over the given multihashmap @a map
1213 struct GNUNET_CONTAINER_MultiPeerMapIterator *
1214 GNUNET_CONTAINER_multipeermap_iterator_create (const struct GNUNET_CONTAINER_MultiPeerMap *map);
1219 * Retrieve the next element from the hash map at the iterator's
1220 * position. If there are no elements left, #GNUNET_NO is returned,
1221 * and @a key and @a value are not modified. This operation is only
1222 * allowed if no elements have been removed from the multihashmap
1223 * since the creation of @a iter, and the map has not been destroyed.
1224 * Adding elements may result in repeating or skipping elements.
1226 * @param iter the iterator to get the next element from
1227 * @param key pointer to store the key in, can be NULL
1228 * @param value pointer to store the value in, can be NULL
1229 * @return #GNUNET_YES we returned an element,
1230 * #GNUNET_NO if we are out of elements
1233 GNUNET_CONTAINER_multipeermap_iterator_next (struct GNUNET_CONTAINER_MultiPeerMapIterator *iter,
1234 struct GNUNET_PeerIdentity *key,
1235 const void **value);
1240 * Destroy a multipeermap iterator.
1242 * @param iter the iterator to destroy
1245 GNUNET_CONTAINER_multipeermap_iterator_destroy (struct GNUNET_CONTAINER_MultiPeerMapIterator *iter);
1250 * Iterate over all entries in the map that match a particular key.
1252 * @param map the map
1253 * @param key public key that the entries must correspond to
1254 * @param it function to call on each entry
1255 * @param it_cls extra argument to @a it
1256 * @return the number of key value pairs processed,
1257 * #GNUNET_SYSERR if it aborted iteration
1260 GNUNET_CONTAINER_multipeermap_get_multiple (const struct GNUNET_CONTAINER_MultiPeerMap *map,
1261 const struct GNUNET_PeerIdentity *key,
1262 GNUNET_CONTAINER_PeerMapIterator it,
1268 * Call @a it on a random value from the map, or not at all
1269 * if the map is empty. Note that this function has linear
1270 * complexity (in the size of the map).
1272 * @param map the map
1273 * @param it function to call on a random entry
1274 * @param it_cls extra argument to @a it
1275 * @return the number of key value pairs processed, zero or one.
1278 GNUNET_CONTAINER_multipeermap_get_random (const struct GNUNET_CONTAINER_MultiPeerMap *map,
1279 GNUNET_CONTAINER_PeerMapIterator it,
1283 /* ***************** Version of Multihashmap for short hashes ****************** */
1287 * Iterator over hash map entries.
1289 * @param cls closure
1290 * @param key current public key
1291 * @param value value in the hash map
1292 * @return #GNUNET_YES if we should continue to
1294 * #GNUNET_NO if not.
1297 (*GNUNET_CONTAINER_ShortmapIterator) (void *cls,
1298 const struct GNUNET_ShortHashCode *key,
1303 * Hash map from peer identities to values.
1305 struct GNUNET_CONTAINER_MultiShortmap;
1310 * Create a multi peer map (hash map for public keys of peers).
1312 * @param len initial size (map will grow as needed)
1313 * @param do_not_copy_keys #GNUNET_NO is always safe and should be used by default;
1314 * #GNUNET_YES means that on 'put', the 'key' does not have
1315 * to be copied as the destination of the pointer is
1316 * guaranteed to be life as long as the value is stored in
1317 * the hashmap. This can significantly reduce memory
1318 * consumption, but of course is also a recipie for
1319 * heap corruption if the assumption is not true. Only
1320 * use this if (1) memory use is important in this case and
1321 * (2) you have triple-checked that the invariant holds
1322 * @return NULL on error
1324 struct GNUNET_CONTAINER_MultiShortmap *
1325 GNUNET_CONTAINER_multishortmap_create (unsigned int len,
1326 int do_not_copy_keys);
1331 * Destroy a hash map. Will not free any values
1332 * stored in the hash map!
1334 * @param map the map
1337 GNUNET_CONTAINER_multishortmap_destroy (struct GNUNET_CONTAINER_MultiShortmap *map);
1342 * Given a key find a value in the map matching the key.
1344 * @param map the map
1345 * @param key what to look for
1346 * @return NULL if no value was found; note that
1347 * this is indistinguishable from values that just
1348 * happen to be NULL; use "contains" to test for
1349 * key-value pairs with value NULL
1352 GNUNET_CONTAINER_multishortmap_get (const struct GNUNET_CONTAINER_MultiShortmap *map,
1353 const struct GNUNET_ShortHashCode *key);
1358 * Remove the given key-value pair from the map. Note that if the
1359 * key-value pair is in the map multiple times, only one of the pairs
1362 * @param map the map
1363 * @param key key of the key-value pair
1364 * @param value value of the key-value pair
1365 * @return #GNUNET_YES on success, #GNUNET_NO if the key-value pair
1369 GNUNET_CONTAINER_multishortmap_remove (struct GNUNET_CONTAINER_MultiShortmap *map,
1370 const struct GNUNET_ShortHashCode * key,
1375 * Remove all entries for the given key from the map.
1376 * Note that the values would not be "freed".
1378 * @param map the map
1379 * @param key identifies values to be removed
1380 * @return number of values removed
1383 GNUNET_CONTAINER_multishortmap_remove_all (struct GNUNET_CONTAINER_MultiShortmap *map,
1384 const struct GNUNET_ShortHashCode *key);
1389 * Check if the map contains any value under the given
1390 * key (including values that are NULL).
1392 * @param map the map
1393 * @param key the key to test if a value exists for it
1394 * @return #GNUNET_YES if such a value exists,
1398 GNUNET_CONTAINER_multishortmap_contains (const struct GNUNET_CONTAINER_MultiShortmap *map,
1399 const struct GNUNET_ShortHashCode *key);
1404 * Check if the map contains the given value under the given
1407 * @param map the map
1408 * @param key the key to test if a value exists for it
1409 * @param value value to test for
1410 * @return #GNUNET_YES if such a value exists,
1414 GNUNET_CONTAINER_multishortmap_contains_value (const struct GNUNET_CONTAINER_MultiShortmap *map,
1415 const struct GNUNET_ShortHashCode * key,
1421 * Store a key-value pair in the map.
1423 * @param map the map
1424 * @param key key to use
1425 * @param value value to use
1426 * @param opt options for put
1427 * @return #GNUNET_OK on success,
1428 * #GNUNET_NO if a value was replaced (with REPLACE)
1429 * #GNUNET_SYSERR if #GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY was the option and the
1430 * value already exists
1433 GNUNET_CONTAINER_multishortmap_put (struct GNUNET_CONTAINER_MultiShortmap *map,
1434 const struct GNUNET_ShortHashCode *key,
1436 enum GNUNET_CONTAINER_MultiHashMapOption opt);
1441 * Get the number of key-value pairs in the map.
1443 * @param map the map
1444 * @return the number of key value pairs
1447 GNUNET_CONTAINER_multishortmap_size (const struct GNUNET_CONTAINER_MultiShortmap *map);
1452 * Iterate over all entries in the map.
1454 * @param map the map
1455 * @param it function to call on each entry
1456 * @param it_cls extra argument to @a it
1457 * @return the number of key value pairs processed,
1458 * #GNUNET_SYSERR if it aborted iteration
1461 GNUNET_CONTAINER_multishortmap_iterate (const struct GNUNET_CONTAINER_MultiShortmap *map,
1462 GNUNET_CONTAINER_ShortmapIterator it,
1466 struct GNUNET_CONTAINER_MultiShortmapIterator;
1471 * Create an iterator for a multihashmap.
1472 * The iterator can be used to retrieve all the elements in the multihashmap
1473 * one by one, without having to handle all elements at once (in contrast to
1474 * #GNUNET_CONTAINER_multishortmap_iterate). Note that the iterator can not be
1475 * used anymore if elements have been removed from @a map after the creation of
1476 * the iterator, or 'map' has been destroyed. Adding elements to @a map may
1477 * result in skipped or repeated elements.
1479 * @param map the map to create an iterator for
1480 * @return an iterator over the given multihashmap @a map
1482 struct GNUNET_CONTAINER_MultiShortmapIterator *
1483 GNUNET_CONTAINER_multishortmap_iterator_create (const struct GNUNET_CONTAINER_MultiShortmap *map);
1488 * Retrieve the next element from the hash map at the iterator's
1489 * position. If there are no elements left, #GNUNET_NO is returned,
1490 * and @a key and @a value are not modified. This operation is only
1491 * allowed if no elements have been removed from the multihashmap
1492 * since the creation of @a iter, and the map has not been destroyed.
1493 * Adding elements may result in repeating or skipping elements.
1495 * @param iter the iterator to get the next element from
1496 * @param key pointer to store the key in, can be NULL
1497 * @param value pointer to store the value in, can be NULL
1498 * @return #GNUNET_YES we returned an element,
1499 * #GNUNET_NO if we are out of elements
1502 GNUNET_CONTAINER_multishortmap_iterator_next (struct GNUNET_CONTAINER_MultiShortmapIterator *iter,
1503 struct GNUNET_ShortHashCode *key,
1504 const void **value);
1509 * Destroy a multishortmap iterator.
1511 * @param iter the iterator to destroy
1514 GNUNET_CONTAINER_multishortmap_iterator_destroy (struct GNUNET_CONTAINER_MultiShortmapIterator *iter);
1519 * Iterate over all entries in the map that match a particular key.
1521 * @param map the map
1522 * @param key public key that the entries must correspond to
1523 * @param it function to call on each entry
1524 * @param it_cls extra argument to @a it
1525 * @return the number of key value pairs processed,
1526 * #GNUNET_SYSERR if it aborted iteration
1529 GNUNET_CONTAINER_multishortmap_get_multiple (const struct GNUNET_CONTAINER_MultiShortmap *map,
1530 const struct GNUNET_ShortHashCode *key,
1531 GNUNET_CONTAINER_ShortmapIterator it,
1537 * Call @a it on a random value from the map, or not at all
1538 * if the map is empty. Note that this function has linear
1539 * complexity (in the size of the map).
1541 * @param map the map
1542 * @param it function to call on a random entry
1543 * @param it_cls extra argument to @a it
1544 * @return the number of key value pairs processed, zero or one.
1547 GNUNET_CONTAINER_multishortmap_get_random (const struct GNUNET_CONTAINER_MultiShortmap *map,
1548 GNUNET_CONTAINER_ShortmapIterator it,
1552 /* Version of multihashmap with 32 bit keys */
1556 * Opaque handle for the 32-bit key HashMap.
1558 struct GNUNET_CONTAINER_MultiHashMap32;
1563 * Opaque handle to an iterator over
1564 * a 32-bit key multihashmap.
1566 struct GNUNET_CONTAINER_MultiHashMap32Iterator;
1571 * Iterator over hash map entries.
1573 * @param cls closure
1574 * @param key current key code
1575 * @param value value in the hash map
1576 * @return #GNUNET_YES if we should continue to
1578 * #GNUNET_NO if not.
1580 typedef int (*GNUNET_CONTAINER_HashMapIterator32) (void *cls,
1587 * Create a 32-bit key multi hash map.
1589 * @param len initial size (map will grow as needed)
1590 * @return NULL on error
1592 struct GNUNET_CONTAINER_MultiHashMap32 *
1593 GNUNET_CONTAINER_multihashmap32_create (unsigned int len);
1598 * Destroy a 32-bit key hash map. Will not free any values
1599 * stored in the hash map!
1601 * @param map the map
1604 GNUNET_CONTAINER_multihashmap32_destroy (struct GNUNET_CONTAINER_MultiHashMap32
1610 * Get the number of key-value pairs in the map.
1612 * @param map the map
1613 * @return the number of key value pairs
1616 GNUNET_CONTAINER_multihashmap32_size (const struct
1617 GNUNET_CONTAINER_MultiHashMap32 *map);
1622 * Given a key find a value in the map matching the key.
1624 * @param map the map
1625 * @param key what to look for
1626 * @return NULL if no value was found; note that
1627 * this is indistinguishable from values that just
1628 * happen to be NULL; use "contains" to test for
1629 * key-value pairs with value NULL
1632 GNUNET_CONTAINER_multihashmap32_get (const struct
1633 GNUNET_CONTAINER_MultiHashMap32 *map,
1639 * Iterate over all entries in the map.
1641 * @param map the map
1642 * @param it function to call on each entry
1643 * @param it_cls extra argument to @a it
1644 * @return the number of key value pairs processed,
1645 * #GNUNET_SYSERR if it aborted iteration
1648 GNUNET_CONTAINER_multihashmap32_iterate (const struct
1649 GNUNET_CONTAINER_MultiHashMap32 *map,
1650 GNUNET_CONTAINER_HashMapIterator32 it,
1656 * Remove the given key-value pair from the map. Note that if the
1657 * key-value pair is in the map multiple times, only one of the pairs
1660 * @param map the map
1661 * @param key key of the key-value pair
1662 * @param value value of the key-value pair
1663 * @return #GNUNET_YES on success, #GNUNET_NO if the key-value pair
1667 GNUNET_CONTAINER_multihashmap32_remove (struct GNUNET_CONTAINER_MultiHashMap32 *map,
1674 * Remove all entries for the given key from the map.
1675 * Note that the values would not be "freed".
1677 * @param map the map
1678 * @param key identifies values to be removed
1679 * @return number of values removed
1682 GNUNET_CONTAINER_multihashmap32_remove_all (struct GNUNET_CONTAINER_MultiHashMap32 *map,
1688 * Check if the map contains any value under the given
1689 * key (including values that are NULL).
1691 * @param map the map
1692 * @param key the key to test if a value exists for it
1693 * @return #GNUNET_YES if such a value exists,
1697 GNUNET_CONTAINER_multihashmap32_contains (const struct GNUNET_CONTAINER_MultiHashMap32 *map,
1703 * Check if the map contains the given value under the given
1706 * @param map the map
1707 * @param key the key to test if a value exists for it
1708 * @param value value to test for
1709 * @return #GNUNET_YES if such a value exists,
1713 GNUNET_CONTAINER_multihashmap32_contains_value (const struct GNUNET_CONTAINER_MultiHashMap32 *map,
1720 * Store a key-value pair in the map.
1722 * @param map the map
1723 * @param key key to use
1724 * @param value value to use
1725 * @param opt options for put
1726 * @return #GNUNET_OK on success,
1727 * #GNUNET_NO if a value was replaced (with REPLACE)
1728 * #GNUNET_SYSERR if #GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY was the option and the
1729 * value already exists
1732 GNUNET_CONTAINER_multihashmap32_put (struct GNUNET_CONTAINER_MultiHashMap32 *map,
1735 enum GNUNET_CONTAINER_MultiHashMapOption opt);
1740 * Iterate over all entries in the map that match a particular key.
1742 * @param map the map
1743 * @param key key that the entries must correspond to
1744 * @param it function to call on each entry
1745 * @param it_cls extra argument to @a it
1746 * @return the number of key value pairs processed,
1747 * #GNUNET_SYSERR if it aborted iteration
1750 GNUNET_CONTAINER_multihashmap32_get_multiple (const struct GNUNET_CONTAINER_MultiHashMap32 *map,
1752 GNUNET_CONTAINER_HashMapIterator32 it,
1757 * Create an iterator for a 32-bit multihashmap.
1758 * The iterator can be used to retrieve all the elements in the multihashmap
1759 * one by one, without having to handle all elements at once (in contrast to
1760 * #GNUNET_CONTAINER_multihashmap32_iterate). Note that the iterator can not be
1761 * used anymore if elements have been removed from 'map' after the creation of
1762 * the iterator, or 'map' has been destroyed. Adding elements to 'map' may
1763 * result in skipped or repeated elements.
1765 * @param map the map to create an iterator for
1766 * @return an iterator over the given multihashmap map
1768 struct GNUNET_CONTAINER_MultiHashMap32Iterator *
1769 GNUNET_CONTAINER_multihashmap32_iterator_create (const struct GNUNET_CONTAINER_MultiHashMap32 *map);
1773 * Retrieve the next element from the hash map at the iterator's position.
1774 * If there are no elements left, GNUNET_NO is returned, and 'key' and 'value'
1776 * This operation is only allowed if no elements have been removed from the
1777 * multihashmap since the creation of 'iter', and the map has not been destroyed.
1778 * Adding elements may result in repeating or skipping elements.
1780 * @param iter the iterator to get the next element from
1781 * @param key pointer to store the key in, can be NULL
1782 * @param value pointer to store the value in, can be NULL
1783 * @return #GNUNET_YES we returned an element,
1784 * #GNUNET_NO if we are out of elements
1787 GNUNET_CONTAINER_multihashmap32_iterator_next (struct GNUNET_CONTAINER_MultiHashMap32Iterator *iter,
1789 const void **value);
1793 * Destroy a 32-bit multihashmap iterator.
1795 * @param iter the iterator to destroy
1798 GNUNET_CONTAINER_multihashmap32_iterator_destroy (struct GNUNET_CONTAINER_MultiHashMapIterator *iter);
1801 /* ******************** doubly-linked list *************** */
1802 /* To avoid mistakes: head->prev == tail->next == NULL */
1806 * Insert an element at the head of a DLL. Assumes that head, tail and
1807 * element are structs with prev and next fields.
1809 * @param head pointer to the head of the DLL
1810 * @param tail pointer to the tail of the DLL
1811 * @param element element to insert
1813 #define GNUNET_CONTAINER_DLL_insert(head,tail,element) do { \
1814 GNUNET_assert ( ( (element)->prev == NULL) && ((head) != (element))); \
1815 GNUNET_assert ( ( (element)->next == NULL) && ((tail) != (element))); \
1816 (element)->next = (head); \
1817 (element)->prev = NULL; \
1818 if ((tail) == NULL) \
1821 (head)->prev = element; \
1822 (head) = (element); } while (0)
1827 * Insert an element at the tail of a DLL. Assumes that head, tail and
1828 * element are structs with prev and next fields.
1830 * @param head pointer to the head of the DLL
1831 * @param tail pointer to the tail of the DLL
1832 * @param element element to insert
1834 #define GNUNET_CONTAINER_DLL_insert_tail(head,tail,element) do { \
1835 GNUNET_assert ( ( (element)->prev == NULL) && ((head) != (element))); \
1836 GNUNET_assert ( ( (element)->next == NULL) && ((tail) != (element))); \
1837 (element)->prev = (tail); \
1838 (element)->next = NULL; \
1839 if ((head) == NULL) \
1842 (tail)->next = element; \
1843 (tail) = (element); } while (0)
1848 * Insert an element into a DLL after the given other element. Insert
1849 * at the head if the other element is NULL.
1851 * @param head pointer to the head of the DLL
1852 * @param tail pointer to the tail of the DLL
1853 * @param other prior element, NULL for insertion at head of DLL
1854 * @param element element to insert
1856 #define GNUNET_CONTAINER_DLL_insert_after(head,tail,other,element) do { \
1857 GNUNET_assert ( ( (element)->prev == NULL) && ((head) != (element))); \
1858 GNUNET_assert ( ( (element)->next == NULL) && ((tail) != (element))); \
1859 (element)->prev = (other); \
1860 if (NULL == other) \
1862 (element)->next = (head); \
1863 (head) = (element); \
1867 (element)->next = (other)->next; \
1868 (other)->next = (element); \
1870 if (NULL == (element)->next) \
1871 (tail) = (element); \
1873 (element)->next->prev = (element); } while (0)
1878 * Insert an element into a DLL before the given other element. Insert
1879 * at the tail if the other element is NULL.
1881 * @param head pointer to the head of the DLL
1882 * @param tail pointer to the tail of the DLL
1883 * @param other prior element, NULL for insertion at head of DLL
1884 * @param element element to insert
1886 #define GNUNET_CONTAINER_DLL_insert_before(head,tail,other,element) do { \
1887 GNUNET_assert ( ( (element)->prev == NULL) && ((head) != (element))); \
1888 GNUNET_assert ( ( (element)->next == NULL) && ((tail) != (element))); \
1889 (element)->next = (other); \
1890 if (NULL == other) \
1892 (element)->prev = (tail); \
1893 (tail) = (element); \
1897 (element)->prev = (other)->prev; \
1898 (other)->prev = (element); \
1900 if (NULL == (element)->prev) \
1901 (head) = (element); \
1903 (element)->prev->next = (element); } while (0)
1908 * Remove an element from a DLL. Assumes that head, tail and
1909 * element point to structs with prev and next fields.
1911 * Using the head or tail pointer as the element
1912 * argument does NOT work with this macro.
1913 * Make sure to store head/tail in another pointer
1914 * and use it to remove the head or tail of the list.
1916 * @param head pointer to the head of the DLL
1917 * @param tail pointer to the tail of the DLL
1918 * @param element element to remove
1920 #define GNUNET_CONTAINER_DLL_remove(head,tail,element) do { \
1921 GNUNET_assert ( ( (element)->prev != NULL) || ((head) == (element))); \
1922 GNUNET_assert ( ( (element)->next != NULL) || ((tail) == (element))); \
1923 if ((element)->prev == NULL) \
1924 (head) = (element)->next; \
1926 (element)->prev->next = (element)->next; \
1927 if ((element)->next == NULL) \
1928 (tail) = (element)->prev; \
1930 (element)->next->prev = (element)->prev; \
1931 (element)->next = NULL; \
1932 (element)->prev = NULL; } while (0)
1935 /* ************ Multi-DLL interface, allows DLL elements to be
1936 in multiple lists at the same time *********************** */
1940 * Insert an element at the head of a MDLL. Assumes that head, tail and
1941 * element are structs with prev and next fields.
1943 * @param mdll suffix name for the next and prev pointers in the element
1944 * @param head pointer to the head of the MDLL
1945 * @param tail pointer to the tail of the MDLL
1946 * @param element element to insert
1948 #define GNUNET_CONTAINER_MDLL_insert(mdll,head,tail,element) do { \
1949 GNUNET_assert ( ( (element)->prev_##mdll == NULL) && ((head) != (element))); \
1950 GNUNET_assert ( ( (element)->next_##mdll == NULL) && ((tail) != (element))); \
1951 (element)->next_##mdll = (head); \
1952 (element)->prev_##mdll = NULL; \
1953 if ((tail) == NULL) \
1956 (head)->prev_##mdll = element; \
1957 (head) = (element); } while (0)
1962 * Insert an element at the tail of a MDLL. Assumes that head, tail and
1963 * element are structs with prev and next fields.
1965 * @param mdll suffix name for the next and prev pointers in the element
1966 * @param head pointer to the head of the MDLL
1967 * @param tail pointer to the tail of the MDLL
1968 * @param element element to insert
1970 #define GNUNET_CONTAINER_MDLL_insert_tail(mdll,head,tail,element) do { \
1971 GNUNET_assert ( ( (element)->prev_##mdll == NULL) && ((head) != (element))); \
1972 GNUNET_assert ( ( (element)->next_##mdll == NULL) && ((tail) != (element))); \
1973 (element)->prev_##mdll = (tail); \
1974 (element)->next_##mdll = NULL; \
1975 if ((head) == NULL) \
1978 (tail)->next_##mdll = element; \
1979 (tail) = (element); } while (0)
1984 * Insert an element into a MDLL after the given other element. Insert
1985 * at the head if the other element is NULL.
1987 * @param mdll suffix name for the next and prev pointers in the element
1988 * @param head pointer to the head of the MDLL
1989 * @param tail pointer to the tail of the MDLL
1990 * @param other prior element, NULL for insertion at head of MDLL
1991 * @param element element to insert
1993 #define GNUNET_CONTAINER_MDLL_insert_after(mdll,head,tail,other,element) do { \
1994 GNUNET_assert ( ( (element)->prev_##mdll == NULL) && ((head) != (element))); \
1995 GNUNET_assert ( ( (element)->next_##mdll == NULL) && ((tail) != (element))); \
1996 (element)->prev_##mdll = (other); \
1997 if (NULL == other) \
1999 (element)->next_##mdll = (head); \
2000 (head) = (element); \
2004 (element)->next_##mdll = (other)->next_##mdll; \
2005 (other)->next_##mdll = (element); \
2007 if (NULL == (element)->next_##mdll) \
2008 (tail) = (element); \
2010 (element)->next->prev_##mdll = (element); } while (0)
2015 * Insert an element into a MDLL before the given other element. Insert
2016 * at the tail if the other element is NULL.
2018 * @param mdll suffix name for the next and prev pointers in the element
2019 * @param head pointer to the head of the MDLL
2020 * @param tail pointer to the tail of the MDLL
2021 * @param other prior element, NULL for insertion at head of MDLL
2022 * @param element element to insert
2024 #define GNUNET_CONTAINER_MDLL_insert_before(mdll,head,tail,other,element) do { \
2025 GNUNET_assert ( ( (element)->prev_##mdll == NULL) && ((head) != (element))); \
2026 GNUNET_assert ( ( (element)->next_##mdll == NULL) && ((tail) != (element))); \
2027 (element)->next_##mdll = (other); \
2028 if (NULL == other) \
2030 (element)->prev = (tail); \
2031 (tail) = (element); \
2035 (element)->prev_##mdll = (other)->prev_##mdll; \
2036 (other)->prev_##mdll = (element); \
2038 if (NULL == (element)->prev_##mdll) \
2039 (head) = (element); \
2041 (element)->prev_##mdll->next_##mdll = (element); } while (0)
2046 * Remove an element from a MDLL. Assumes
2047 * that head, tail and element are structs
2048 * with prev and next fields.
2050 * @param mdll suffix name for the next and prev pointers in the element
2051 * @param head pointer to the head of the MDLL
2052 * @param tail pointer to the tail of the MDLL
2053 * @param element element to remove
2055 #define GNUNET_CONTAINER_MDLL_remove(mdll,head,tail,element) do { \
2056 GNUNET_assert ( ( (element)->prev_##mdll != NULL) || ((head) == (element))); \
2057 GNUNET_assert ( ( (element)->next_##mdll != NULL) || ((tail) == (element))); \
2058 if ((element)->prev_##mdll == NULL) \
2059 (head) = (element)->next_##mdll; \
2061 (element)->prev_##mdll->next_##mdll = (element)->next_##mdll; \
2062 if ((element)->next_##mdll == NULL) \
2063 (tail) = (element)->prev_##mdll; \
2065 (element)->next_##mdll->prev_##mdll = (element)->prev_##mdll; \
2066 (element)->next_##mdll = NULL; \
2067 (element)->prev_##mdll = NULL; } while (0)
2072 * Insertion sort of @a element into DLL from @a head to @a tail
2073 * sorted by @a comparator.
2075 * @param TYPE element type of the elements, i.e. `struct ListElement`
2076 * @param comparator function like memcmp() to compare elements; takes
2077 * three arguments, the @a comparator_cls and two elements,
2078 * returns an `int` (-1, 0 or 1)
2079 * @param comparator_cls closure for @a comparator
2080 * @param[in,out] head head of DLL
2081 * @param[in,out] tail tail of DLL
2082 * @param element element to insert
2084 #define GNUNET_CONTAINER_DLL_insert_sorted(TYPE,comparator,comparator_cls,head,tail,element) do { \
2085 if ( (NULL == head) || \
2086 (0 < comparator (comparator_cls, \
2090 /* insert at head, element < head */ \
2091 GNUNET_CONTAINER_DLL_insert (head, \
2103 comparator (comparator_cls, \
2106 break; /* element < pos */ \
2107 if (NULL == pos) /* => element > tail */ \
2109 GNUNET_CONTAINER_DLL_insert_tail (head, \
2113 else /* prev < element < pos */ \
2115 GNUNET_CONTAINER_DLL_insert_after (head, \
2124 /* ******************** Heap *************** */
2129 * Cost by which elements in a heap can be ordered.
2131 typedef uint64_t GNUNET_CONTAINER_HeapCostType;
2136 * Heap type, either max or min.
2138 enum GNUNET_CONTAINER_HeapOrder
2142 * Heap with the maximum cost at the root.
2144 GNUNET_CONTAINER_HEAP_ORDER_MAX,
2148 * Heap with the minimum cost at the root.
2150 GNUNET_CONTAINER_HEAP_ORDER_MIN
2158 struct GNUNET_CONTAINER_Heap;
2163 * Handle to a node in a heap.
2165 struct GNUNET_CONTAINER_HeapNode;
2170 * Create a new heap.
2172 * @param order how should the heap be sorted?
2173 * @return handle to the heap
2175 struct GNUNET_CONTAINER_Heap *
2176 GNUNET_CONTAINER_heap_create (enum GNUNET_CONTAINER_HeapOrder order);
2181 * Destroys the heap. Only call on a heap that
2184 * @param heap heap to destroy
2187 GNUNET_CONTAINER_heap_destroy (struct GNUNET_CONTAINER_Heap *heap);
2192 * Get element stored at the root of @a heap.
2194 * @param heap Heap to inspect.
2195 * @return Element at the root, or NULL if heap is empty.
2198 GNUNET_CONTAINER_heap_peek (const struct GNUNET_CONTAINER_Heap *heap);
2202 * Get @a element and @a cost stored at the root of @a heap.
2204 * @param[in] heap Heap to inspect.
2205 * @param[out] element Root element is returned here.
2206 * @param[out] cost Cost of @a element is returned here.
2207 * @return #GNUNET_YES if an element is returned,
2208 * #GNUNET_NO if the heap is empty.
2211 GNUNET_CONTAINER_heap_peek2 (const struct GNUNET_CONTAINER_Heap *heap,
2213 GNUNET_CONTAINER_HeapCostType *cost);
2218 * Get the current size of the heap
2220 * @param heap the heap to get the size of
2221 * @return number of elements stored
2224 GNUNET_CONTAINER_heap_get_size (const struct GNUNET_CONTAINER_Heap *heap);
2229 * Get the current cost of the node
2231 * @param node the node to get the cost of
2232 * @return cost of the node
2234 GNUNET_CONTAINER_HeapCostType
2235 GNUNET_CONTAINER_heap_node_get_cost (const struct GNUNET_CONTAINER_HeapNode *node);
2242 * @param cls closure
2243 * @param node internal node of the heap
2244 * @param element value stored at the node
2245 * @param cost cost associated with the node
2246 * @return #GNUNET_YES if we should continue to iterate,
2247 * #GNUNET_NO if not.
2250 (*GNUNET_CONTAINER_HeapIterator) (void *cls,
2251 struct GNUNET_CONTAINER_HeapNode *node,
2253 GNUNET_CONTAINER_HeapCostType cost);
2258 * Iterate over all entries in the heap.
2260 * @param heap the heap
2261 * @param iterator function to call on each entry
2262 * @param iterator_cls closure for @a iterator
2265 GNUNET_CONTAINER_heap_iterate (const struct GNUNET_CONTAINER_Heap *heap,
2266 GNUNET_CONTAINER_HeapIterator iterator,
2267 void *iterator_cls);
2271 * Perform a random walk of the tree. The walk is biased
2272 * towards elements closer to the root of the tree (since
2273 * each walk starts at the root and ends at a random leaf).
2274 * The heap internally tracks the current position of the
2277 * @param heap heap to walk
2278 * @return data stored at the next random node in the walk;
2279 * NULL if the tree is empty.
2282 GNUNET_CONTAINER_heap_walk_get_next (struct GNUNET_CONTAINER_Heap *heap);
2287 * Inserts a new element into the heap.
2289 * @param heap heap to modify
2290 * @param element element to insert
2291 * @param cost cost for the element
2292 * @return node for the new element
2294 struct GNUNET_CONTAINER_HeapNode *
2295 GNUNET_CONTAINER_heap_insert (struct GNUNET_CONTAINER_Heap *heap,
2297 GNUNET_CONTAINER_HeapCostType cost);
2302 * Remove root of the heap.
2304 * @param heap heap to modify
2305 * @return element data stored at the root node
2308 GNUNET_CONTAINER_heap_remove_root (struct GNUNET_CONTAINER_Heap *heap);
2313 * Removes a node from the heap.
2315 * @param node node to remove
2316 * @return element data stored at the node, NULL if heap is empty
2319 GNUNET_CONTAINER_heap_remove_node (struct GNUNET_CONTAINER_HeapNode *node);
2324 * Updates the cost of any node in the tree
2326 * @param node node for which the cost is to be changed
2327 * @param new_cost new cost for the node
2330 GNUNET_CONTAINER_heap_update_cost (struct GNUNET_CONTAINER_HeapNode *node,
2331 GNUNET_CONTAINER_HeapCostType new_cost);
2334 #if 0 /* keep Emacsens' auto-indent happy */
2342 /* ifndef GNUNET_CONTAINER_LIB_H */
2344 /* end of gnunet_container_lib.h */