-fix double free, linker issue
[oweals/gnunet.git] / src / include / gnunet_container_lib.h
1 /*
2      This file is part of GNUnet.
3      (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010 Christian Grothoff (and other contributing authors)
4
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 2, or (at your
8      option) any later version.
9
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.
14
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., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file include/gnunet_container_lib.h
23  * @brief container classes for GNUnet
24  *
25  * @author Christian Grothoff
26  * @author Nils Durner
27  */
28
29 #ifndef GNUNET_CONTAINER_LIB_H
30 #define GNUNET_CONTAINER_LIB_H
31
32 /* add error and config prototypes */
33 #include "gnunet_crypto_lib.h"
34 #include <extractor.h>
35
36 #ifndef EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME
37 /* hack for LE < 0.6.3 */
38 #define EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME 180
39 #endif
40
41 #ifdef __cplusplus
42 extern "C"
43 {
44 #if 0                           /* keep Emacsens' auto-indent happy */
45 }
46 #endif
47 #endif
48
49
50 /* ******************* bloomfilter ***************** */
51
52 /**
53  * @brief bloomfilter representation (opaque)
54  */
55 struct GNUNET_CONTAINER_BloomFilter;
56
57 /**
58  * Iterator over HashCodes.
59  *
60  * @param cls closure
61  * @param next set to the next hash code
62  * @return GNUNET_YES if next was updated
63  *         GNUNET_NO if there are no more entries
64  */
65 typedef int (*GNUNET_HashCodeIterator) (void *cls, struct GNUNET_HashCode * next);
66
67
68 /**
69  * Load a bloom-filter from a file.
70  *
71  * @param filename the name of the file (or the prefix)
72  * @param size the size of the bloom-filter (number of
73  *        bytes of storage space to use); will be rounded up
74  *        to next power of 2
75  * @param k the number of GNUNET_CRYPTO_hash-functions to apply per
76  *        element (number of bits set per element in the set)
77  * @return the bloomfilter
78  */
79 struct GNUNET_CONTAINER_BloomFilter *
80 GNUNET_CONTAINER_bloomfilter_load (const char *filename, size_t size,
81                                    unsigned int k);
82
83
84 /**
85  * Create a bloom filter from raw bits.
86  *
87  * @param data the raw bits in memory (maybe NULL,
88  *        in which case all bits should be considered
89  *        to be zero).
90  * @param size the size of the bloom-filter (number of
91  *        bytes of storage space to use); also size of data
92  *        -- unless data is NULL.  Must be a power of 2.
93  * @param k the number of GNUNET_CRYPTO_hash-functions to apply per
94  *        element (number of bits set per element in the set)
95  * @return the bloomfilter
96  */
97 struct GNUNET_CONTAINER_BloomFilter *
98 GNUNET_CONTAINER_bloomfilter_init (const char *data, size_t size,
99                                    unsigned int k);
100
101
102 /**
103  * Copy the raw data of this bloomfilter into
104  * the given data array.
105  *
106  * @param data where to write the data
107  * @param size the size of the given data array
108  * @return GNUNET_SYSERR if the data array of the wrong size
109  */
110 int
111 GNUNET_CONTAINER_bloomfilter_get_raw_data (const struct
112                                            GNUNET_CONTAINER_BloomFilter *bf,
113                                            char *data, size_t size);
114
115
116 /**
117  * Test if an element is in the filter.
118  * @param e the element
119  * @param bf the filter
120  * @return GNUNET_YES if the element is in the filter, GNUNET_NO if not
121  */
122 int
123 GNUNET_CONTAINER_bloomfilter_test (const struct GNUNET_CONTAINER_BloomFilter
124                                    *bf, const struct GNUNET_HashCode * e);
125
126
127 /**
128  * Add an element to the filter
129  * @param bf the filter
130  * @param e the element
131  */
132 void
133 GNUNET_CONTAINER_bloomfilter_add (struct GNUNET_CONTAINER_BloomFilter *bf,
134                                   const struct GNUNET_HashCode * e);
135
136
137 /**
138  * Remove an element from the filter.
139  * @param bf the filter
140  * @param e the element to remove
141  */
142 void
143 GNUNET_CONTAINER_bloomfilter_remove (struct GNUNET_CONTAINER_BloomFilter *bf,
144                                      const struct GNUNET_HashCode * e);
145
146
147 /**
148  * Create a copy of a bloomfilter.
149  *
150  * @param bf the filter
151  * @return copy of bf
152  */
153 struct GNUNET_CONTAINER_BloomFilter *
154 GNUNET_CONTAINER_bloomfilter_copy (const struct GNUNET_CONTAINER_BloomFilter
155                                    *bf);
156
157
158
159 /**
160  * Free the space associcated with a filter
161  * in memory, flush to drive if needed (do not
162  * free the space on the drive)
163  * @param bf the filter
164  */
165 void
166 GNUNET_CONTAINER_bloomfilter_free (struct GNUNET_CONTAINER_BloomFilter *bf);
167
168
169 /**
170  * Get size of the bloom filter.
171  *
172  * @param bf the filter
173  * @return number of bytes used for the data of the bloom filter
174  */
175 size_t
176 GNUNET_CONTAINER_bloomfilter_get_size (const struct GNUNET_CONTAINER_BloomFilter
177                                        *bf);
178
179
180 /**
181  * Reset a bloom filter to empty.
182  * @param bf the filter
183  */
184 void
185 GNUNET_CONTAINER_bloomfilter_clear (struct GNUNET_CONTAINER_BloomFilter *bf);
186
187 /**
188  * Or the entries of the given raw data array with the
189  * data of the given bloom filter.  Assumes that
190  * the size of the data array and the current filter
191  * match.
192  *
193  * @param bf the filter
194  * @param data data to OR-in
195  * @param size size of data
196  * @return GNUNET_OK on success
197  */
198 int
199 GNUNET_CONTAINER_bloomfilter_or (struct GNUNET_CONTAINER_BloomFilter *bf,
200                                  const char *data, size_t size);
201
202 /**
203  * Or the entries of the given raw data array with the
204  * data of the given bloom filter.  Assumes that
205  * the size of the data array and the current filter
206  * match.
207  *
208  * @param bf the filter
209  * @param to_or the bloomfilter to or-in
210  * @param size number of bytes in data
211  */
212 int
213 GNUNET_CONTAINER_bloomfilter_or2 (struct GNUNET_CONTAINER_BloomFilter *bf,
214                                   const struct GNUNET_CONTAINER_BloomFilter
215                                   *to_or, size_t size);
216
217 /**
218  * Resize a bloom filter.  Note that this operation
219  * is pretty costly.  Essentially, the bloom filter
220  * needs to be completely re-build.
221  *
222  * @param bf the filter
223  * @param iterator an iterator over all elements stored in the BF
224  * @param iterator_cls closure for iterator
225  * @param size the new size for the filter
226  * @param k the new number of GNUNET_CRYPTO_hash-function to apply per element
227  */
228 void
229 GNUNET_CONTAINER_bloomfilter_resize (struct GNUNET_CONTAINER_BloomFilter *bf,
230                                      GNUNET_HashCodeIterator iterator,
231                                      void *iterator_cls, size_t size,
232                                      unsigned int k);
233
234 /* ****************** metadata ******************* */
235
236 /**
237  * Meta data to associate with a file, directory or namespace.
238  */
239 struct GNUNET_CONTAINER_MetaData;
240
241 /**
242  * Create a fresh MetaData token.
243  *
244  * @return empty meta-data container
245  */
246 struct GNUNET_CONTAINER_MetaData *
247 GNUNET_CONTAINER_meta_data_create (void);
248
249 /**
250  * Duplicate a MetaData token.
251  *
252  * @param md what to duplicate
253  * @return duplicate meta-data container
254  */
255 struct GNUNET_CONTAINER_MetaData *
256 GNUNET_CONTAINER_meta_data_duplicate (const struct GNUNET_CONTAINER_MetaData
257                                       *md);
258
259 /**
260  * Free meta data.
261  *
262  * @param md what to free
263  */
264 void
265 GNUNET_CONTAINER_meta_data_destroy (struct GNUNET_CONTAINER_MetaData *md);
266
267 /**
268  * Test if two MDs are equal. We consider them equal if
269  * the meta types, formats and content match (we do not
270  * include the mime types and plugins names in this
271  * consideration).
272  *
273  * @param md1 first value to check
274  * @param md2 other value to check
275  * @return GNUNET_YES if they are equal
276  */
277 int
278 GNUNET_CONTAINER_meta_data_test_equal (const struct GNUNET_CONTAINER_MetaData
279                                        *md1,
280                                        const struct GNUNET_CONTAINER_MetaData
281                                        *md2);
282
283
284 /**
285  * Extend metadata.
286  *
287  * @param md metadata to extend
288  * @param plugin_name name of the plugin that produced this value;
289  *        special values can be used (i.e. '&lt;zlib&gt;' for zlib being
290  *        used in the main libextractor library and yielding
291  *        meta data).
292  * @param type libextractor-type describing the meta data
293  * @param format basic format information about data
294  * @param data_mime_type mime-type of data (not of the original file);
295  *        can be NULL (if mime-type is not known)
296  * @param data actual meta-data found
297  * @param data_size number of bytes in data
298  * @return GNUNET_OK on success, GNUNET_SYSERR if this entry already exists
299  *         data_mime_type and plugin_name are not considered for "exists" checks
300  */
301 int
302 GNUNET_CONTAINER_meta_data_insert (struct GNUNET_CONTAINER_MetaData *md,
303                                    const char *plugin_name,
304                                    enum EXTRACTOR_MetaType type,
305                                    enum EXTRACTOR_MetaFormat format,
306                                    const char *data_mime_type, const char *data,
307                                    size_t data_size);
308
309
310 /**
311  * Extend metadata.  Merges the meta data from the second argument
312  * into the first, discarding duplicate key-value pairs.
313  *
314  * @param md metadata to extend
315  * @param in metadata to merge
316  */
317 void
318 GNUNET_CONTAINER_meta_data_merge (struct GNUNET_CONTAINER_MetaData *md,
319                                   const struct GNUNET_CONTAINER_MetaData *in);
320
321
322 /**
323  * Remove an item.
324  *
325  * @param md metadata to manipulate
326  * @param type type of the item to remove
327  * @param data specific value to remove, NULL to remove all
328  *        entries of the given type
329  * @param data_size number of bytes in data
330  * @return GNUNET_OK on success, GNUNET_SYSERR if the item does not exist in md
331  */
332 int
333 GNUNET_CONTAINER_meta_data_delete (struct GNUNET_CONTAINER_MetaData *md,
334                                    enum EXTRACTOR_MetaType type,
335                                    const char *data, size_t data_size);
336
337
338 /**
339  * Remove all items in the container.
340  *
341  * @param md metadata to manipulate
342  */
343 void
344 GNUNET_CONTAINER_meta_data_clear (struct GNUNET_CONTAINER_MetaData *md);
345
346
347 /**
348  * Add the current time as the publication date
349  * to the meta-data.
350  *
351  * @param md metadata to modify
352  */
353 void
354 GNUNET_CONTAINER_meta_data_add_publication_date (struct
355                                                  GNUNET_CONTAINER_MetaData *md);
356
357
358 /**
359  * Iterate over MD entries.
360  *
361  * @param md metadata to inspect
362  * @param iter function to call on each entry
363  * @param iter_cls closure for iterator
364  * @return number of entries
365  */
366 int
367 GNUNET_CONTAINER_meta_data_iterate (const struct GNUNET_CONTAINER_MetaData *md,
368                                     EXTRACTOR_MetaDataProcessor iter,
369                                     void *iter_cls);
370
371 /**
372  * Get the first MD entry of the given type.  Caller
373  * is responsible for freeing the return value.
374  * Also, only meta data items that are strings (0-terminated)
375  * are returned by this function.
376  *
377  * @param md metadata to inspect
378  * @param type type to look for
379  * @return NULL if no entry was found
380  */
381 char *
382 GNUNET_CONTAINER_meta_data_get_by_type (const struct GNUNET_CONTAINER_MetaData
383                                         *md, enum EXTRACTOR_MetaType type);
384
385
386 /**
387  * Get the first matching MD entry of the given types. Caller is
388  * responsible for freeing the return value.  Also, only meta data
389  * items that are strings (0-terminated) are returned by this
390  * function.
391  *
392  * @param md metadata to inspect
393  * @param ... -1-terminated list of types
394  * @return NULL if we do not have any such entry,
395  *  otherwise client is responsible for freeing the value!
396  */
397 char *
398 GNUNET_CONTAINER_meta_data_get_first_by_types (const struct
399                                                GNUNET_CONTAINER_MetaData *md,
400                                                ...);
401
402 /**
403  * Get a thumbnail from the meta-data (if present).  Only matches meta
404  * data with mime type "image" and binary format.
405  *
406  * @param md metadata to inspect
407  * @param thumb will be set to the thumbnail data.  Must be
408  *        freed by the caller!
409  * @return number of bytes in thumbnail, 0 if not available
410  */
411 size_t
412 GNUNET_CONTAINER_meta_data_get_thumbnail (const struct GNUNET_CONTAINER_MetaData
413                                           *md, unsigned char **thumb);
414
415
416
417 /**
418  * Options for metadata serialization.
419  */
420 enum GNUNET_CONTAINER_MetaDataSerializationOptions
421 {
422   /**
423    * Serialize all of the data.
424    */
425   GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL = 0,
426
427   /**
428    * If not enough space is available, it is acceptable
429    * to only serialize some of the metadata.
430    */
431   GNUNET_CONTAINER_META_DATA_SERIALIZE_PART = 1,
432
433   /**
434    * Speed is of the essence, do not allow compression.
435    */
436   GNUNET_CONTAINER_META_DATA_SERIALIZE_NO_COMPRESS = 2
437 };
438
439
440 /**
441  * Serialize meta-data to target.
442  *
443  * @param md metadata to serialize
444  * @param target where to write the serialized metadata;
445  *         *target can be NULL, in which case memory is allocated
446  * @param max maximum number of bytes available
447  * @param opt is it ok to just write SOME of the
448  *        meta-data to match the size constraint,
449  *        possibly discarding some data?
450  * @return number of bytes written on success,
451  *         -1 on error (typically: not enough
452  *         space)
453  */
454 ssize_t
455 GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData
456                                       *md, char **target, size_t max,
457                                       enum
458                                       GNUNET_CONTAINER_MetaDataSerializationOptions
459                                       opt);
460
461
462 /**
463  * Get the size of the full meta-data in serialized form.
464  *
465  * @param md metadata to inspect
466  * @return number of bytes needed for serialization, -1 on error
467  */
468 ssize_t
469 GNUNET_CONTAINER_meta_data_get_serialized_size (const struct
470                                                 GNUNET_CONTAINER_MetaData *md);
471
472
473 /**
474  * Deserialize meta-data.  Initializes md.
475  *
476  * @param input serialized meta-data.
477  * @param size number of bytes available
478  * @return MD on success, NULL on error (i.e.
479  *         bad format)
480  */
481 struct GNUNET_CONTAINER_MetaData *
482 GNUNET_CONTAINER_meta_data_deserialize (const char *input, size_t size);
483
484
485 /* ******************************* HashMap **************************** */
486
487 /**
488  * Opaque handle for a HashMap.
489  */
490 struct GNUNET_CONTAINER_MultiHashMap;
491
492 /**
493  * Options for storing values in the HashMap.
494  */
495 enum GNUNET_CONTAINER_MultiHashMapOption
496 {
497
498   /**
499    * If a value with the given key exists, replace it.  Note that the
500    * old value would NOT be freed by replace (the application has to
501    * make sure that this happens if required).
502    */
503   GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE,
504
505   /**
506    * Allow multiple values with the same key.
507    */
508   GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE,
509
510   /**
511    * There must only be one value per key; storing a value should fail
512    * if a value under the same key already exists.
513    */
514   GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY,
515
516   /**
517    * There must only be one value per key, but don't bother checking
518    * if a value already exists (faster than UNIQUE_ONLY; implemented
519    * just like MULTIPLE but this option documents better what is
520    * intended if UNIQUE is what is desired).
521    */
522   GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST
523 };
524
525
526 /**
527  * Iterator over hash map entries.
528  *
529  * @param cls closure
530  * @param key current key code
531  * @param value value in the hash map
532  * @return GNUNET_YES if we should continue to
533  *         iterate,
534  *         GNUNET_NO if not.
535  */
536 typedef int (*GNUNET_CONTAINER_HashMapIterator) (void *cls,
537                                                  const struct GNUNET_HashCode * key,
538                                                  void *value);
539
540
541 /**
542  * Create a multi hash map.
543  *
544  * @param len initial size (map will grow as needed)
545  * @return NULL on error
546  */
547 struct GNUNET_CONTAINER_MultiHashMap *
548 GNUNET_CONTAINER_multihashmap_create (unsigned int len);
549
550
551 /**
552  * Destroy a hash map.  Will not free any values
553  * stored in the hash map!
554  *
555  * @param map the map
556  */
557 void
558 GNUNET_CONTAINER_multihashmap_destroy (struct GNUNET_CONTAINER_MultiHashMap
559                                        *map);
560
561
562 /**
563  * Given a key find a value in the map matching the key.
564  *
565  * @param map the map
566  * @param key what to look for
567  * @return NULL if no value was found; note that
568  *   this is indistinguishable from values that just
569  *   happen to be NULL; use "contains" to test for
570  *   key-value pairs with value NULL
571  */
572 void *
573 GNUNET_CONTAINER_multihashmap_get (const struct GNUNET_CONTAINER_MultiHashMap
574                                    *map, const struct GNUNET_HashCode * key);
575
576
577 /**
578  * Remove the given key-value pair from the map.  Note that if the
579  * key-value pair is in the map multiple times, only one of the pairs
580  * will be removed.
581  *
582  * @param map the map
583  * @param key key of the key-value pair
584  * @param value value of the key-value pair
585  * @return GNUNET_YES on success, GNUNET_NO if the key-value pair
586  *  is not in the map
587  */
588 int
589 GNUNET_CONTAINER_multihashmap_remove (struct GNUNET_CONTAINER_MultiHashMap *map,
590                                       const struct GNUNET_HashCode * key, void *value);
591
592 /**
593  * Remove all entries for the given key from the map.
594  * Note that the values would not be "freed".
595  *
596  * @param map the map
597  * @param key identifies values to be removed
598  * @return number of values removed
599  */
600 int
601 GNUNET_CONTAINER_multihashmap_remove_all (struct GNUNET_CONTAINER_MultiHashMap
602                                           *map, const struct GNUNET_HashCode * key);
603
604
605 /**
606  * Check if the map contains any value under the given
607  * key (including values that are NULL).
608  *
609  * @param map the map
610  * @param key the key to test if a value exists for it
611  * @return GNUNET_YES if such a value exists,
612  *         GNUNET_NO if not
613  */
614 int
615 GNUNET_CONTAINER_multihashmap_contains (const struct
616                                         GNUNET_CONTAINER_MultiHashMap *map,
617                                         const struct GNUNET_HashCode * key);
618
619
620 /**
621  * Check if the map contains the given value under the given
622  * key.
623  *
624  * @param map the map
625  * @param key the key to test if a value exists for it
626  * @param value value to test for
627  * @return GNUNET_YES if such a value exists,
628  *         GNUNET_NO if not
629  */
630 int
631 GNUNET_CONTAINER_multihashmap_contains_value (const struct
632                                               GNUNET_CONTAINER_MultiHashMap
633                                               *map, const struct GNUNET_HashCode * key,
634                                               const void *value);
635
636
637 /**
638  * Store a key-value pair in the map.
639  *
640  * @param map the map
641  * @param key key to use
642  * @param value value to use
643  * @param opt options for put
644  * @return GNUNET_OK on success,
645  *         GNUNET_NO if a value was replaced (with REPLACE)
646  *         GNUNET_SYSERR if UNIQUE_ONLY was the option and the
647  *                       value already exists
648  */
649 int
650 GNUNET_CONTAINER_multihashmap_put (struct GNUNET_CONTAINER_MultiHashMap *map,
651                                    const struct GNUNET_HashCode * key, void *value,
652                                    enum GNUNET_CONTAINER_MultiHashMapOption
653                                    opt);
654
655 /**
656  * Get the number of key-value pairs in the map.
657  *
658  * @param map the map
659  * @return the number of key value pairs
660  */
661 unsigned int
662 GNUNET_CONTAINER_multihashmap_size (const struct GNUNET_CONTAINER_MultiHashMap
663                                     *map);
664
665
666 /**
667  * Iterate over all entries in the map.
668  *
669  * @param map the map
670  * @param it function to call on each entry
671  * @param it_cls extra argument to it
672  * @return the number of key value pairs processed,
673  *         GNUNET_SYSERR if it aborted iteration
674  */
675 int
676 GNUNET_CONTAINER_multihashmap_iterate (const struct
677                                        GNUNET_CONTAINER_MultiHashMap *map,
678                                        GNUNET_CONTAINER_HashMapIterator it,
679                                        void *it_cls);
680
681
682 /**
683  * Iterate over all entries in the map that match a particular key.
684  *
685  * @param map the map
686  * @param key key that the entries must correspond to
687  * @param it function to call on each entry
688  * @param it_cls extra argument to it
689  * @return the number of key value pairs processed,
690  *         GNUNET_SYSERR if it aborted iteration
691  */
692 int
693 GNUNET_CONTAINER_multihashmap_get_multiple (const struct
694                                             GNUNET_CONTAINER_MultiHashMap *map,
695                                             const struct GNUNET_HashCode * key,
696                                             GNUNET_CONTAINER_HashMapIterator it,
697                                             void *it_cls);
698
699
700 /* ******************** doubly-linked list *************** */
701 /* To avoid mistakes: head->prev == tail->next == NULL     */
702
703 /**
704  * Insert an element at the head of a DLL. Assumes that head, tail and
705  * element are structs with prev and next fields.
706  *
707  * @param head pointer to the head of the DLL
708  * @param tail pointer to the tail of the DLL
709  * @param element element to insert
710  */
711 #define GNUNET_CONTAINER_DLL_insert(head,tail,element) do { \
712   GNUNET_assert ( ( (element)->prev == NULL) && ((head) != (element))); \
713   GNUNET_assert ( ( (element)->next == NULL) && ((tail) != (element))); \
714   (element)->next = (head); \
715   (element)->prev = NULL; \
716   if ((tail) == NULL) \
717     (tail) = element; \
718   else \
719     (head)->prev = element; \
720   (head) = (element); } while (0)
721
722
723 /**
724  * Insert an element at the tail of a DLL. Assumes that head, tail and
725  * element are structs with prev and next fields.
726  *
727  * @param head pointer to the head of the DLL
728  * @param tail pointer to the tail of the DLL
729  * @param element element to insert
730  */
731 #define GNUNET_CONTAINER_DLL_insert_tail(head,tail,element) do { \
732   GNUNET_assert ( ( (element)->prev == NULL) && ((head) != (element))); \
733   GNUNET_assert ( ( (element)->next == NULL) && ((tail) != (element))); \
734   (element)->prev = (tail); \
735   (element)->next = NULL; \
736   if ((head) == NULL) \
737     (head) = element; \
738   else \
739     (tail)->next = element; \
740   (tail) = (element); } while (0)
741
742
743 /**
744  * Insert an element into a DLL after the given other element.  Insert
745  * at the head if the other element is NULL.
746  *
747  * @param head pointer to the head of the DLL
748  * @param tail pointer to the tail of the DLL
749  * @param other prior element, NULL for insertion at head of DLL
750  * @param element element to insert
751  */
752 #define GNUNET_CONTAINER_DLL_insert_after(head,tail,other,element) do { \
753   GNUNET_assert ( ( (element)->prev == NULL) && ((head) != (element))); \
754   GNUNET_assert ( ( (element)->next == NULL) && ((tail) != (element))); \
755   (element)->prev = (other); \
756   if (NULL == other) \
757     { \
758       (element)->next = (head); \
759       (head) = (element); \
760     } \
761   else \
762     { \
763       (element)->next = (other)->next; \
764       (other)->next = (element); \
765     } \
766   if (NULL == (element)->next) \
767     (tail) = (element); \
768   else \
769     (element)->next->prev = (element); } while (0)
770
771
772 /**
773  * Insert an element into a DLL before the given other element.  Insert
774  * at the tail if the other element is NULL.
775  *
776  * @param head pointer to the head of the DLL
777  * @param tail pointer to the tail of the DLL
778  * @param other prior element, NULL for insertion at head of DLL
779  * @param element element to insert
780  */
781 #define GNUNET_CONTAINER_DLL_insert_before(head,tail,other,element) do { \
782   GNUNET_assert ( ( (element)->prev == NULL) && ((head) != (element))); \
783   GNUNET_assert ( ( (element)->next == NULL) && ((tail) != (element))); \
784   (element)->next = (other); \
785   if (NULL == other) \
786     { \
787       (element)->prev = (tail); \
788       (tail) = (element); \
789     } \
790   else \
791     { \
792       (element)->prev = (other)->prev; \
793       (other)->prev = (element); \
794     } \
795   if (NULL == (element)->prev) \
796     (head) = (element); \
797   else \
798     (element)->prev->next = (element); } while (0)
799
800
801 /**
802  * Remove an element from a DLL. Assumes
803  * that head, tail and element are structs
804  * with prev and next fields.
805  *
806  * @param head pointer to the head of the DLL
807  * @param tail pointer to the tail of the DLL
808  * @param element element to remove
809  */
810 #define GNUNET_CONTAINER_DLL_remove(head,tail,element) do { \
811   GNUNET_assert ( ( (element)->prev != NULL) || ((head) == (element))); \
812   GNUNET_assert ( ( (element)->next != NULL) || ((tail) == (element))); \
813   if ((element)->prev == NULL) \
814     (head) = (element)->next;  \
815   else \
816     (element)->prev->next = (element)->next; \
817   if ((element)->next == NULL) \
818     (tail) = (element)->prev;  \
819   else \
820     (element)->next->prev = (element)->prev; \
821   (element)->next = NULL; \
822   (element)->prev = NULL; } while (0)
823
824
825
826 /* ******************** Heap *************** */
827
828
829 /**
830  * Cost by which elements in a heap can be ordered.
831  */
832 typedef uint64_t GNUNET_CONTAINER_HeapCostType;
833
834
835 /*
836  * Heap type, either max or min.  Hopefully makes the
837  * implementation more useful.
838  */
839 enum GNUNET_CONTAINER_HeapOrder
840 {
841   /**
842    * Heap with the maximum cost at the root.
843    */
844   GNUNET_CONTAINER_HEAP_ORDER_MAX,
845
846   /**
847    * Heap with the minimum cost at the root.
848    */
849   GNUNET_CONTAINER_HEAP_ORDER_MIN
850 };
851
852
853 /**
854  * Handle to a Heap.
855  */
856 struct GNUNET_CONTAINER_Heap;
857
858
859
860 /**
861  * Handle to a node in a heap.
862  */
863 struct GNUNET_CONTAINER_HeapNode;
864
865
866 /**
867  * Create a new heap.
868  *
869  * @param order how should the heap be sorted?
870  * @return handle to the heap
871  */
872 struct GNUNET_CONTAINER_Heap *
873 GNUNET_CONTAINER_heap_create (enum GNUNET_CONTAINER_HeapOrder order);
874
875
876 /**
877  * Destroys the heap.  Only call on a heap that
878  * is already empty.
879  *
880  * @param heap heap to destroy
881  */
882 void
883 GNUNET_CONTAINER_heap_destroy (struct GNUNET_CONTAINER_Heap *heap);
884
885
886 /**
887  * Get element stored at root of heap.
888  *
889  * @param heap heap to inspect
890  * @return NULL if heap is empty
891  */
892 void *
893 GNUNET_CONTAINER_heap_peek (const struct GNUNET_CONTAINER_Heap *heap);
894
895
896 /**
897  * Get the current size of the heap
898  *
899  * @param heap the heap to get the size of
900  * @return number of elements stored
901  */
902 unsigned int
903 GNUNET_CONTAINER_heap_get_size (const struct GNUNET_CONTAINER_Heap *heap);
904
905
906 /**
907  * Get the current cost of the node
908  *
909  * @param node the node to get the cost of
910  * @return cost of the node
911  */
912 GNUNET_CONTAINER_HeapCostType
913 GNUNET_CONTAINER_heap_node_get_cost (const struct GNUNET_CONTAINER_HeapNode
914                                      *node);
915
916 /**
917  * Iterator for heap
918  *
919  * @param cls closure
920  * @param node internal node of the heap
921  * @param element value stored at the node
922  * @param cost cost associated with the node
923  * @return GNUNET_YES if we should continue to iterate,
924  *         GNUNET_NO if not.
925  */
926 typedef int (*GNUNET_CONTAINER_HeapIterator) (void *cls,
927                                               struct GNUNET_CONTAINER_HeapNode *
928                                               node, void *element,
929                                               GNUNET_CONTAINER_HeapCostType
930                                               cost);
931
932
933 /**
934  * Iterate over all entries in the heap.
935  *
936  * @param heap the heap
937  * @param iterator function to call on each entry
938  * @param iterator_cls closure for iterator
939  */
940 void
941 GNUNET_CONTAINER_heap_iterate (const struct GNUNET_CONTAINER_Heap *heap,
942                                GNUNET_CONTAINER_HeapIterator iterator,
943                                void *iterator_cls);
944
945
946 /**
947  * Return a *uniform* random element from the heap.  Choose a random
948  * number between 0 and heap size and then walk directly to it.
949  * This cost can be between 0 and n, amortized cost of logN.
950  *
951  * @param heap heap to choose random element from
952  * @param max how many nodes from the heap to choose from
953  *
954  * @return data stored at the chosen random node,
955  *         NULL if the heap is empty.
956  *
957  */
958 void *
959 GNUNET_CONTAINER_heap_get_random (struct GNUNET_CONTAINER_Heap *heap,
960                                   uint32_t max);
961
962
963 /**
964  * Perform a random walk of the tree.  The walk is biased
965  * towards elements closer to the root of the tree (since
966  * each walk starts at the root and ends at a random leaf).
967  * The heap internally tracks the current position of the
968  * walk.
969  *
970  * @param heap heap to walk
971  * @return data stored at the next random node in the walk;
972  *         NULL if the tree is empty.
973  */
974 void *
975 GNUNET_CONTAINER_heap_walk_get_next (struct GNUNET_CONTAINER_Heap *heap);
976
977
978 /**
979  * Inserts a new element into the heap.
980  *
981  * @param heap heap to modify
982  * @param element element to insert
983  * @param cost cost for the element
984  * @return node for the new element
985  */
986 struct GNUNET_CONTAINER_HeapNode *
987 GNUNET_CONTAINER_heap_insert (struct GNUNET_CONTAINER_Heap *heap, void *element,
988                               GNUNET_CONTAINER_HeapCostType cost);
989
990
991 /**
992  * Remove root of the heap.
993  *
994  * @param heap heap to modify
995  * @return element data stored at the root node
996  */
997 void *
998 GNUNET_CONTAINER_heap_remove_root (struct GNUNET_CONTAINER_Heap *heap);
999
1000
1001 /**
1002  * Removes a node from the heap.
1003  *
1004  * @param node node to remove
1005  * @return element data stored at the node, NULL if heap is empty
1006  */
1007 void *
1008 GNUNET_CONTAINER_heap_remove_node (struct GNUNET_CONTAINER_HeapNode *node);
1009
1010
1011 /**
1012  * Updates the cost of any node in the tree
1013  *
1014  * @param heap heap to modify
1015  * @param node node for which the cost is to be changed
1016  * @param new_cost new cost for the node
1017  */
1018 void
1019 GNUNET_CONTAINER_heap_update_cost (struct GNUNET_CONTAINER_Heap *heap,
1020                                    struct GNUNET_CONTAINER_HeapNode *node,
1021                                    GNUNET_CONTAINER_HeapCostType new_cost);
1022
1023
1024 /* ******************** Singly linked list *************** */
1025
1026 /**
1027  * Possible ways for how data stored in the linked list
1028  * might be allocated.
1029  */
1030 enum GNUNET_CONTAINER_SListDisposition
1031 {
1032     /**
1033      * Single-linked list must copy the buffer.
1034      */
1035   GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT = 0,
1036
1037     /**
1038      * Data is static, no need to copy or free.
1039      */
1040   GNUNET_CONTAINER_SLIST_DISPOSITION_STATIC = 2,
1041
1042     /**
1043      * Data is dynamic, do not copy but free when done.
1044      */
1045   GNUNET_CONTAINER_SLIST_DISPOSITION_DYNAMIC = 4
1046 };
1047
1048
1049
1050 /**
1051  * Handle to a singly linked list
1052  */
1053 struct GNUNET_CONTAINER_SList;
1054
1055 /**
1056  * Handle to a singly linked list iterator
1057  */
1058 struct GNUNET_CONTAINER_SList_Iterator
1059 {
1060   /**
1061    * Linked list that we are iterating over.
1062    */
1063   struct GNUNET_CONTAINER_SList *list;
1064
1065   /**
1066    * Last element accessed.
1067    */
1068   struct GNUNET_CONTAINER_SList_Elem *last;
1069
1070   /**
1071    * Current list element.
1072    */
1073   struct GNUNET_CONTAINER_SList_Elem *elem;
1074 };
1075
1076
1077
1078 /**
1079  * Add a new element to the list
1080  * @param l list
1081  * @param disp memory disposition
1082  * @param buf payload buffer
1083  * @param len length of the buffer
1084  */
1085 void
1086 GNUNET_CONTAINER_slist_add (struct GNUNET_CONTAINER_SList *l,
1087                             enum GNUNET_CONTAINER_SListDisposition disp,
1088                             const void *buf, size_t len);
1089
1090
1091 /**
1092  * Add a new element to the end of the list
1093  * @param l list
1094  * @param disp memory disposition
1095  * @param buf payload buffer
1096  * @param len length of the buffer
1097  */
1098 void
1099 GNUNET_CONTAINER_slist_add_end (struct GNUNET_CONTAINER_SList *l,
1100                                 enum GNUNET_CONTAINER_SListDisposition disp,
1101                                 const void *buf, size_t len);
1102
1103
1104 /**
1105  * Append a singly linked list to another
1106  * @param dst list to append to
1107  * @param src source
1108  */
1109 void
1110 GNUNET_CONTAINER_slist_append (struct GNUNET_CONTAINER_SList *dst,
1111                                struct GNUNET_CONTAINER_SList *src);
1112
1113
1114 /**
1115  * Create a new singly linked list
1116  * @return the new list
1117  */
1118 struct GNUNET_CONTAINER_SList *
1119 GNUNET_CONTAINER_slist_create (void);
1120
1121
1122 /**
1123  * Destroy a singly linked list
1124  * @param l the list to be destroyed
1125  */
1126 void
1127 GNUNET_CONTAINER_slist_destroy (struct GNUNET_CONTAINER_SList *l);
1128
1129
1130 /**
1131  * Return the beginning of a list
1132  *
1133  * @param l list
1134  * @return iterator pointing to the beginning (by value! Either allocate the
1135  *   structure on the stack, or use GNUNET_malloc() yourself! All other
1136  *   functions do take pointer to this struct though)
1137  */
1138 struct GNUNET_CONTAINER_SList_Iterator
1139 GNUNET_CONTAINER_slist_begin (struct GNUNET_CONTAINER_SList *l);
1140
1141
1142 /**
1143  * Clear a list
1144  *
1145  * @param l list
1146  */
1147 void
1148 GNUNET_CONTAINER_slist_clear (struct GNUNET_CONTAINER_SList *l);
1149
1150
1151 /**
1152  * Check if a list contains a certain element
1153  * @param l list
1154  * @param buf payload buffer to find
1155  * @param len length of the payload (number of bytes in buf)
1156  *
1157  * @return GNUNET_YES if found, GNUNET_NO otherwise
1158  */
1159 int
1160 GNUNET_CONTAINER_slist_contains (const struct GNUNET_CONTAINER_SList *l,
1161                                  const void *buf, size_t len);
1162
1163 /**
1164  * Check if a list contains a certain element using 'compare' function
1165  *
1166  * @param l list
1167  * @param buf payload buffer to find
1168  * @param len length of the payload (number of bytes in buf)
1169  * @param compare comparison function
1170  *
1171  * @return NULL if the 'buf' could not be found, pointer to the
1172  *         list element, if found
1173  */
1174 void *
1175 GNUNET_CONTAINER_slist_contains2 (const struct GNUNET_CONTAINER_SList *l,
1176                                   const void *buf, size_t len,
1177                                   int (*compare)(const void *, const size_t, const void *, const size_t));
1178 /**
1179  * Count the elements of a list
1180  * @param l list
1181  * @return number of elements in the list
1182  */
1183 int
1184 GNUNET_CONTAINER_slist_count (const struct GNUNET_CONTAINER_SList *l);
1185
1186
1187 /**
1188  * Remove an element from the list
1189  * @param i iterator that points to the element to be removed
1190  */
1191 void
1192 GNUNET_CONTAINER_slist_erase (struct GNUNET_CONTAINER_SList_Iterator *i);
1193
1194
1195 /**
1196  * Insert an element into a list at a specific position
1197  * @param before where to insert the new element
1198  * @param disp memory disposition
1199  * @param buf payload buffer
1200  * @param len length of the payload
1201  */
1202 void
1203 GNUNET_CONTAINER_slist_insert (struct GNUNET_CONTAINER_SList_Iterator *before,
1204                                enum GNUNET_CONTAINER_SListDisposition disp,
1205                                const void *buf, size_t len);
1206
1207
1208 /**
1209  * Advance an iterator to the next element
1210  * @param i iterator
1211  * @return GNUNET_YES on success, GNUNET_NO if the end has been reached
1212  */
1213 int
1214 GNUNET_CONTAINER_slist_next (struct GNUNET_CONTAINER_SList_Iterator *i);
1215
1216
1217 /**
1218  * Check if an iterator points beyond the end of a list
1219  * @param i iterator
1220  * @return GNUNET_YES if the end has been reached, GNUNET_NO if the iterator
1221  *         points to a valid element
1222  */
1223 int
1224 GNUNET_CONTAINER_slist_end (struct GNUNET_CONTAINER_SList_Iterator *i);
1225
1226
1227 /**
1228  * Retrieve the element at a specific position in a list
1229  *
1230  * @param i iterator
1231  * @param len set to the payload length
1232  * @return payload
1233  */
1234 void *
1235 GNUNET_CONTAINER_slist_get (const struct GNUNET_CONTAINER_SList_Iterator *i,
1236                             size_t * len);
1237
1238
1239 /**
1240  * Release an iterator
1241  * @param i iterator
1242  */
1243 void
1244 GNUNET_CONTAINER_slist_iter_destroy (struct GNUNET_CONTAINER_SList_Iterator *i);
1245
1246
1247 #if 0                           /* keep Emacsens' auto-indent happy */
1248 {
1249 #endif
1250 #ifdef __cplusplus
1251 }
1252 #endif
1253
1254
1255 /* ifndef GNUNET_CONTAINER_LIB_H */
1256 #endif
1257 /* end of gnunet_container_lib.h */