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
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 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 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
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,
94 #include <extractor.h>
98 /* definitions from extractor.h we need for the build */
101 * Enumeration defining various sources of keywords. See also
102 * http://dublincore.org/documents/1998/09/dces/
104 enum EXTRACTOR_MetaType {
105 EXTRACTOR_METATYPE_RESERVED = 0,
106 EXTRACTOR_METATYPE_MIMETYPE = 1,
107 EXTRACTOR_METATYPE_FILENAME = 2,
108 EXTRACTOR_METATYPE_COMMENT = 3,
109 EXTRACTOR_METATYPE_TITLE = 4,
110 EXTRACTOR_METATYPE_BOOK_TITLE = 5,
111 EXTRACTOR_METATYPE_JOURNAL_NAME = 8,
112 EXTRACTOR_METATYPE_AUTHOR_NAME = 13,
113 EXTRACTOR_METATYPE_PUBLICATION_DATE = 24,
114 EXTRACTOR_METATYPE_URL = 29,
115 EXTRACTOR_METATYPE_URI = 30,
116 EXTRACTOR_METATYPE_ISRC = 31,
117 EXTRACTOR_METATYPE_UNKNOWN = 45,
118 EXTRACTOR_METATYPE_DESCRIPTION = 46,
119 EXTRACTOR_METATYPE_KEYWORDS = 49,
120 EXTRACTOR_METATYPE_SUBJECT = 52,
121 EXTRACTOR_METATYPE_PACKAGE_NAME = 69,
122 EXTRACTOR_METATYPE_THUMBNAIL = 114,
123 EXTRACTOR_METATYPE_ALBUM = 129,
124 EXTRACTOR_METATYPE_ARTIST = 130,
125 EXTRACTOR_METATYPE_ORIGINAL_TITLE = 162,
126 EXTRACTOR_METATYPE_GNUNET_FULL_DATA = 174,
127 EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME = 180,
132 * Format in which the extracted meta data is presented.
134 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
177 (*EXTRACTOR_MetaDataProcessor) (void *cls,
178 const char *plugin_name,
179 enum EXTRACTOR_MetaType type,
180 enum EXTRACTOR_MetaFormat format,
181 const char *data_mime_type,
187 #ifndef EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME
188 /* hack for LE < 0.6.3 */
189 #define EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME 180
195 #if 0 /* keep Emacsens' auto-indent happy */
201 /* ******************* bloomfilter ***************** */
204 * @brief bloomfilter representation (opaque)
205 * @ingroup bloomfilter
207 struct GNUNET_CONTAINER_BloomFilter;
211 * @ingroup bloomfilter
212 * Iterator over `struct GNUNET_HashCode`.
215 * @param next set to the next hash code
216 * @return #GNUNET_YES if next was updated
217 * #GNUNET_NO if there are no more entries
220 (*GNUNET_CONTAINER_HashCodeIterator) (void *cls,
221 struct GNUNET_HashCode *next);
225 * @ingroup bloomfilter
226 * Load a Bloom filter from a file.
228 * @param filename the name of the file (or the prefix)
229 * @param size the size of the bloom-filter (number of
230 * bytes of storage space to use); will be rounded up
232 * @param k the number of #GNUNET_CRYPTO_hash-functions to apply per
233 * element (number of bits set per element in the set)
234 * @return the bloomfilter
236 struct GNUNET_CONTAINER_BloomFilter *
237 GNUNET_CONTAINER_bloomfilter_load (const char *filename,
243 * @ingroup bloomfilter
244 * Create a Bloom filter from raw bits.
246 * @param data the raw bits in memory (maybe NULL,
247 * in which case all bits should be considered
249 * @param size the size of the bloom-filter (number of
250 * bytes of storage space to use); also size of @a data
251 * -- unless data is NULL. Must be a power of 2.
252 * @param k the number of #GNUNET_CRYPTO_hash-functions to apply per
253 * element (number of bits set per element in the set)
254 * @return the bloomfilter
256 struct GNUNET_CONTAINER_BloomFilter *
257 GNUNET_CONTAINER_bloomfilter_init (const char *data,
263 * @ingroup bloomfilter
264 * Copy the raw data of this Bloom filter into
265 * the given data array.
267 * @param data where to write the data
268 * @param size the size of the given @a data array
269 * @return #GNUNET_SYSERR if the data array of the wrong size
272 GNUNET_CONTAINER_bloomfilter_get_raw_data (const struct GNUNET_CONTAINER_BloomFilter *bf,
278 * @ingroup bloomfilter
279 * Test if an element is in the filter.
281 * @param e the element
282 * @param bf the filter
283 * @return #GNUNET_YES if the element is in the filter, #GNUNET_NO if not
286 GNUNET_CONTAINER_bloomfilter_test (const struct GNUNET_CONTAINER_BloomFilter *bf,
287 const struct GNUNET_HashCode *e);
291 * @ingroup bloomfilter
292 * Add an element to the filter.
294 * @param bf the filter
295 * @param e the element
298 GNUNET_CONTAINER_bloomfilter_add (struct GNUNET_CONTAINER_BloomFilter *bf,
299 const struct GNUNET_HashCode *e);
303 * @ingroup bloomfilter
304 * Remove an element from the filter.
306 * @param bf the filter
307 * @param e the element to remove
310 GNUNET_CONTAINER_bloomfilter_remove (struct GNUNET_CONTAINER_BloomFilter *bf,
311 const struct GNUNET_HashCode *e);
315 * @ingroup bloomfilter
316 * Create a copy of a bloomfilter.
318 * @param bf the filter
321 struct GNUNET_CONTAINER_BloomFilter *
322 GNUNET_CONTAINER_bloomfilter_copy (const struct GNUNET_CONTAINER_BloomFilter *bf);
327 * @ingroup bloomfilter
328 * Free the space associcated with a filter
329 * in memory, flush to drive if needed (do not
330 * free the space on the drive).
332 * @param bf the filter
335 GNUNET_CONTAINER_bloomfilter_free (struct GNUNET_CONTAINER_BloomFilter *bf);
339 * Get the number of the addresses set per element in the bloom filter.
341 * @param bf the filter
342 * @return addresses set per element in the bf
345 GNUNET_CONTAINER_bloomfilter_get_element_addresses (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 (const struct GNUNET_CONTAINER_BloomFilter *bf);
360 * @ingroup bloomfilter
361 * Reset a Bloom filter to empty.
363 * @param bf the filter
366 GNUNET_CONTAINER_bloomfilter_clear (struct GNUNET_CONTAINER_BloomFilter *bf);
370 * @ingroup bloomfilter
371 * "or" the entries of the given raw data array with the
372 * data of the given Bloom filter. Assumes that
373 * the @a size of the @a data array and the current filter
376 * @param bf the filter
377 * @param data data to OR-in
378 * @param size size of @a data
379 * @return #GNUNET_OK on success
382 GNUNET_CONTAINER_bloomfilter_or (struct GNUNET_CONTAINER_BloomFilter *bf,
383 const char *data, size_t size);
387 * @ingroup bloomfilter
388 * "or" the entries of the given raw data array with the
389 * data of the given Bloom filter. Assumes that
390 * the size of the two filters matches.
392 * @param bf the filter
393 * @param to_or the bloomfilter to or-in
394 * @return #GNUNET_OK on success
397 GNUNET_CONTAINER_bloomfilter_or2 (struct GNUNET_CONTAINER_BloomFilter *bf,
398 const struct GNUNET_CONTAINER_BloomFilter *to_or);
402 * @ingroup bloomfilter
403 * Resize a bloom filter. Note that this operation
404 * is pretty costly. Essentially, the Bloom filter
405 * needs to be completely re-build.
407 * @param bf the filter
408 * @param iterator an iterator over all elements stored in the BF
409 * @param iterator_cls closure for @a iterator
410 * @param size the new size for the filter
411 * @param k the new number of #GNUNET_CRYPTO_hash-function to apply per element
414 GNUNET_CONTAINER_bloomfilter_resize (struct GNUNET_CONTAINER_BloomFilter *bf,
415 GNUNET_CONTAINER_HashCodeIterator iterator,
421 /* ****************** metadata ******************* */
425 * Meta data to associate with a file, directory or namespace.
427 struct GNUNET_CONTAINER_MetaData;
432 * Create a fresh meta data container.
434 * @return empty meta-data container
436 struct GNUNET_CONTAINER_MetaData *
437 GNUNET_CONTAINER_meta_data_create (void);
442 * Duplicate a MetaData token.
444 * @param md what to duplicate
445 * @return duplicate meta-data container
447 struct GNUNET_CONTAINER_MetaData *
448 GNUNET_CONTAINER_meta_data_duplicate (const struct GNUNET_CONTAINER_MetaData *md);
455 * @param md what to free
458 GNUNET_CONTAINER_meta_data_destroy (struct GNUNET_CONTAINER_MetaData *md);
463 * Test if two MDs are equal. We consider them equal if
464 * the meta types, formats and content match (we do not
465 * include the mime types and plugins names in this
468 * @param md1 first value to check
469 * @param md2 other value to check
470 * @return #GNUNET_YES if they are equal
473 GNUNET_CONTAINER_meta_data_test_equal (const struct GNUNET_CONTAINER_MetaData *md1,
474 const struct GNUNET_CONTAINER_MetaData *md2);
481 * @param md metadata to extend
482 * @param plugin_name name of the plugin that produced this value;
483 * special values can be used (i.e. '<zlib>' for zlib being
484 * used in the main libextractor library and yielding
486 * @param type libextractor-type describing the meta data
487 * @param format basic format information about data
488 * @param data_mime_type mime-type of data (not of the original file);
489 * can be NULL (if mime-type is not known)
490 * @param data actual meta-data found
491 * @param data_size number of bytes in data
492 * @return #GNUNET_OK on success, #GNUNET_SYSERR if this entry already exists
493 * data_mime_type and plugin_name are not considered for "exists" checks
496 GNUNET_CONTAINER_meta_data_insert (struct GNUNET_CONTAINER_MetaData *md,
497 const char *plugin_name,
498 enum EXTRACTOR_MetaType type,
499 enum EXTRACTOR_MetaFormat format,
500 const char *data_mime_type,
507 * Extend metadata. Merges the meta data from the second argument
508 * into the first, discarding duplicate key-value pairs.
510 * @param md metadata to extend
511 * @param in metadata to merge
514 GNUNET_CONTAINER_meta_data_merge (struct GNUNET_CONTAINER_MetaData *md,
515 const struct GNUNET_CONTAINER_MetaData *in);
522 * @param md metadata to manipulate
523 * @param type type of the item to remove
524 * @param data specific value to remove, NULL to remove all
525 * entries of the given type
526 * @param data_size number of bytes in data
527 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the item does not exist in md
530 GNUNET_CONTAINER_meta_data_delete (struct GNUNET_CONTAINER_MetaData *md,
531 enum EXTRACTOR_MetaType type,
538 * Remove all items in the container.
540 * @param md metadata to manipulate
543 GNUNET_CONTAINER_meta_data_clear (struct GNUNET_CONTAINER_MetaData *md);
548 * Add the current time as the publication date
551 * @param md metadata to modify
554 GNUNET_CONTAINER_meta_data_add_publication_date (struct GNUNET_CONTAINER_MetaData *md);
559 * Iterate over MD entries.
561 * @param md metadata to inspect
562 * @param iter function to call on each entry, return 0 to continue to iterate
563 * and 1 to abort iteration in this function (GNU libextractor API!)
564 * @param iter_cls closure for @a iter
565 * @return number of entries
568 GNUNET_CONTAINER_meta_data_iterate (const struct GNUNET_CONTAINER_MetaData *md,
569 EXTRACTOR_MetaDataProcessor iter,
575 * Get the first MD entry of the given type. Caller
576 * is responsible for freeing the return value.
577 * Also, only meta data items that are strings (0-terminated)
578 * are returned by this function.
580 * @param md metadata to inspect
581 * @param type type to look for
582 * @return NULL if no entry was found
585 GNUNET_CONTAINER_meta_data_get_by_type (const struct GNUNET_CONTAINER_MetaData *md,
586 enum EXTRACTOR_MetaType type);
591 * Get the first matching MD entry of the given types. Caller is
592 * responsible for freeing the return value. Also, only meta data
593 * items that are strings (0-terminated) are returned by this
596 * @param md metadata to inspect
597 * @param ... -1-terminated list of types
598 * @return NULL if we do not have any such entry,
599 * otherwise client is responsible for freeing the value!
602 GNUNET_CONTAINER_meta_data_get_first_by_types (const struct GNUNET_CONTAINER_MetaData *md,
607 * Get a thumbnail from the meta-data (if present). Only matches meta
608 * data with mime type "image" and binary format.
610 * @param md metadata to inspect
611 * @param thumb will be set to the thumbnail data. Must be
612 * freed by the caller!
613 * @return number of bytes in thumbnail, 0 if not available
616 GNUNET_CONTAINER_meta_data_get_thumbnail (const struct GNUNET_CONTAINER_MetaData *md,
617 unsigned char **thumb);
623 * Options for metadata serialization.
625 enum GNUNET_CONTAINER_MetaDataSerializationOptions
629 * Serialize all of the data.
631 GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL = 0,
635 * If not enough space is available, it is acceptable
636 * to only serialize some of the metadata.
638 GNUNET_CONTAINER_META_DATA_SERIALIZE_PART = 1,
642 * Speed is of the essence, do not allow compression.
644 GNUNET_CONTAINER_META_DATA_SERIALIZE_NO_COMPRESS = 2
650 * Serialize meta-data to target.
652 * @param md metadata to serialize
653 * @param target where to write the serialized metadata;
654 * *target can be NULL, in which case memory is allocated
655 * @param max maximum number of bytes available
656 * @param opt is it ok to just write SOME of the
657 * meta-data to match the size constraint,
658 * possibly discarding some data?
659 * @return number of bytes written on success,
660 * -1 on error (typically: not enough
664 GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData *md,
667 enum GNUNET_CONTAINER_MetaDataSerializationOptions opt);
672 * Get the size of the full meta-data in serialized form.
674 * @param md metadata to inspect
675 * @return number of bytes needed for serialization, -1 on error
678 GNUNET_CONTAINER_meta_data_get_serialized_size (const struct GNUNET_CONTAINER_MetaData *md);
683 * Deserialize meta-data. Initializes md.
685 * @param input serialized meta-data.
686 * @param size number of bytes available
687 * @return MD on success, NULL on error (i.e.
690 struct GNUNET_CONTAINER_MetaData *
691 GNUNET_CONTAINER_meta_data_deserialize (const char *input,
695 /* ******************************* HashMap **************************** */
699 * Opaque handle for a HashMap.
701 struct GNUNET_CONTAINER_MultiHashMap;
705 * Opaque handle to an iterator over
708 struct GNUNET_CONTAINER_MultiHashMapIterator;
712 * Options for storing values in the HashMap.
714 enum GNUNET_CONTAINER_MultiHashMapOption
719 * If a value with the given key exists, replace it. Note that the
720 * old value would NOT be freed by replace (the application has to
721 * make sure that this happens if required).
723 GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE,
727 * Allow multiple values with the same key.
729 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE,
733 * There must only be one value per key; storing a value should fail
734 * if a value under the same key already exists.
736 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY,
739 * @ingroup hashmap There must only be one value per key, but don't
740 * bother checking if a value already exists (faster than
741 * #GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY; implemented
742 * just like #GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE but this
743 * option documents better what is intended if
744 * #GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY is what is
747 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST
753 * Iterator over hash map entries.
756 * @param key current key code
757 * @param value value in the hash map
758 * @return #GNUNET_YES if we should continue to
763 (*GNUNET_CONTAINER_HashMapIterator) (void *cls,
764 const struct GNUNET_HashCode *key,
770 * Create a multi hash map.
772 * @param len initial size (map will grow as needed)
773 * @param do_not_copy_keys #GNUNET_NO is always safe and should be used by default;
774 * #GNUNET_YES means that on 'put', the 'key' does not have
775 * to be copied as the destination of the pointer is
776 * guaranteed to be life as long as the value is stored in
777 * the hashmap. This can significantly reduce memory
778 * consumption, but of course is also a recipie for
779 * heap corruption if the assumption is not true. Only
780 * use this if (1) memory use is important in this case and
781 * (2) you have triple-checked that the invariant holds
782 * @return NULL on error
784 struct GNUNET_CONTAINER_MultiHashMap *
785 GNUNET_CONTAINER_multihashmap_create (unsigned int len,
786 int do_not_copy_keys);
791 * Destroy a hash map. Will not free any values
792 * stored in the hash map!
797 GNUNET_CONTAINER_multihashmap_destroy (struct GNUNET_CONTAINER_MultiHashMap *map);
802 * Given a key find a value in the map matching the key.
805 * @param key what to look for
806 * @return NULL if no value was found; note that
807 * this is indistinguishable from values that just
808 * happen to be NULL; use "contains" to test for
809 * key-value pairs with value NULL
812 GNUNET_CONTAINER_multihashmap_get (const struct GNUNET_CONTAINER_MultiHashMap *map,
813 const struct GNUNET_HashCode *key);
818 * Remove the given key-value pair from the map. Note that if the
819 * key-value pair is in the map multiple times, only one of the pairs
823 * @param key key of the key-value pair
824 * @param value value of the key-value pair
825 * @return #GNUNET_YES on success, #GNUNET_NO if the key-value pair
829 GNUNET_CONTAINER_multihashmap_remove (struct GNUNET_CONTAINER_MultiHashMap *map,
830 const struct GNUNET_HashCode *key,
835 * Remove all entries for the given key from the map.
836 * Note that the values would not be "freed".
839 * @param key identifies values to be removed
840 * @return number of values removed
843 GNUNET_CONTAINER_multihashmap_remove_all (struct GNUNET_CONTAINER_MultiHashMap *map,
844 const struct GNUNET_HashCode *key);
849 * Remove all entries from the map.
850 * Note that the values would not be "freed".
853 * @return number of values removed
856 GNUNET_CONTAINER_multihashmap_clear (struct GNUNET_CONTAINER_MultiHashMap *map);
861 * Check if the map contains any value under the given
862 * key (including values that are NULL).
865 * @param key the key to test if a value exists for it
866 * @return #GNUNET_YES if such a value exists,
870 GNUNET_CONTAINER_multihashmap_contains (const struct GNUNET_CONTAINER_MultiHashMap *map,
871 const struct GNUNET_HashCode * key);
876 * Check if the map contains the given value under the given
880 * @param key the key to test if a value exists for it
881 * @param value value to test for
882 * @return #GNUNET_YES if such a value exists,
886 GNUNET_CONTAINER_multihashmap_contains_value (const struct GNUNET_CONTAINER_MultiHashMap *map,
887 const struct GNUNET_HashCode *key,
893 * Store a key-value pair in the map.
896 * @param key key to use
897 * @param value value to use
898 * @param opt options for put
899 * @return #GNUNET_OK on success,
900 * #GNUNET_NO if a value was replaced (with REPLACE)
901 * #GNUNET_SYSERR if #GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY was the option and the
902 * value already exists
905 GNUNET_CONTAINER_multihashmap_put (struct GNUNET_CONTAINER_MultiHashMap *map,
906 const struct GNUNET_HashCode *key,
908 enum GNUNET_CONTAINER_MultiHashMapOption
913 * Get the number of key-value pairs in the map.
916 * @return the number of key value pairs
919 GNUNET_CONTAINER_multihashmap_size (const struct GNUNET_CONTAINER_MultiHashMap *map);
924 * Iterate over all entries in the map.
927 * @param it function to call on each entry
928 * @param it_cls extra argument to @a it
929 * @return the number of key value pairs processed,
930 * #GNUNET_SYSERR if it aborted iteration
933 GNUNET_CONTAINER_multihashmap_iterate (const struct GNUNET_CONTAINER_MultiHashMap *map,
934 GNUNET_CONTAINER_HashMapIterator it,
940 * Create an iterator for a multihashmap.
941 * The iterator can be used to retrieve all the elements in the multihashmap
942 * one by one, without having to handle all elements at once (in contrast to
943 * #GNUNET_CONTAINER_multihashmap_iterate). Note that the iterator can not be
944 * used anymore if elements have been removed from 'map' after the creation of
945 * the iterator, or 'map' has been destroyed. Adding elements to 'map' may
946 * result in skipped or repeated elements.
948 * @param map the map to create an iterator for
949 * @return an iterator over the given multihashmap @a map
951 struct GNUNET_CONTAINER_MultiHashMapIterator *
952 GNUNET_CONTAINER_multihashmap_iterator_create (const struct GNUNET_CONTAINER_MultiHashMap *map);
957 * Retrieve the next element from the hash map at the iterator's
958 * position. If there are no elements left, #GNUNET_NO is returned,
959 * and @a key and @a value are not modified. This operation is only
960 * allowed if no elements have been removed from the multihashmap
961 * since the creation of @a iter, and the map has not been destroyed.
962 * Adding elements may result in repeating or skipping elements.
964 * @param iter the iterator to get the next element from
965 * @param key pointer to store the key in, can be NULL
966 * @param value pointer to store the value in, can be NULL
967 * @return #GNUNET_YES we returned an element,
968 * #GNUNET_NO if we are out of elements
971 GNUNET_CONTAINER_multihashmap_iterator_next (struct GNUNET_CONTAINER_MultiHashMapIterator *iter,
972 struct GNUNET_HashCode *key,
978 * Destroy a multihashmap iterator.
980 * @param iter the iterator to destroy
983 GNUNET_CONTAINER_multihashmap_iterator_destroy (struct GNUNET_CONTAINER_MultiHashMapIterator *iter);
988 * Iterate over all entries in the map that match a particular key.
991 * @param key key that the entries must correspond to
992 * @param it function to call on each entry
993 * @param it_cls extra argument to @a it
994 * @return the number of key value pairs processed,
995 * #GNUNET_SYSERR if it aborted iteration
998 GNUNET_CONTAINER_multihashmap_get_multiple (const struct GNUNET_CONTAINER_MultiHashMap *map,
999 const struct GNUNET_HashCode *key,
1000 GNUNET_CONTAINER_HashMapIterator it,
1006 * Call @a it on a random value from the map, or not at all
1007 * if the map is empty. Note that this function has linear
1008 * complexity (in the size of the map).
1010 * @param map the map
1011 * @param it function to call on a random entry
1012 * @param it_cls extra argument to @a it
1013 * @return the number of key value pairs processed, zero or one.
1016 GNUNET_CONTAINER_multihashmap_get_random (const struct GNUNET_CONTAINER_MultiHashMap *map,
1017 GNUNET_CONTAINER_HashMapIterator it,
1021 /* ***************** Version of Multihashmap for peer identities ****************** */
1025 * Iterator over hash map entries.
1027 * @param cls closure
1028 * @param key current public key
1029 * @param value value in the hash map
1030 * @return #GNUNET_YES if we should continue to
1032 * #GNUNET_NO if not.
1035 (*GNUNET_CONTAINER_PeerMapIterator) (void *cls,
1036 const struct GNUNET_PeerIdentity *key,
1041 * Hash map from peer identities to values.
1043 struct GNUNET_CONTAINER_MultiPeerMap;
1048 * Create a multi peer map (hash map for public keys of peers).
1050 * @param len initial size (map will grow as needed)
1051 * @param do_not_copy_keys #GNUNET_NO is always safe and should be used by default;
1052 * #GNUNET_YES means that on 'put', the 'key' does not have
1053 * to be copied as the destination of the pointer is
1054 * guaranteed to be life as long as the value is stored in
1055 * the hashmap. This can significantly reduce memory
1056 * consumption, but of course is also a recipie for
1057 * heap corruption if the assumption is not true. Only
1058 * use this if (1) memory use is important in this case and
1059 * (2) you have triple-checked that the invariant holds
1060 * @return NULL on error
1062 struct GNUNET_CONTAINER_MultiPeerMap *
1063 GNUNET_CONTAINER_multipeermap_create (unsigned int len,
1064 int do_not_copy_keys);
1069 * Destroy a hash map. Will not free any values
1070 * stored in the hash map!
1072 * @param map the map
1075 GNUNET_CONTAINER_multipeermap_destroy (struct GNUNET_CONTAINER_MultiPeerMap *map);
1080 * Given a key find a value in the map matching the key.
1082 * @param map the map
1083 * @param key what to look for
1084 * @return NULL if no value was found; note that
1085 * this is indistinguishable from values that just
1086 * happen to be NULL; use "contains" to test for
1087 * key-value pairs with value NULL
1090 GNUNET_CONTAINER_multipeermap_get (const struct GNUNET_CONTAINER_MultiPeerMap *map,
1091 const struct GNUNET_PeerIdentity *key);
1096 * Remove the given key-value pair from the map. Note that if the
1097 * key-value pair is in the map multiple times, only one of the pairs
1100 * @param map the map
1101 * @param key key of the key-value pair
1102 * @param value value of the key-value pair
1103 * @return #GNUNET_YES on success, #GNUNET_NO if the key-value pair
1107 GNUNET_CONTAINER_multipeermap_remove (struct GNUNET_CONTAINER_MultiPeerMap *map,
1108 const struct GNUNET_PeerIdentity * key,
1113 * Remove all entries for the given key from the map.
1114 * Note that the values would not be "freed".
1116 * @param map the map
1117 * @param key identifies values to be removed
1118 * @return number of values removed
1121 GNUNET_CONTAINER_multipeermap_remove_all (struct GNUNET_CONTAINER_MultiPeerMap *map,
1122 const struct GNUNET_PeerIdentity *key);
1127 * Check if the map contains any value under the given
1128 * key (including values that are NULL).
1130 * @param map the map
1131 * @param key the key to test if a value exists for it
1132 * @return #GNUNET_YES if such a value exists,
1136 GNUNET_CONTAINER_multipeermap_contains (const struct GNUNET_CONTAINER_MultiPeerMap *map,
1137 const struct GNUNET_PeerIdentity *key);
1142 * Check if the map contains the given value under the given
1145 * @param map the map
1146 * @param key the key to test if a value exists for it
1147 * @param value value to test for
1148 * @return #GNUNET_YES if such a value exists,
1152 GNUNET_CONTAINER_multipeermap_contains_value (const struct GNUNET_CONTAINER_MultiPeerMap *map,
1153 const struct GNUNET_PeerIdentity * key,
1159 * Store a key-value pair in the map.
1161 * @param map the map
1162 * @param key key to use
1163 * @param value value to use
1164 * @param opt options for put
1165 * @return #GNUNET_OK on success,
1166 * #GNUNET_NO if a value was replaced (with REPLACE)
1167 * #GNUNET_SYSERR if #GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY was the option and the
1168 * value already exists
1171 GNUNET_CONTAINER_multipeermap_put (struct GNUNET_CONTAINER_MultiPeerMap *map,
1172 const struct GNUNET_PeerIdentity *key,
1174 enum GNUNET_CONTAINER_MultiHashMapOption opt);
1179 * Get the number of key-value pairs in the map.
1181 * @param map the map
1182 * @return the number of key value pairs
1185 GNUNET_CONTAINER_multipeermap_size (const struct GNUNET_CONTAINER_MultiPeerMap *map);
1190 * Iterate over all entries in the map.
1192 * @param map the map
1193 * @param it function to call on each entry
1194 * @param it_cls extra argument to @a it
1195 * @return the number of key value pairs processed,
1196 * #GNUNET_SYSERR if it aborted iteration
1199 GNUNET_CONTAINER_multipeermap_iterate (const struct GNUNET_CONTAINER_MultiPeerMap *map,
1200 GNUNET_CONTAINER_PeerMapIterator it,
1204 struct GNUNET_CONTAINER_MultiPeerMapIterator;
1207 * Create an iterator for a multihashmap.
1208 * The iterator can be used to retrieve all the elements in the multihashmap
1209 * one by one, without having to handle all elements at once (in contrast to
1210 * #GNUNET_CONTAINER_multipeermap_iterate). Note that the iterator can not be
1211 * used anymore if elements have been removed from @a map after the creation of
1212 * the iterator, or 'map' has been destroyed. Adding elements to @a map may
1213 * result in skipped or repeated elements.
1215 * @param map the map to create an iterator for
1216 * @return an iterator over the given multihashmap @a map
1218 struct GNUNET_CONTAINER_MultiPeerMapIterator *
1219 GNUNET_CONTAINER_multipeermap_iterator_create (const struct GNUNET_CONTAINER_MultiPeerMap *map);
1224 * Retrieve the next element from the hash map at the iterator's
1225 * position. If there are no elements left, #GNUNET_NO is returned,
1226 * and @a key and @a value are not modified. This operation is only
1227 * allowed if no elements have been removed from the multihashmap
1228 * since the creation of @a iter, and the map has not been destroyed.
1229 * Adding elements may result in repeating or skipping elements.
1231 * @param iter the iterator to get the next element from
1232 * @param key pointer to store the key in, can be NULL
1233 * @param value pointer to store the value in, can be NULL
1234 * @return #GNUNET_YES we returned an element,
1235 * #GNUNET_NO if we are out of elements
1238 GNUNET_CONTAINER_multipeermap_iterator_next (struct GNUNET_CONTAINER_MultiPeerMapIterator *iter,
1239 struct GNUNET_PeerIdentity *key,
1240 const void **value);
1245 * Destroy a multipeermap iterator.
1247 * @param iter the iterator to destroy
1250 GNUNET_CONTAINER_multipeermap_iterator_destroy (struct GNUNET_CONTAINER_MultiPeerMapIterator *iter);
1255 * Iterate over all entries in the map that match a particular key.
1257 * @param map the map
1258 * @param key public key that the entries must correspond to
1259 * @param it function to call on each entry
1260 * @param it_cls extra argument to @a it
1261 * @return the number of key value pairs processed,
1262 * #GNUNET_SYSERR if it aborted iteration
1265 GNUNET_CONTAINER_multipeermap_get_multiple (const struct GNUNET_CONTAINER_MultiPeerMap *map,
1266 const struct GNUNET_PeerIdentity *key,
1267 GNUNET_CONTAINER_PeerMapIterator it,
1273 * Call @a it on a random value from the map, or not at all
1274 * if the map is empty. Note that this function has linear
1275 * complexity (in the size of the map).
1277 * @param map the map
1278 * @param it function to call on a random entry
1279 * @param it_cls extra argument to @a it
1280 * @return the number of key value pairs processed, zero or one.
1283 GNUNET_CONTAINER_multipeermap_get_random (const struct GNUNET_CONTAINER_MultiPeerMap *map,
1284 GNUNET_CONTAINER_PeerMapIterator it,
1288 /* Version of multihashmap with 32 bit keys */
1292 * Opaque handle for the 32-bit key HashMap.
1294 struct GNUNET_CONTAINER_MultiHashMap32;
1299 * Opaque handle to an iterator over
1300 * a 32-bit key multihashmap.
1302 struct GNUNET_CONTAINER_MultiHashMap32Iterator;
1307 * Iterator over hash map entries.
1309 * @param cls closure
1310 * @param key current key code
1311 * @param value value in the hash map
1312 * @return #GNUNET_YES if we should continue to
1314 * #GNUNET_NO if not.
1316 typedef int (*GNUNET_CONTAINER_HashMapIterator32) (void *cls,
1323 * Create a 32-bit key multi hash map.
1325 * @param len initial size (map will grow as needed)
1326 * @return NULL on error
1328 struct GNUNET_CONTAINER_MultiHashMap32 *
1329 GNUNET_CONTAINER_multihashmap32_create (unsigned int len);
1334 * Destroy a 32-bit key hash map. Will not free any values
1335 * stored in the hash map!
1337 * @param map the map
1340 GNUNET_CONTAINER_multihashmap32_destroy (struct GNUNET_CONTAINER_MultiHashMap32
1346 * Get the number of key-value pairs in the map.
1348 * @param map the map
1349 * @return the number of key value pairs
1352 GNUNET_CONTAINER_multihashmap32_size (const struct
1353 GNUNET_CONTAINER_MultiHashMap32 *map);
1358 * Given a key find a value in the map matching the key.
1360 * @param map the map
1361 * @param key what to look for
1362 * @return NULL if no value was found; note that
1363 * this is indistinguishable from values that just
1364 * happen to be NULL; use "contains" to test for
1365 * key-value pairs with value NULL
1368 GNUNET_CONTAINER_multihashmap32_get (const struct
1369 GNUNET_CONTAINER_MultiHashMap32 *map,
1375 * Iterate over all entries in the map.
1377 * @param map the map
1378 * @param it function to call on each entry
1379 * @param it_cls extra argument to @a it
1380 * @return the number of key value pairs processed,
1381 * #GNUNET_SYSERR if it aborted iteration
1384 GNUNET_CONTAINER_multihashmap32_iterate (const struct
1385 GNUNET_CONTAINER_MultiHashMap32 *map,
1386 GNUNET_CONTAINER_HashMapIterator32 it,
1392 * Remove the given key-value pair from the map. Note that if the
1393 * key-value pair is in the map multiple times, only one of the pairs
1396 * @param map the map
1397 * @param key key of the key-value pair
1398 * @param value value of the key-value pair
1399 * @return #GNUNET_YES on success, #GNUNET_NO if the key-value pair
1403 GNUNET_CONTAINER_multihashmap32_remove (struct GNUNET_CONTAINER_MultiHashMap32 *map,
1410 * Remove all entries for the given key from the map.
1411 * Note that the values would not be "freed".
1413 * @param map the map
1414 * @param key identifies values to be removed
1415 * @return number of values removed
1418 GNUNET_CONTAINER_multihashmap32_remove_all (struct GNUNET_CONTAINER_MultiHashMap32 *map,
1424 * Check if the map contains any value under the given
1425 * key (including values that are NULL).
1427 * @param map the map
1428 * @param key the key to test if a value exists for it
1429 * @return #GNUNET_YES if such a value exists,
1433 GNUNET_CONTAINER_multihashmap32_contains (const struct GNUNET_CONTAINER_MultiHashMap32 *map,
1439 * Check if the map contains the given value under the given
1442 * @param map the map
1443 * @param key the key to test if a value exists for it
1444 * @param value value to test for
1445 * @return #GNUNET_YES if such a value exists,
1449 GNUNET_CONTAINER_multihashmap32_contains_value (const struct GNUNET_CONTAINER_MultiHashMap32 *map,
1456 * Store a key-value pair in the map.
1458 * @param map the map
1459 * @param key key to use
1460 * @param value value to use
1461 * @param opt options for put
1462 * @return #GNUNET_OK on success,
1463 * #GNUNET_NO if a value was replaced (with REPLACE)
1464 * #GNUNET_SYSERR if #GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY was the option and the
1465 * value already exists
1468 GNUNET_CONTAINER_multihashmap32_put (struct GNUNET_CONTAINER_MultiHashMap32 *map,
1471 enum GNUNET_CONTAINER_MultiHashMapOption opt);
1476 * Iterate over all entries in the map that match a particular key.
1478 * @param map the map
1479 * @param key key that the entries must correspond to
1480 * @param it function to call on each entry
1481 * @param it_cls extra argument to @a it
1482 * @return the number of key value pairs processed,
1483 * #GNUNET_SYSERR if it aborted iteration
1486 GNUNET_CONTAINER_multihashmap32_get_multiple (const struct GNUNET_CONTAINER_MultiHashMap32 *map,
1488 GNUNET_CONTAINER_HashMapIterator32 it,
1493 * Create an iterator for a 32-bit multihashmap.
1494 * The iterator can be used to retrieve all the elements in the multihashmap
1495 * one by one, without having to handle all elements at once (in contrast to
1496 * #GNUNET_CONTAINER_multihashmap32_iterate). Note that the iterator can not be
1497 * used anymore if elements have been removed from 'map' after the creation of
1498 * the iterator, or 'map' has been destroyed. Adding elements to 'map' may
1499 * result in skipped or repeated elements.
1501 * @param map the map to create an iterator for
1502 * @return an iterator over the given multihashmap map
1504 struct GNUNET_CONTAINER_MultiHashMap32Iterator *
1505 GNUNET_CONTAINER_multihashmap32_iterator_create (const struct GNUNET_CONTAINER_MultiHashMap32 *map);
1509 * Retrieve the next element from the hash map at the iterator's position.
1510 * If there are no elements left, GNUNET_NO is returned, and 'key' and 'value'
1512 * This operation is only allowed if no elements have been removed from the
1513 * multihashmap since the creation of 'iter', and the map has not been destroyed.
1514 * Adding elements may result in repeating or skipping elements.
1516 * @param iter the iterator to get the next element from
1517 * @param key pointer to store the key in, can be NULL
1518 * @param value pointer to store the value in, can be NULL
1519 * @return #GNUNET_YES we returned an element,
1520 * #GNUNET_NO if we are out of elements
1523 GNUNET_CONTAINER_multihashmap32_iterator_next (struct GNUNET_CONTAINER_MultiHashMap32Iterator *iter,
1525 const void **value);
1529 * Destroy a 32-bit multihashmap iterator.
1531 * @param iter the iterator to destroy
1534 GNUNET_CONTAINER_multihashmap32_iterator_destroy (struct GNUNET_CONTAINER_MultiHashMapIterator *iter);
1537 /* ******************** doubly-linked list *************** */
1538 /* To avoid mistakes: head->prev == tail->next == NULL */
1542 * Insert an element at the head of a DLL. Assumes that head, tail and
1543 * element are structs with prev and next fields.
1545 * @param head pointer to the head of the DLL
1546 * @param tail pointer to the tail of the DLL
1547 * @param element element to insert
1549 #define GNUNET_CONTAINER_DLL_insert(head,tail,element) do { \
1550 GNUNET_assert ( ( (element)->prev == NULL) && ((head) != (element))); \
1551 GNUNET_assert ( ( (element)->next == NULL) && ((tail) != (element))); \
1552 (element)->next = (head); \
1553 (element)->prev = NULL; \
1554 if ((tail) == NULL) \
1557 (head)->prev = element; \
1558 (head) = (element); } while (0)
1563 * Insert an element at the tail of a DLL. Assumes that head, tail and
1564 * element are structs with prev and next fields.
1566 * @param head pointer to the head of the DLL
1567 * @param tail pointer to the tail of the DLL
1568 * @param element element to insert
1570 #define GNUNET_CONTAINER_DLL_insert_tail(head,tail,element) do { \
1571 GNUNET_assert ( ( (element)->prev == NULL) && ((head) != (element))); \
1572 GNUNET_assert ( ( (element)->next == NULL) && ((tail) != (element))); \
1573 (element)->prev = (tail); \
1574 (element)->next = NULL; \
1575 if ((head) == NULL) \
1578 (tail)->next = element; \
1579 (tail) = (element); } while (0)
1584 * Insert an element into a DLL after the given other element. Insert
1585 * at the head if the other element is NULL.
1587 * @param head pointer to the head of the DLL
1588 * @param tail pointer to the tail of the DLL
1589 * @param other prior element, NULL for insertion at head of DLL
1590 * @param element element to insert
1592 #define GNUNET_CONTAINER_DLL_insert_after(head,tail,other,element) do { \
1593 GNUNET_assert ( ( (element)->prev == NULL) && ((head) != (element))); \
1594 GNUNET_assert ( ( (element)->next == NULL) && ((tail) != (element))); \
1595 (element)->prev = (other); \
1596 if (NULL == other) \
1598 (element)->next = (head); \
1599 (head) = (element); \
1603 (element)->next = (other)->next; \
1604 (other)->next = (element); \
1606 if (NULL == (element)->next) \
1607 (tail) = (element); \
1609 (element)->next->prev = (element); } while (0)
1614 * Insert an element into a DLL before the given other element. Insert
1615 * at the tail if the other element is NULL.
1617 * @param head pointer to the head of the DLL
1618 * @param tail pointer to the tail of the DLL
1619 * @param other prior element, NULL for insertion at head of DLL
1620 * @param element element to insert
1622 #define GNUNET_CONTAINER_DLL_insert_before(head,tail,other,element) do { \
1623 GNUNET_assert ( ( (element)->prev == NULL) && ((head) != (element))); \
1624 GNUNET_assert ( ( (element)->next == NULL) && ((tail) != (element))); \
1625 (element)->next = (other); \
1626 if (NULL == other) \
1628 (element)->prev = (tail); \
1629 (tail) = (element); \
1633 (element)->prev = (other)->prev; \
1634 (other)->prev = (element); \
1636 if (NULL == (element)->prev) \
1637 (head) = (element); \
1639 (element)->prev->next = (element); } while (0)
1644 * Remove an element from a DLL. Assumes that head, tail and
1645 * element point to structs with prev and next fields.
1647 * Using the head or tail pointer as the element
1648 * argument does NOT work with this macro.
1649 * Make sure to store head/tail in another pointer
1650 * and use it to remove the head or tail of the list.
1652 * @param head pointer to the head of the DLL
1653 * @param tail pointer to the tail of the DLL
1654 * @param element element to remove
1656 #define GNUNET_CONTAINER_DLL_remove(head,tail,element) do { \
1657 GNUNET_assert ( ( (element)->prev != NULL) || ((head) == (element))); \
1658 GNUNET_assert ( ( (element)->next != NULL) || ((tail) == (element))); \
1659 if ((element)->prev == NULL) \
1660 (head) = (element)->next; \
1662 (element)->prev->next = (element)->next; \
1663 if ((element)->next == NULL) \
1664 (tail) = (element)->prev; \
1666 (element)->next->prev = (element)->prev; \
1667 (element)->next = NULL; \
1668 (element)->prev = NULL; } while (0)
1671 /* ************ Multi-DLL interface, allows DLL elements to be
1672 in multiple lists at the same time *********************** */
1676 * Insert an element at the head of a MDLL. Assumes that head, tail and
1677 * element are structs with prev and next fields.
1679 * @param mdll suffix name for the next and prev pointers in the element
1680 * @param head pointer to the head of the MDLL
1681 * @param tail pointer to the tail of the MDLL
1682 * @param element element to insert
1684 #define GNUNET_CONTAINER_MDLL_insert(mdll,head,tail,element) do { \
1685 GNUNET_assert ( ( (element)->prev_##mdll == NULL) && ((head) != (element))); \
1686 GNUNET_assert ( ( (element)->next_##mdll == NULL) && ((tail) != (element))); \
1687 (element)->next_##mdll = (head); \
1688 (element)->prev_##mdll = NULL; \
1689 if ((tail) == NULL) \
1692 (head)->prev_##mdll = element; \
1693 (head) = (element); } while (0)
1698 * Insert an element at the tail of a MDLL. Assumes that head, tail and
1699 * element are structs with prev and next fields.
1701 * @param mdll suffix name for the next and prev pointers in the element
1702 * @param head pointer to the head of the MDLL
1703 * @param tail pointer to the tail of the MDLL
1704 * @param element element to insert
1706 #define GNUNET_CONTAINER_MDLL_insert_tail(mdll,head,tail,element) do { \
1707 GNUNET_assert ( ( (element)->prev_##mdll == NULL) && ((head) != (element))); \
1708 GNUNET_assert ( ( (element)->next_##mdll == NULL) && ((tail) != (element))); \
1709 (element)->prev_##mdll = (tail); \
1710 (element)->next_##mdll = NULL; \
1711 if ((head) == NULL) \
1714 (tail)->next_##mdll = element; \
1715 (tail) = (element); } while (0)
1720 * Insert an element into a MDLL after the given other element. Insert
1721 * at the head if the other element is NULL.
1723 * @param mdll suffix name for the next and prev pointers in the element
1724 * @param head pointer to the head of the MDLL
1725 * @param tail pointer to the tail of the MDLL
1726 * @param other prior element, NULL for insertion at head of MDLL
1727 * @param element element to insert
1729 #define GNUNET_CONTAINER_MDLL_insert_after(mdll,head,tail,other,element) do { \
1730 GNUNET_assert ( ( (element)->prev_##mdll == NULL) && ((head) != (element))); \
1731 GNUNET_assert ( ( (element)->next_##mdll == NULL) && ((tail) != (element))); \
1732 (element)->prev_##mdll = (other); \
1733 if (NULL == other) \
1735 (element)->next_##mdll = (head); \
1736 (head) = (element); \
1740 (element)->next_##mdll = (other)->next_##mdll; \
1741 (other)->next_##mdll = (element); \
1743 if (NULL == (element)->next_##mdll) \
1744 (tail) = (element); \
1746 (element)->next->prev_##mdll = (element); } while (0)
1751 * Insert an element into a MDLL before the given other element. Insert
1752 * at the tail if the other element is NULL.
1754 * @param mdll suffix name for the next and prev pointers in the element
1755 * @param head pointer to the head of the MDLL
1756 * @param tail pointer to the tail of the MDLL
1757 * @param other prior element, NULL for insertion at head of MDLL
1758 * @param element element to insert
1760 #define GNUNET_CONTAINER_MDLL_insert_before(mdll,head,tail,other,element) do { \
1761 GNUNET_assert ( ( (element)->prev_##mdll == NULL) && ((head) != (element))); \
1762 GNUNET_assert ( ( (element)->next_##mdll == NULL) && ((tail) != (element))); \
1763 (element)->next_##mdll = (other); \
1764 if (NULL == other) \
1766 (element)->prev = (tail); \
1767 (tail) = (element); \
1771 (element)->prev_##mdll = (other)->prev_##mdll; \
1772 (other)->prev_##mdll = (element); \
1774 if (NULL == (element)->prev_##mdll) \
1775 (head) = (element); \
1777 (element)->prev_##mdll->next_##mdll = (element); } while (0)
1782 * Remove an element from a MDLL. Assumes
1783 * that head, tail and element are structs
1784 * with prev and next fields.
1786 * @param mdll suffix name for the next and prev pointers in the element
1787 * @param head pointer to the head of the MDLL
1788 * @param tail pointer to the tail of the MDLL
1789 * @param element element to remove
1791 #define GNUNET_CONTAINER_MDLL_remove(mdll,head,tail,element) do { \
1792 GNUNET_assert ( ( (element)->prev_##mdll != NULL) || ((head) == (element))); \
1793 GNUNET_assert ( ( (element)->next_##mdll != NULL) || ((tail) == (element))); \
1794 if ((element)->prev_##mdll == NULL) \
1795 (head) = (element)->next_##mdll; \
1797 (element)->prev_##mdll->next_##mdll = (element)->next_##mdll; \
1798 if ((element)->next_##mdll == NULL) \
1799 (tail) = (element)->prev_##mdll; \
1801 (element)->next_##mdll->prev_##mdll = (element)->prev_##mdll; \
1802 (element)->next_##mdll = NULL; \
1803 (element)->prev_##mdll = NULL; } while (0)
1807 /* ******************** Heap *************** */
1812 * Cost by which elements in a heap can be ordered.
1814 typedef uint64_t GNUNET_CONTAINER_HeapCostType;
1819 * Heap type, either max or min.
1821 enum GNUNET_CONTAINER_HeapOrder
1825 * Heap with the maximum cost at the root.
1827 GNUNET_CONTAINER_HEAP_ORDER_MAX,
1831 * Heap with the minimum cost at the root.
1833 GNUNET_CONTAINER_HEAP_ORDER_MIN
1841 struct GNUNET_CONTAINER_Heap;
1846 * Handle to a node in a heap.
1848 struct GNUNET_CONTAINER_HeapNode;
1853 * Create a new heap.
1855 * @param order how should the heap be sorted?
1856 * @return handle to the heap
1858 struct GNUNET_CONTAINER_Heap *
1859 GNUNET_CONTAINER_heap_create (enum GNUNET_CONTAINER_HeapOrder order);
1864 * Destroys the heap. Only call on a heap that
1867 * @param heap heap to destroy
1870 GNUNET_CONTAINER_heap_destroy (struct GNUNET_CONTAINER_Heap *heap);
1875 * Get element stored at the root of @a heap.
1877 * @param heap Heap to inspect.
1878 * @return Element at the root, or NULL if heap is empty.
1881 GNUNET_CONTAINER_heap_peek (const struct GNUNET_CONTAINER_Heap *heap);
1885 * Get @a element and @a cost stored at the root of @a heap.
1887 * @param[in] heap Heap to inspect.
1888 * @param[out] element Root element is returned here.
1889 * @param[out] cost Cost of @a element is returned here.
1890 * @return #GNUNET_YES if an element is returned,
1891 * #GNUNET_NO if the heap is empty.
1894 GNUNET_CONTAINER_heap_peek2 (const struct GNUNET_CONTAINER_Heap *heap,
1896 GNUNET_CONTAINER_HeapCostType *cost);
1901 * Get the current size of the heap
1903 * @param heap the heap to get the size of
1904 * @return number of elements stored
1907 GNUNET_CONTAINER_heap_get_size (const struct GNUNET_CONTAINER_Heap *heap);
1912 * Get the current cost of the node
1914 * @param node the node to get the cost of
1915 * @return cost of the node
1917 GNUNET_CONTAINER_HeapCostType
1918 GNUNET_CONTAINER_heap_node_get_cost (const struct GNUNET_CONTAINER_HeapNode
1925 * @param cls closure
1926 * @param node internal node of the heap
1927 * @param element value stored at the node
1928 * @param cost cost associated with the node
1929 * @return #GNUNET_YES if we should continue to iterate,
1930 * #GNUNET_NO if not.
1933 (*GNUNET_CONTAINER_HeapIterator) (void *cls,
1934 struct GNUNET_CONTAINER_HeapNode *node,
1936 GNUNET_CONTAINER_HeapCostType cost);
1941 * Iterate over all entries in the heap.
1943 * @param heap the heap
1944 * @param iterator function to call on each entry
1945 * @param iterator_cls closure for @a iterator
1948 GNUNET_CONTAINER_heap_iterate (const struct GNUNET_CONTAINER_Heap *heap,
1949 GNUNET_CONTAINER_HeapIterator iterator,
1950 void *iterator_cls);
1954 * Perform a random walk of the tree. The walk is biased
1955 * towards elements closer to the root of the tree (since
1956 * each walk starts at the root and ends at a random leaf).
1957 * The heap internally tracks the current position of the
1960 * @param heap heap to walk
1961 * @return data stored at the next random node in the walk;
1962 * NULL if the tree is empty.
1965 GNUNET_CONTAINER_heap_walk_get_next (struct GNUNET_CONTAINER_Heap *heap);
1970 * Inserts a new element into the heap.
1972 * @param heap heap to modify
1973 * @param element element to insert
1974 * @param cost cost for the element
1975 * @return node for the new element
1977 struct GNUNET_CONTAINER_HeapNode *
1978 GNUNET_CONTAINER_heap_insert (struct GNUNET_CONTAINER_Heap *heap,
1980 GNUNET_CONTAINER_HeapCostType cost);
1985 * Remove root of the heap.
1987 * @param heap heap to modify
1988 * @return element data stored at the root node
1991 GNUNET_CONTAINER_heap_remove_root (struct GNUNET_CONTAINER_Heap *heap);
1996 * Removes a node from the heap.
1998 * @param node node to remove
1999 * @return element data stored at the node, NULL if heap is empty
2002 GNUNET_CONTAINER_heap_remove_node (struct GNUNET_CONTAINER_HeapNode *node);
2007 * Updates the cost of any node in the tree
2009 * @param heap heap to modify
2010 * @param node node for which the cost is to be changed
2011 * @param new_cost new cost for the node
2014 GNUNET_CONTAINER_heap_update_cost (struct GNUNET_CONTAINER_Heap *heap,
2015 struct GNUNET_CONTAINER_HeapNode *node,
2016 GNUNET_CONTAINER_HeapCostType new_cost);
2019 #if 0 /* keep Emacsens' auto-indent happy */
2027 /* ifndef GNUNET_CONTAINER_LIB_H */
2029 /* end of gnunet_container_lib.h */