aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2019-06-18 10:30:08 +0200
committerChristian Grothoff <christian@grothoff.org>2019-06-18 10:30:08 +0200
commit9ae7f13f17e3d04d3ba88862299c8e42541eab47 (patch)
tree167259c402cd199bcbce49f14d6aae20f41425d8
parent93c332be89c4c65f10b7c4c49b6ed15d91b91884 (diff)
downloadgnunet-9ae7f13f17e3d04d3ba88862299c8e42541eab47.tar.gz
gnunet-9ae7f13f17e3d04d3ba88862299c8e42541eab47.zip
Introducing GNUNET_Uuid and matching hash map for 128 bit values.
TNG: reducing size of AcknowledgementUUIDPs from 256 bits to 128 bits.
-rw-r--r--src/include/gnunet_common.h25
-rw-r--r--src/include/gnunet_container_lib.h1127
-rw-r--r--src/transport/gnunet-service-tng.c42
-rw-r--r--src/util/Makefile.am1
-rw-r--r--src/util/common_logging.c393
-rw-r--r--src/util/container_multiuuidmap.c1015
6 files changed, 1979 insertions, 624 deletions
diff --git a/src/include/gnunet_common.h b/src/include/gnunet_common.h
index 0fca53b7f..6b48c81d8 100644
--- a/src/include/gnunet_common.h
+++ b/src/include/gnunet_common.h
@@ -273,6 +273,18 @@ struct GNUNET_ShortHashCode
273 273
274 274
275/** 275/**
276 * A UUID, a 128 bit random value.
277 */
278struct GNUNET_Uuid
279{
280 /**
281 * 128 random bits.
282 */
283 uint32_t value[4];
284};
285
286
287/**
276 * Header for all communications. 288 * Header for all communications.
277 */ 289 */
278struct GNUNET_MessageHeader 290struct GNUNET_MessageHeader
@@ -655,6 +667,19 @@ GNUNET_sh2s (const struct GNUNET_ShortHashCode *shc);
655 667
656/** 668/**
657 * @ingroup logging 669 * @ingroup logging
670 * Convert a UUID to a string (for printing debug messages).
671 * This is one of the very few calls in the entire API that is
672 * NOT reentrant!
673 *
674 * @param uuid the UUID
675 * @return string
676 */
677const char *
678GNUNET_uuid2s (const struct GNUNET_Uuid *uuid);
679
680
681/**
682 * @ingroup logging
658 * Convert a hash value to a string (for printing debug messages). 683 * Convert a hash value to a string (for printing debug messages).
659 * This is one of the very few calls in the entire API that is 684 * This is one of the very few calls in the entire API that is
660 * NOT reentrant! 685 * NOT reentrant!
diff --git a/src/include/gnunet_container_lib.h b/src/include/gnunet_container_lib.h
index fee851e1c..fbfbf2d40 100644
--- a/src/include/gnunet_container_lib.h
+++ b/src/include/gnunet_container_lib.h
@@ -84,9 +84,7 @@ GNUNET_try_compression (const char *data,
84 * @return NULL on error, buffer of @a output_size decompressed bytes otherwise 84 * @return NULL on error, buffer of @a output_size decompressed bytes otherwise
85 */ 85 */
86char * 86char *
87GNUNET_decompress (const char *input, 87GNUNET_decompress (const char *input, size_t input_size, size_t output_size);
88 size_t input_size,
89 size_t output_size);
90 88
91 89
92#if HAVE_EXTRACTOR_H 90#if HAVE_EXTRACTOR_H
@@ -101,7 +99,8 @@ GNUNET_decompress (const char *input,
101 * Enumeration defining various sources of keywords. See also 99 * Enumeration defining various sources of keywords. See also
102 * http://dublincore.org/documents/1998/09/dces/ 100 * http://dublincore.org/documents/1998/09/dces/
103 */ 101 */
104enum EXTRACTOR_MetaType { 102enum EXTRACTOR_MetaType
103{
105 EXTRACTOR_METATYPE_RESERVED = 0, 104 EXTRACTOR_METATYPE_RESERVED = 0,
106 EXTRACTOR_METATYPE_MIMETYPE = 1, 105 EXTRACTOR_METATYPE_MIMETYPE = 1,
107 EXTRACTOR_METATYPE_FILENAME = 2, 106 EXTRACTOR_METATYPE_FILENAME = 2,
@@ -131,7 +130,8 @@ enum EXTRACTOR_MetaType {
131/** 130/**
132 * Format in which the extracted meta data is presented. 131 * Format in which the extracted meta data is presented.
133 */ 132 */
134enum EXTRACTOR_MetaFormat { 133enum EXTRACTOR_MetaFormat
134{
135 /** 135 /**
136 * Format is unknown. 136 * Format is unknown.
137 */ 137 */
@@ -173,14 +173,13 @@ enum EXTRACTOR_MetaFormat {
173 * @param data_len number of bytes in @a data 173 * @param data_len number of bytes in @a data
174 * @return 0 to continue extracting, 1 to abort 174 * @return 0 to continue extracting, 1 to abort
175 */ 175 */
176typedef int 176typedef int (*EXTRACTOR_MetaDataProcessor) (void *cls,
177(*EXTRACTOR_MetaDataProcessor) (void *cls, 177 const char *plugin_name,
178 const char *plugin_name, 178 enum EXTRACTOR_MetaType type,
179 enum EXTRACTOR_MetaType type, 179 enum EXTRACTOR_MetaFormat format,
180 enum EXTRACTOR_MetaFormat format, 180 const char *data_mime_type,
181 const char *data_mime_type, 181 const char *data,
182 const char *data, 182 size_t data_len);
183 size_t data_len);
184 183
185#endif 184#endif
186 185
@@ -190,9 +189,8 @@ typedef int
190#endif 189#endif
191 190
192#ifdef __cplusplus 191#ifdef __cplusplus
193extern "C" 192extern "C" {
194{ 193#if 0 /* keep Emacsens' auto-indent happy */
195#if 0 /* keep Emacsens' auto-indent happy */
196} 194}
197#endif 195#endif
198#endif 196#endif
@@ -216,9 +214,8 @@ struct GNUNET_CONTAINER_BloomFilter;
216 * @return #GNUNET_YES if next was updated 214 * @return #GNUNET_YES if next was updated
217 * #GNUNET_NO if there are no more entries 215 * #GNUNET_NO if there are no more entries
218 */ 216 */
219typedef int 217typedef int (*GNUNET_CONTAINER_HashCodeIterator) (void *cls,
220(*GNUNET_CONTAINER_HashCodeIterator) (void *cls, 218 struct GNUNET_HashCode *next);
221 struct GNUNET_HashCode *next);
222 219
223 220
224/** 221/**
@@ -269,9 +266,10 @@ GNUNET_CONTAINER_bloomfilter_init (const char *data,
269 * @return #GNUNET_SYSERR if the data array of the wrong size 266 * @return #GNUNET_SYSERR if the data array of the wrong size
270 */ 267 */
271int 268int
272GNUNET_CONTAINER_bloomfilter_get_raw_data (const struct GNUNET_CONTAINER_BloomFilter *bf, 269GNUNET_CONTAINER_bloomfilter_get_raw_data (
273 char *data, 270 const struct GNUNET_CONTAINER_BloomFilter *bf,
274 size_t size); 271 char *data,
272 size_t size);
275 273
276 274
277/** 275/**
@@ -283,8 +281,9 @@ GNUNET_CONTAINER_bloomfilter_get_raw_data (const struct GNUNET_CONTAINER_BloomFi
283 * @return #GNUNET_YES if the element is in the filter, #GNUNET_NO if not 281 * @return #GNUNET_YES if the element is in the filter, #GNUNET_NO if not
284 */ 282 */
285int 283int
286GNUNET_CONTAINER_bloomfilter_test (const struct GNUNET_CONTAINER_BloomFilter *bf, 284GNUNET_CONTAINER_bloomfilter_test (
287 const struct GNUNET_HashCode *e); 285 const struct GNUNET_CONTAINER_BloomFilter *bf,
286 const struct GNUNET_HashCode *e);
288 287
289 288
290/** 289/**
@@ -319,8 +318,8 @@ GNUNET_CONTAINER_bloomfilter_remove (struct GNUNET_CONTAINER_BloomFilter *bf,
319 * @return copy of bf 318 * @return copy of bf
320 */ 319 */
321struct GNUNET_CONTAINER_BloomFilter * 320struct GNUNET_CONTAINER_BloomFilter *
322GNUNET_CONTAINER_bloomfilter_copy (const struct GNUNET_CONTAINER_BloomFilter *bf); 321GNUNET_CONTAINER_bloomfilter_copy (
323 322 const struct GNUNET_CONTAINER_BloomFilter *bf);
324 323
325 324
326/** 325/**
@@ -342,7 +341,8 @@ GNUNET_CONTAINER_bloomfilter_free (struct GNUNET_CONTAINER_BloomFilter *bf);
342 * @return addresses set per element in the bf 341 * @return addresses set per element in the bf
343 */ 342 */
344size_t 343size_t
345GNUNET_CONTAINER_bloomfilter_get_element_addresses (const struct GNUNET_CONTAINER_BloomFilter *bf); 344GNUNET_CONTAINER_bloomfilter_get_element_addresses (
345 const struct GNUNET_CONTAINER_BloomFilter *bf);
346 346
347 347
348/** 348/**
@@ -353,7 +353,8 @@ GNUNET_CONTAINER_bloomfilter_get_element_addresses (const struct GNUNET_CONTAINE
353 * @return number of bytes used for the data of the bloom filter 353 * @return number of bytes used for the data of the bloom filter
354 */ 354 */
355size_t 355size_t
356GNUNET_CONTAINER_bloomfilter_get_size (const struct GNUNET_CONTAINER_BloomFilter *bf); 356GNUNET_CONTAINER_bloomfilter_get_size (
357 const struct GNUNET_CONTAINER_BloomFilter *bf);
357 358
358 359
359/** 360/**
@@ -380,7 +381,8 @@ GNUNET_CONTAINER_bloomfilter_clear (struct GNUNET_CONTAINER_BloomFilter *bf);
380 */ 381 */
381int 382int
382GNUNET_CONTAINER_bloomfilter_or (struct GNUNET_CONTAINER_BloomFilter *bf, 383GNUNET_CONTAINER_bloomfilter_or (struct GNUNET_CONTAINER_BloomFilter *bf,
383 const char *data, size_t size); 384 const char *data,
385 size_t size);
384 386
385 387
386/** 388/**
@@ -394,8 +396,9 @@ GNUNET_CONTAINER_bloomfilter_or (struct GNUNET_CONTAINER_BloomFilter *bf,
394 * @return #GNUNET_OK on success 396 * @return #GNUNET_OK on success
395 */ 397 */
396int 398int
397GNUNET_CONTAINER_bloomfilter_or2 (struct GNUNET_CONTAINER_BloomFilter *bf, 399GNUNET_CONTAINER_bloomfilter_or2 (
398 const struct GNUNET_CONTAINER_BloomFilter *to_or); 400 struct GNUNET_CONTAINER_BloomFilter *bf,
401 const struct GNUNET_CONTAINER_BloomFilter *to_or);
399 402
400 403
401/** 404/**
@@ -445,7 +448,8 @@ GNUNET_CONTAINER_meta_data_create (void);
445 * @return duplicate meta-data container 448 * @return duplicate meta-data container
446 */ 449 */
447struct GNUNET_CONTAINER_MetaData * 450struct GNUNET_CONTAINER_MetaData *
448GNUNET_CONTAINER_meta_data_duplicate (const struct GNUNET_CONTAINER_MetaData *md); 451GNUNET_CONTAINER_meta_data_duplicate (
452 const struct GNUNET_CONTAINER_MetaData *md);
449 453
450 454
451/** 455/**
@@ -470,8 +474,9 @@ GNUNET_CONTAINER_meta_data_destroy (struct GNUNET_CONTAINER_MetaData *md);
470 * @return #GNUNET_YES if they are equal 474 * @return #GNUNET_YES if they are equal
471 */ 475 */
472int 476int
473GNUNET_CONTAINER_meta_data_test_equal (const struct GNUNET_CONTAINER_MetaData *md1, 477GNUNET_CONTAINER_meta_data_test_equal (
474 const struct GNUNET_CONTAINER_MetaData *md2); 478 const struct GNUNET_CONTAINER_MetaData *md1,
479 const struct GNUNET_CONTAINER_MetaData *md2);
475 480
476 481
477/** 482/**
@@ -551,7 +556,8 @@ GNUNET_CONTAINER_meta_data_clear (struct GNUNET_CONTAINER_MetaData *md);
551 * @param md metadata to modify 556 * @param md metadata to modify
552 */ 557 */
553void 558void
554GNUNET_CONTAINER_meta_data_add_publication_date (struct GNUNET_CONTAINER_MetaData *md); 559GNUNET_CONTAINER_meta_data_add_publication_date (
560 struct GNUNET_CONTAINER_MetaData *md);
555 561
556 562
557/** 563/**
@@ -582,8 +588,9 @@ GNUNET_CONTAINER_meta_data_iterate (const struct GNUNET_CONTAINER_MetaData *md,
582 * @return NULL if no entry was found 588 * @return NULL if no entry was found
583 */ 589 */
584char * 590char *
585GNUNET_CONTAINER_meta_data_get_by_type (const struct GNUNET_CONTAINER_MetaData *md, 591GNUNET_CONTAINER_meta_data_get_by_type (
586 enum EXTRACTOR_MetaType type); 592 const struct GNUNET_CONTAINER_MetaData *md,
593 enum EXTRACTOR_MetaType type);
587 594
588 595
589/** 596/**
@@ -599,8 +606,9 @@ GNUNET_CONTAINER_meta_data_get_by_type (const struct GNUNET_CONTAINER_MetaData *
599 * otherwise client is responsible for freeing the value! 606 * otherwise client is responsible for freeing the value!
600 */ 607 */
601char * 608char *
602GNUNET_CONTAINER_meta_data_get_first_by_types (const struct GNUNET_CONTAINER_MetaData *md, 609GNUNET_CONTAINER_meta_data_get_first_by_types (
603 ...); 610 const struct GNUNET_CONTAINER_MetaData *md,
611 ...);
604 612
605/** 613/**
606 * @ingroup metadata 614 * @ingroup metadata
@@ -613,9 +621,9 @@ GNUNET_CONTAINER_meta_data_get_first_by_types (const struct GNUNET_CONTAINER_Met
613 * @return number of bytes in thumbnail, 0 if not available 621 * @return number of bytes in thumbnail, 0 if not available
614 */ 622 */
615size_t 623size_t
616GNUNET_CONTAINER_meta_data_get_thumbnail (const struct GNUNET_CONTAINER_MetaData *md, 624GNUNET_CONTAINER_meta_data_get_thumbnail (
617 unsigned char **thumb); 625 const struct GNUNET_CONTAINER_MetaData *md,
618 626 unsigned char **thumb);
619 627
620 628
621/** 629/**
@@ -661,10 +669,11 @@ enum GNUNET_CONTAINER_MetaDataSerializationOptions
661 * space) 669 * space)
662 */ 670 */
663ssize_t 671ssize_t
664GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData *md, 672GNUNET_CONTAINER_meta_data_serialize (
665 char **target, 673 const struct GNUNET_CONTAINER_MetaData *md,
666 size_t max, 674 char **target,
667 enum GNUNET_CONTAINER_MetaDataSerializationOptions opt); 675 size_t max,
676 enum GNUNET_CONTAINER_MetaDataSerializationOptions opt);
668 677
669 678
670/** 679/**
@@ -675,7 +684,8 @@ GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData *md
675 * @return number of bytes needed for serialization, -1 on error 684 * @return number of bytes needed for serialization, -1 on error
676 */ 685 */
677ssize_t 686ssize_t
678GNUNET_CONTAINER_meta_data_get_serialized_size (const struct GNUNET_CONTAINER_MetaData *md); 687GNUNET_CONTAINER_meta_data_get_serialized_size (
688 const struct GNUNET_CONTAINER_MetaData *md);
679 689
680 690
681/** 691/**
@@ -688,8 +698,7 @@ GNUNET_CONTAINER_meta_data_get_serialized_size (const struct GNUNET_CONTAINER_Me
688 * bad format) 698 * bad format)
689 */ 699 */
690struct GNUNET_CONTAINER_MetaData * 700struct GNUNET_CONTAINER_MetaData *
691GNUNET_CONTAINER_meta_data_deserialize (const char *input, 701GNUNET_CONTAINER_meta_data_deserialize (const char *input, size_t size);
692 size_t size);
693 702
694 703
695/* ******************************* HashMap **************************** */ 704/* ******************************* HashMap **************************** */
@@ -759,10 +768,10 @@ enum GNUNET_CONTAINER_MultiHashMapOption
759 * iterate, 768 * iterate,
760 * #GNUNET_NO if not. 769 * #GNUNET_NO if not.
761 */ 770 */
762typedef int 771typedef int (*GNUNET_CONTAINER_HashMapIterator) (
763(*GNUNET_CONTAINER_HashMapIterator) (void *cls, 772 void *cls,
764 const struct GNUNET_HashCode *key, 773 const struct GNUNET_HashCode *key,
765 void *value); 774 void *value);
766 775
767 776
768/** 777/**
@@ -782,8 +791,7 @@ typedef int
782 * @return NULL on error 791 * @return NULL on error
783 */ 792 */
784struct GNUNET_CONTAINER_MultiHashMap * 793struct GNUNET_CONTAINER_MultiHashMap *
785GNUNET_CONTAINER_multihashmap_create (unsigned int len, 794GNUNET_CONTAINER_multihashmap_create (unsigned int len, int do_not_copy_keys);
786 int do_not_copy_keys);
787 795
788 796
789/** 797/**
@@ -794,7 +802,8 @@ GNUNET_CONTAINER_multihashmap_create (unsigned int len,
794 * @param map the map 802 * @param map the map
795 */ 803 */
796void 804void
797GNUNET_CONTAINER_multihashmap_destroy (struct GNUNET_CONTAINER_MultiHashMap *map); 805GNUNET_CONTAINER_multihashmap_destroy (
806 struct GNUNET_CONTAINER_MultiHashMap *map);
798 807
799 808
800/** 809/**
@@ -809,8 +818,9 @@ GNUNET_CONTAINER_multihashmap_destroy (struct GNUNET_CONTAINER_MultiHashMap *map
809 * key-value pairs with value NULL 818 * key-value pairs with value NULL
810 */ 819 */
811void * 820void *
812GNUNET_CONTAINER_multihashmap_get (const struct GNUNET_CONTAINER_MultiHashMap *map, 821GNUNET_CONTAINER_multihashmap_get (
813 const struct GNUNET_HashCode *key); 822 const struct GNUNET_CONTAINER_MultiHashMap *map,
823 const struct GNUNET_HashCode *key);
814 824
815 825
816/** 826/**
@@ -828,7 +838,7 @@ GNUNET_CONTAINER_multihashmap_get (const struct GNUNET_CONTAINER_MultiHashMap *m
828int 838int
829GNUNET_CONTAINER_multihashmap_remove (struct GNUNET_CONTAINER_MultiHashMap *map, 839GNUNET_CONTAINER_multihashmap_remove (struct GNUNET_CONTAINER_MultiHashMap *map,
830 const struct GNUNET_HashCode *key, 840 const struct GNUNET_HashCode *key,
831 const void *value); 841 const void *value);
832 842
833/** 843/**
834 * @ingroup hashmap 844 * @ingroup hashmap
@@ -840,8 +850,9 @@ GNUNET_CONTAINER_multihashmap_remove (struct GNUNET_CONTAINER_MultiHashMap *map,
840 * @return number of values removed 850 * @return number of values removed
841 */ 851 */
842int 852int
843GNUNET_CONTAINER_multihashmap_remove_all (struct GNUNET_CONTAINER_MultiHashMap *map, 853GNUNET_CONTAINER_multihashmap_remove_all (
844 const struct GNUNET_HashCode *key); 854 struct GNUNET_CONTAINER_MultiHashMap *map,
855 const struct GNUNET_HashCode *key);
845 856
846 857
847/** 858/**
@@ -867,8 +878,9 @@ GNUNET_CONTAINER_multihashmap_clear (struct GNUNET_CONTAINER_MultiHashMap *map);
867 * #GNUNET_NO if not 878 * #GNUNET_NO if not
868 */ 879 */
869int 880int
870GNUNET_CONTAINER_multihashmap_contains (const struct GNUNET_CONTAINER_MultiHashMap *map, 881GNUNET_CONTAINER_multihashmap_contains (
871 const struct GNUNET_HashCode * key); 882 const struct GNUNET_CONTAINER_MultiHashMap *map,
883 const struct GNUNET_HashCode *key);
872 884
873 885
874/** 886/**
@@ -883,9 +895,10 @@ GNUNET_CONTAINER_multihashmap_contains (const struct GNUNET_CONTAINER_MultiHashM
883 * #GNUNET_NO if not 895 * #GNUNET_NO if not
884 */ 896 */
885int 897int
886GNUNET_CONTAINER_multihashmap_contains_value (const struct GNUNET_CONTAINER_MultiHashMap *map, 898GNUNET_CONTAINER_multihashmap_contains_value (
887 const struct GNUNET_HashCode *key, 899 const struct GNUNET_CONTAINER_MultiHashMap *map,
888 const void *value); 900 const struct GNUNET_HashCode *key,
901 const void *value);
889 902
890 903
891/** 904/**
@@ -902,11 +915,11 @@ GNUNET_CONTAINER_multihashmap_contains_value (const struct GNUNET_CONTAINER_Mult
902 * value already exists 915 * value already exists
903 */ 916 */
904int 917int
905GNUNET_CONTAINER_multihashmap_put (struct GNUNET_CONTAINER_MultiHashMap *map, 918GNUNET_CONTAINER_multihashmap_put (
906 const struct GNUNET_HashCode *key, 919 struct GNUNET_CONTAINER_MultiHashMap *map,
907 void *value, 920 const struct GNUNET_HashCode *key,
908 enum GNUNET_CONTAINER_MultiHashMapOption 921 void *value,
909 opt); 922 enum GNUNET_CONTAINER_MultiHashMapOption opt);
910 923
911/** 924/**
912 * @ingroup hashmap 925 * @ingroup hashmap
@@ -916,7 +929,8 @@ GNUNET_CONTAINER_multihashmap_put (struct GNUNET_CONTAINER_MultiHashMap *map,
916 * @return the number of key value pairs 929 * @return the number of key value pairs
917 */ 930 */
918unsigned int 931unsigned int
919GNUNET_CONTAINER_multihashmap_size (const struct GNUNET_CONTAINER_MultiHashMap *map); 932GNUNET_CONTAINER_multihashmap_size (
933 const struct GNUNET_CONTAINER_MultiHashMap *map);
920 934
921 935
922/** 936/**
@@ -930,9 +944,10 @@ GNUNET_CONTAINER_multihashmap_size (const struct GNUNET_CONTAINER_MultiHashMap *
930 * #GNUNET_SYSERR if it aborted iteration 944 * #GNUNET_SYSERR if it aborted iteration
931 */ 945 */
932int 946int
933GNUNET_CONTAINER_multihashmap_iterate (struct GNUNET_CONTAINER_MultiHashMap *map, 947GNUNET_CONTAINER_multihashmap_iterate (
934 GNUNET_CONTAINER_HashMapIterator it, 948 struct GNUNET_CONTAINER_MultiHashMap *map,
935 void *it_cls); 949 GNUNET_CONTAINER_HashMapIterator it,
950 void *it_cls);
936 951
937 952
938/** 953/**
@@ -949,7 +964,8 @@ GNUNET_CONTAINER_multihashmap_iterate (struct GNUNET_CONTAINER_MultiHashMap *map
949 * @return an iterator over the given multihashmap @a map 964 * @return an iterator over the given multihashmap @a map
950 */ 965 */
951struct GNUNET_CONTAINER_MultiHashMapIterator * 966struct GNUNET_CONTAINER_MultiHashMapIterator *
952GNUNET_CONTAINER_multihashmap_iterator_create (const struct GNUNET_CONTAINER_MultiHashMap *map); 967GNUNET_CONTAINER_multihashmap_iterator_create (
968 const struct GNUNET_CONTAINER_MultiHashMap *map);
953 969
954 970
955/** 971/**
@@ -968,9 +984,10 @@ GNUNET_CONTAINER_multihashmap_iterator_create (const struct GNUNET_CONTAINER_Mul
968 * #GNUNET_NO if we are out of elements 984 * #GNUNET_NO if we are out of elements
969 */ 985 */
970int 986int
971GNUNET_CONTAINER_multihashmap_iterator_next (struct GNUNET_CONTAINER_MultiHashMapIterator *iter, 987GNUNET_CONTAINER_multihashmap_iterator_next (
972 struct GNUNET_HashCode *key, 988 struct GNUNET_CONTAINER_MultiHashMapIterator *iter,
973 const void **value); 989 struct GNUNET_HashCode *key,
990 const void **value);
974 991
975 992
976/** 993/**
@@ -980,7 +997,8 @@ GNUNET_CONTAINER_multihashmap_iterator_next (struct GNUNET_CONTAINER_MultiHashMa
980 * @param iter the iterator to destroy 997 * @param iter the iterator to destroy
981 */ 998 */
982void 999void
983GNUNET_CONTAINER_multihashmap_iterator_destroy (struct GNUNET_CONTAINER_MultiHashMapIterator *iter); 1000GNUNET_CONTAINER_multihashmap_iterator_destroy (
1001 struct GNUNET_CONTAINER_MultiHashMapIterator *iter);
984 1002
985 1003
986/** 1004/**
@@ -995,10 +1013,11 @@ GNUNET_CONTAINER_multihashmap_iterator_destroy (struct GNUNET_CONTAINER_MultiHas
995 * #GNUNET_SYSERR if it aborted iteration 1013 * #GNUNET_SYSERR if it aborted iteration
996 */ 1014 */
997int 1015int
998GNUNET_CONTAINER_multihashmap_get_multiple (struct GNUNET_CONTAINER_MultiHashMap *map, 1016GNUNET_CONTAINER_multihashmap_get_multiple (
999 const struct GNUNET_HashCode *key, 1017 struct GNUNET_CONTAINER_MultiHashMap *map,
1000 GNUNET_CONTAINER_HashMapIterator it, 1018 const struct GNUNET_HashCode *key,
1001 void *it_cls); 1019 GNUNET_CONTAINER_HashMapIterator it,
1020 void *it_cls);
1002 1021
1003 1022
1004/** 1023/**
@@ -1013,9 +1032,10 @@ GNUNET_CONTAINER_multihashmap_get_multiple (struct GNUNET_CONTAINER_MultiHashMap
1013 * @return the number of key value pairs processed, zero or one. 1032 * @return the number of key value pairs processed, zero or one.
1014 */ 1033 */
1015unsigned int 1034unsigned int
1016GNUNET_CONTAINER_multihashmap_get_random (const struct GNUNET_CONTAINER_MultiHashMap *map, 1035GNUNET_CONTAINER_multihashmap_get_random (
1017 GNUNET_CONTAINER_HashMapIterator it, 1036 const struct GNUNET_CONTAINER_MultiHashMap *map,
1018 void *it_cls); 1037 GNUNET_CONTAINER_HashMapIterator it,
1038 void *it_cls);
1019 1039
1020 1040
1021/* ***************** Version of Multihashmap for peer identities ****************** */ 1041/* ***************** Version of Multihashmap for peer identities ****************** */
@@ -1031,10 +1051,10 @@ GNUNET_CONTAINER_multihashmap_get_random (const struct GNUNET_CONTAINER_MultiHas
1031 * iterate, 1051 * iterate,
1032 * #GNUNET_NO if not. 1052 * #GNUNET_NO if not.
1033 */ 1053 */
1034typedef int 1054typedef int (*GNUNET_CONTAINER_PeerMapIterator) (
1035(*GNUNET_CONTAINER_PeerMapIterator) (void *cls, 1055 void *cls,
1036 const struct GNUNET_PeerIdentity *key, 1056 const struct GNUNET_PeerIdentity *key,
1037 void *value); 1057 void *value);
1038 1058
1039 1059
1040/** 1060/**
@@ -1060,8 +1080,7 @@ struct GNUNET_CONTAINER_MultiPeerMap;
1060 * @return NULL on error 1080 * @return NULL on error
1061 */ 1081 */
1062struct GNUNET_CONTAINER_MultiPeerMap * 1082struct GNUNET_CONTAINER_MultiPeerMap *
1063GNUNET_CONTAINER_multipeermap_create (unsigned int len, 1083GNUNET_CONTAINER_multipeermap_create (unsigned int len, int do_not_copy_keys);
1064 int do_not_copy_keys);
1065 1084
1066 1085
1067/** 1086/**
@@ -1072,7 +1091,8 @@ GNUNET_CONTAINER_multipeermap_create (unsigned int len,
1072 * @param map the map 1091 * @param map the map
1073 */ 1092 */
1074void 1093void
1075GNUNET_CONTAINER_multipeermap_destroy (struct GNUNET_CONTAINER_MultiPeerMap *map); 1094GNUNET_CONTAINER_multipeermap_destroy (
1095 struct GNUNET_CONTAINER_MultiPeerMap *map);
1076 1096
1077 1097
1078/** 1098/**
@@ -1087,8 +1107,9 @@ GNUNET_CONTAINER_multipeermap_destroy (struct GNUNET_CONTAINER_MultiPeerMap *map
1087 * key-value pairs with value NULL 1107 * key-value pairs with value NULL
1088 */ 1108 */
1089void * 1109void *
1090GNUNET_CONTAINER_multipeermap_get (const struct GNUNET_CONTAINER_MultiPeerMap *map, 1110GNUNET_CONTAINER_multipeermap_get (
1091 const struct GNUNET_PeerIdentity *key); 1111 const struct GNUNET_CONTAINER_MultiPeerMap *map,
1112 const struct GNUNET_PeerIdentity *key);
1092 1113
1093 1114
1094/** 1115/**
@@ -1105,8 +1126,8 @@ GNUNET_CONTAINER_multipeermap_get (const struct GNUNET_CONTAINER_MultiPeerMap *m
1105 */ 1126 */
1106int 1127int
1107GNUNET_CONTAINER_multipeermap_remove (struct GNUNET_CONTAINER_MultiPeerMap *map, 1128GNUNET_CONTAINER_multipeermap_remove (struct GNUNET_CONTAINER_MultiPeerMap *map,
1108 const struct GNUNET_PeerIdentity * key, 1129 const struct GNUNET_PeerIdentity *key,
1109 const void *value); 1130 const void *value);
1110 1131
1111/** 1132/**
1112 * @ingroup hashmap 1133 * @ingroup hashmap
@@ -1118,8 +1139,9 @@ GNUNET_CONTAINER_multipeermap_remove (struct GNUNET_CONTAINER_MultiPeerMap *map,
1118 * @return number of values removed 1139 * @return number of values removed
1119 */ 1140 */
1120int 1141int
1121GNUNET_CONTAINER_multipeermap_remove_all (struct GNUNET_CONTAINER_MultiPeerMap *map, 1142GNUNET_CONTAINER_multipeermap_remove_all (
1122 const struct GNUNET_PeerIdentity *key); 1143 struct GNUNET_CONTAINER_MultiPeerMap *map,
1144 const struct GNUNET_PeerIdentity *key);
1123 1145
1124 1146
1125/** 1147/**
@@ -1133,8 +1155,9 @@ GNUNET_CONTAINER_multipeermap_remove_all (struct GNUNET_CONTAINER_MultiPeerMap *
1133 * #GNUNET_NO if not 1155 * #GNUNET_NO if not
1134 */ 1156 */
1135int 1157int
1136GNUNET_CONTAINER_multipeermap_contains (const struct GNUNET_CONTAINER_MultiPeerMap *map, 1158GNUNET_CONTAINER_multipeermap_contains (
1137 const struct GNUNET_PeerIdentity *key); 1159 const struct GNUNET_CONTAINER_MultiPeerMap *map,
1160 const struct GNUNET_PeerIdentity *key);
1138 1161
1139 1162
1140/** 1163/**
@@ -1149,9 +1172,10 @@ GNUNET_CONTAINER_multipeermap_contains (const struct GNUNET_CONTAINER_MultiPeerM
1149 * #GNUNET_NO if not 1172 * #GNUNET_NO if not
1150 */ 1173 */
1151int 1174int
1152GNUNET_CONTAINER_multipeermap_contains_value (const struct GNUNET_CONTAINER_MultiPeerMap *map, 1175GNUNET_CONTAINER_multipeermap_contains_value (
1153 const struct GNUNET_PeerIdentity * key, 1176 const struct GNUNET_CONTAINER_MultiPeerMap *map,
1154 const void *value); 1177 const struct GNUNET_PeerIdentity *key,
1178 const void *value);
1155 1179
1156 1180
1157/** 1181/**
@@ -1168,10 +1192,11 @@ GNUNET_CONTAINER_multipeermap_contains_value (const struct GNUNET_CONTAINER_Mult
1168 * value already exists 1192 * value already exists
1169 */ 1193 */
1170int 1194int
1171GNUNET_CONTAINER_multipeermap_put (struct GNUNET_CONTAINER_MultiPeerMap *map, 1195GNUNET_CONTAINER_multipeermap_put (
1172 const struct GNUNET_PeerIdentity *key, 1196 struct GNUNET_CONTAINER_MultiPeerMap *map,
1173 void *value, 1197 const struct GNUNET_PeerIdentity *key,
1174 enum GNUNET_CONTAINER_MultiHashMapOption opt); 1198 void *value,
1199 enum GNUNET_CONTAINER_MultiHashMapOption opt);
1175 1200
1176 1201
1177/** 1202/**
@@ -1182,7 +1207,8 @@ GNUNET_CONTAINER_multipeermap_put (struct GNUNET_CONTAINER_MultiPeerMap *map,
1182 * @return the number of key value pairs 1207 * @return the number of key value pairs
1183 */ 1208 */
1184unsigned int 1209unsigned int
1185GNUNET_CONTAINER_multipeermap_size (const struct GNUNET_CONTAINER_MultiPeerMap *map); 1210GNUNET_CONTAINER_multipeermap_size (
1211 const struct GNUNET_CONTAINER_MultiPeerMap *map);
1186 1212
1187 1213
1188/** 1214/**
@@ -1196,9 +1222,10 @@ GNUNET_CONTAINER_multipeermap_size (const struct GNUNET_CONTAINER_MultiPeerMap *
1196 * #GNUNET_SYSERR if it aborted iteration 1222 * #GNUNET_SYSERR if it aborted iteration
1197 */ 1223 */
1198int 1224int
1199GNUNET_CONTAINER_multipeermap_iterate (struct GNUNET_CONTAINER_MultiPeerMap *map, 1225GNUNET_CONTAINER_multipeermap_iterate (
1200 GNUNET_CONTAINER_PeerMapIterator it, 1226 struct GNUNET_CONTAINER_MultiPeerMap *map,
1201 void *it_cls); 1227 GNUNET_CONTAINER_PeerMapIterator it,
1228 void *it_cls);
1202 1229
1203 1230
1204struct GNUNET_CONTAINER_MultiPeerMapIterator; 1231struct GNUNET_CONTAINER_MultiPeerMapIterator;
@@ -1216,7 +1243,8 @@ struct GNUNET_CONTAINER_MultiPeerMapIterator;
1216 * @return an iterator over the given multihashmap @a map 1243 * @return an iterator over the given multihashmap @a map
1217 */ 1244 */
1218struct GNUNET_CONTAINER_MultiPeerMapIterator * 1245struct GNUNET_CONTAINER_MultiPeerMapIterator *
1219GNUNET_CONTAINER_multipeermap_iterator_create (const struct GNUNET_CONTAINER_MultiPeerMap *map); 1246GNUNET_CONTAINER_multipeermap_iterator_create (
1247 const struct GNUNET_CONTAINER_MultiPeerMap *map);
1220 1248
1221 1249
1222/** 1250/**
@@ -1235,9 +1263,10 @@ GNUNET_CONTAINER_multipeermap_iterator_create (const struct GNUNET_CONTAINER_Mul
1235 * #GNUNET_NO if we are out of elements 1263 * #GNUNET_NO if we are out of elements
1236 */ 1264 */
1237int 1265int
1238GNUNET_CONTAINER_multipeermap_iterator_next (struct GNUNET_CONTAINER_MultiPeerMapIterator *iter, 1266GNUNET_CONTAINER_multipeermap_iterator_next (
1239 struct GNUNET_PeerIdentity *key, 1267 struct GNUNET_CONTAINER_MultiPeerMapIterator *iter,
1240 const void **value); 1268 struct GNUNET_PeerIdentity *key,
1269 const void **value);
1241 1270
1242 1271
1243/** 1272/**
@@ -1247,7 +1276,8 @@ GNUNET_CONTAINER_multipeermap_iterator_next (struct GNUNET_CONTAINER_MultiPeerMa
1247 * @param iter the iterator to destroy 1276 * @param iter the iterator to destroy
1248 */ 1277 */
1249void 1278void
1250GNUNET_CONTAINER_multipeermap_iterator_destroy (struct GNUNET_CONTAINER_MultiPeerMapIterator *iter); 1279GNUNET_CONTAINER_multipeermap_iterator_destroy (
1280 struct GNUNET_CONTAINER_MultiPeerMapIterator *iter);
1251 1281
1252 1282
1253/** 1283/**
@@ -1262,10 +1292,11 @@ GNUNET_CONTAINER_multipeermap_iterator_destroy (struct GNUNET_CONTAINER_MultiPee
1262 * #GNUNET_SYSERR if it aborted iteration 1292 * #GNUNET_SYSERR if it aborted iteration
1263 */ 1293 */
1264int 1294int
1265GNUNET_CONTAINER_multipeermap_get_multiple (struct GNUNET_CONTAINER_MultiPeerMap *map, 1295GNUNET_CONTAINER_multipeermap_get_multiple (
1266 const struct GNUNET_PeerIdentity *key, 1296 struct GNUNET_CONTAINER_MultiPeerMap *map,
1267 GNUNET_CONTAINER_PeerMapIterator it, 1297 const struct GNUNET_PeerIdentity *key,
1268 void *it_cls); 1298 GNUNET_CONTAINER_PeerMapIterator it,
1299 void *it_cls);
1269 1300
1270 1301
1271/** 1302/**
@@ -1280,9 +1311,10 @@ GNUNET_CONTAINER_multipeermap_get_multiple (struct GNUNET_CONTAINER_MultiPeerMap
1280 * @return the number of key value pairs processed, zero or one. 1311 * @return the number of key value pairs processed, zero or one.
1281 */ 1312 */
1282unsigned int 1313unsigned int
1283GNUNET_CONTAINER_multipeermap_get_random (const struct GNUNET_CONTAINER_MultiPeerMap *map, 1314GNUNET_CONTAINER_multipeermap_get_random (
1284 GNUNET_CONTAINER_PeerMapIterator it, 1315 const struct GNUNET_CONTAINER_MultiPeerMap *map,
1285 void *it_cls); 1316 GNUNET_CONTAINER_PeerMapIterator it,
1317 void *it_cls);
1286 1318
1287 1319
1288/* ***************** Version of Multihashmap for short hashes ****************** */ 1320/* ***************** Version of Multihashmap for short hashes ****************** */
@@ -1298,10 +1330,10 @@ GNUNET_CONTAINER_multipeermap_get_random (const struct GNUNET_CONTAINER_MultiPee
1298 * iterate, 1330 * iterate,
1299 * #GNUNET_NO if not. 1331 * #GNUNET_NO if not.
1300 */ 1332 */
1301typedef int 1333typedef int (*GNUNET_CONTAINER_ShortmapIterator) (
1302(*GNUNET_CONTAINER_ShortmapIterator) (void *cls, 1334 void *cls,
1303 const struct GNUNET_ShortHashCode *key, 1335 const struct GNUNET_ShortHashCode *key,
1304 void *value); 1336 void *value);
1305 1337
1306 1338
1307/** 1339/**
@@ -1327,8 +1359,7 @@ struct GNUNET_CONTAINER_MultiShortmap;
1327 * @return NULL on error 1359 * @return NULL on error
1328 */ 1360 */
1329struct GNUNET_CONTAINER_MultiShortmap * 1361struct GNUNET_CONTAINER_MultiShortmap *
1330GNUNET_CONTAINER_multishortmap_create (unsigned int len, 1362GNUNET_CONTAINER_multishortmap_create (unsigned int len, int do_not_copy_keys);
1331 int do_not_copy_keys);
1332 1363
1333 1364
1334/** 1365/**
@@ -1339,7 +1370,8 @@ GNUNET_CONTAINER_multishortmap_create (unsigned int len,
1339 * @param map the map 1370 * @param map the map
1340 */ 1371 */
1341void 1372void
1342GNUNET_CONTAINER_multishortmap_destroy (struct GNUNET_CONTAINER_MultiShortmap *map); 1373GNUNET_CONTAINER_multishortmap_destroy (
1374 struct GNUNET_CONTAINER_MultiShortmap *map);
1343 1375
1344 1376
1345/** 1377/**
@@ -1354,8 +1386,9 @@ GNUNET_CONTAINER_multishortmap_destroy (struct GNUNET_CONTAINER_MultiShortmap *m
1354 * key-value pairs with value NULL 1386 * key-value pairs with value NULL
1355 */ 1387 */
1356void * 1388void *
1357GNUNET_CONTAINER_multishortmap_get (const struct GNUNET_CONTAINER_MultiShortmap *map, 1389GNUNET_CONTAINER_multishortmap_get (
1358 const struct GNUNET_ShortHashCode *key); 1390 const struct GNUNET_CONTAINER_MultiShortmap *map,
1391 const struct GNUNET_ShortHashCode *key);
1359 1392
1360 1393
1361/** 1394/**
@@ -1371,9 +1404,10 @@ GNUNET_CONTAINER_multishortmap_get (const struct GNUNET_CONTAINER_MultiShortmap
1371 * is not in the map 1404 * is not in the map
1372 */ 1405 */
1373int 1406int
1374GNUNET_CONTAINER_multishortmap_remove (struct GNUNET_CONTAINER_MultiShortmap *map, 1407GNUNET_CONTAINER_multishortmap_remove (
1375 const struct GNUNET_ShortHashCode * key, 1408 struct GNUNET_CONTAINER_MultiShortmap *map,
1376 const void *value); 1409 const struct GNUNET_ShortHashCode *key,
1410 const void *value);
1377 1411
1378/** 1412/**
1379 * @ingroup hashmap 1413 * @ingroup hashmap
@@ -1385,8 +1419,9 @@ GNUNET_CONTAINER_multishortmap_remove (struct GNUNET_CONTAINER_MultiShortmap *ma
1385 * @return number of values removed 1419 * @return number of values removed
1386 */ 1420 */
1387int 1421int
1388GNUNET_CONTAINER_multishortmap_remove_all (struct GNUNET_CONTAINER_MultiShortmap *map, 1422GNUNET_CONTAINER_multishortmap_remove_all (
1389 const struct GNUNET_ShortHashCode *key); 1423 struct GNUNET_CONTAINER_MultiShortmap *map,
1424 const struct GNUNET_ShortHashCode *key);
1390 1425
1391 1426
1392/** 1427/**
@@ -1400,8 +1435,9 @@ GNUNET_CONTAINER_multishortmap_remove_all (struct GNUNET_CONTAINER_MultiShortmap
1400 * #GNUNET_NO if not 1435 * #GNUNET_NO if not
1401 */ 1436 */
1402int 1437int
1403GNUNET_CONTAINER_multishortmap_contains (const struct GNUNET_CONTAINER_MultiShortmap *map, 1438GNUNET_CONTAINER_multishortmap_contains (
1404 const struct GNUNET_ShortHashCode *key); 1439 const struct GNUNET_CONTAINER_MultiShortmap *map,
1440 const struct GNUNET_ShortHashCode *key);
1405 1441
1406 1442
1407/** 1443/**
@@ -1416,9 +1452,10 @@ GNUNET_CONTAINER_multishortmap_contains (const struct GNUNET_CONTAINER_MultiShor
1416 * #GNUNET_NO if not 1452 * #GNUNET_NO if not
1417 */ 1453 */
1418int 1454int
1419GNUNET_CONTAINER_multishortmap_contains_value (const struct GNUNET_CONTAINER_MultiShortmap *map, 1455GNUNET_CONTAINER_multishortmap_contains_value (
1420 const struct GNUNET_ShortHashCode * key, 1456 const struct GNUNET_CONTAINER_MultiShortmap *map,
1421 const void *value); 1457 const struct GNUNET_ShortHashCode *key,
1458 const void *value);
1422 1459
1423 1460
1424/** 1461/**
@@ -1435,10 +1472,11 @@ GNUNET_CONTAINER_multishortmap_contains_value (const struct GNUNET_CONTAINER_Mul
1435 * value already exists 1472 * value already exists
1436 */ 1473 */
1437int 1474int
1438GNUNET_CONTAINER_multishortmap_put (struct GNUNET_CONTAINER_MultiShortmap *map, 1475GNUNET_CONTAINER_multishortmap_put (
1439 const struct GNUNET_ShortHashCode *key, 1476 struct GNUNET_CONTAINER_MultiShortmap *map,
1440 void *value, 1477 const struct GNUNET_ShortHashCode *key,
1441 enum GNUNET_CONTAINER_MultiHashMapOption opt); 1478 void *value,
1479 enum GNUNET_CONTAINER_MultiHashMapOption opt);
1442 1480
1443 1481
1444/** 1482/**
@@ -1449,7 +1487,8 @@ GNUNET_CONTAINER_multishortmap_put (struct GNUNET_CONTAINER_MultiShortmap *map,
1449 * @return the number of key value pairs 1487 * @return the number of key value pairs
1450 */ 1488 */
1451unsigned int 1489unsigned int
1452GNUNET_CONTAINER_multishortmap_size (const struct GNUNET_CONTAINER_MultiShortmap *map); 1490GNUNET_CONTAINER_multishortmap_size (
1491 const struct GNUNET_CONTAINER_MultiShortmap *map);
1453 1492
1454 1493
1455/** 1494/**
@@ -1463,9 +1502,10 @@ GNUNET_CONTAINER_multishortmap_size (const struct GNUNET_CONTAINER_MultiShortmap
1463 * #GNUNET_SYSERR if it aborted iteration 1502 * #GNUNET_SYSERR if it aborted iteration
1464 */ 1503 */
1465int 1504int
1466GNUNET_CONTAINER_multishortmap_iterate (struct GNUNET_CONTAINER_MultiShortmap *map, 1505GNUNET_CONTAINER_multishortmap_iterate (
1467 GNUNET_CONTAINER_ShortmapIterator it, 1506 struct GNUNET_CONTAINER_MultiShortmap *map,
1468 void *it_cls); 1507 GNUNET_CONTAINER_ShortmapIterator it,
1508 void *it_cls);
1469 1509
1470 1510
1471struct GNUNET_CONTAINER_MultiShortmapIterator; 1511struct GNUNET_CONTAINER_MultiShortmapIterator;
@@ -1485,7 +1525,8 @@ struct GNUNET_CONTAINER_MultiShortmapIterator;
1485 * @return an iterator over the given multihashmap @a map 1525 * @return an iterator over the given multihashmap @a map
1486 */ 1526 */
1487struct GNUNET_CONTAINER_MultiShortmapIterator * 1527struct GNUNET_CONTAINER_MultiShortmapIterator *
1488GNUNET_CONTAINER_multishortmap_iterator_create (const struct GNUNET_CONTAINER_MultiShortmap *map); 1528GNUNET_CONTAINER_multishortmap_iterator_create (
1529 const struct GNUNET_CONTAINER_MultiShortmap *map);
1489 1530
1490 1531
1491/** 1532/**
@@ -1504,9 +1545,10 @@ GNUNET_CONTAINER_multishortmap_iterator_create (const struct GNUNET_CONTAINER_Mu
1504 * #GNUNET_NO if we are out of elements 1545 * #GNUNET_NO if we are out of elements
1505 */ 1546 */
1506int 1547int
1507GNUNET_CONTAINER_multishortmap_iterator_next (struct GNUNET_CONTAINER_MultiShortmapIterator *iter, 1548GNUNET_CONTAINER_multishortmap_iterator_next (
1508 struct GNUNET_ShortHashCode *key, 1549 struct GNUNET_CONTAINER_MultiShortmapIterator *iter,
1509 const void **value); 1550 struct GNUNET_ShortHashCode *key,
1551 const void **value);
1510 1552
1511 1553
1512/** 1554/**
@@ -1516,7 +1558,8 @@ GNUNET_CONTAINER_multishortmap_iterator_next (struct GNUNET_CONTAINER_MultiShort
1516 * @param iter the iterator to destroy 1558 * @param iter the iterator to destroy
1517 */ 1559 */
1518void 1560void
1519GNUNET_CONTAINER_multishortmap_iterator_destroy (struct GNUNET_CONTAINER_MultiShortmapIterator *iter); 1561GNUNET_CONTAINER_multishortmap_iterator_destroy (
1562 struct GNUNET_CONTAINER_MultiShortmapIterator *iter);
1520 1563
1521 1564
1522/** 1565/**
@@ -1531,10 +1574,11 @@ GNUNET_CONTAINER_multishortmap_iterator_destroy (struct GNUNET_CONTAINER_MultiSh
1531 * #GNUNET_SYSERR if it aborted iteration 1574 * #GNUNET_SYSERR if it aborted iteration
1532 */ 1575 */
1533int 1576int
1534GNUNET_CONTAINER_multishortmap_get_multiple (struct GNUNET_CONTAINER_MultiShortmap *map, 1577GNUNET_CONTAINER_multishortmap_get_multiple (
1535 const struct GNUNET_ShortHashCode *key, 1578 struct GNUNET_CONTAINER_MultiShortmap *map,
1536 GNUNET_CONTAINER_ShortmapIterator it, 1579 const struct GNUNET_ShortHashCode *key,
1537 void *it_cls); 1580 GNUNET_CONTAINER_ShortmapIterator it,
1581 void *it_cls);
1538 1582
1539 1583
1540/** 1584/**
@@ -1549,9 +1593,292 @@ GNUNET_CONTAINER_multishortmap_get_multiple (struct GNUNET_CONTAINER_MultiShortm
1549 * @return the number of key value pairs processed, zero or one. 1593 * @return the number of key value pairs processed, zero or one.
1550 */ 1594 */
1551unsigned int 1595unsigned int
1552GNUNET_CONTAINER_multishortmap_get_random (const struct GNUNET_CONTAINER_MultiShortmap *map, 1596GNUNET_CONTAINER_multishortmap_get_random (
1553 GNUNET_CONTAINER_ShortmapIterator it, 1597 const struct GNUNET_CONTAINER_MultiShortmap *map,
1554 void *it_cls); 1598 GNUNET_CONTAINER_ShortmapIterator it,
1599 void *it_cls);
1600
1601
1602/* ***************** Version of Multihashmap for UUIDs ****************** */
1603
1604
1605/**
1606 * @ingroup hashmap
1607 * Iterator over uuid map entries.
1608 *
1609 * @param cls closure
1610 * @param key current public key
1611 * @param value value in the hash map
1612 * @return #GNUNET_YES if we should continue to
1613 * iterate,
1614 * #GNUNET_NO if not.
1615 */
1616typedef int (*GNUNET_CONTAINER_MultiUuidmapIterator) (
1617 void *cls,
1618 const struct GNUNET_Uuid *key,
1619 void *value);
1620
1621
1622/**
1623 * Hash map from peer identities to values.
1624 */
1625struct GNUNET_CONTAINER_MultiUuidmap;
1626
1627
1628/**
1629 * @ingroup hashmap
1630 * Create a multi peer map (hash map for public keys of peers).
1631 *
1632 * @param len initial size (map will grow as needed)
1633 * @param do_not_copy_keys #GNUNET_NO is always safe and should be used by default;
1634 * #GNUNET_YES means that on 'put', the 'key' does not have
1635 * to be copied as the destination of the pointer is
1636 * guaranteed to be life as long as the value is stored in
1637 * the hashmap. This can significantly reduce memory
1638 * consumption, but of course is also a recipie for
1639 * heap corruption if the assumption is not true. Only
1640 * use this if (1) memory use is important in this case and
1641 * (2) you have triple-checked that the invariant holds
1642 * @return NULL on error
1643 */
1644struct GNUNET_CONTAINER_MultiUuidmap *
1645GNUNET_CONTAINER_multiuuidmap_create (unsigned int len, int do_not_copy_keys);
1646
1647
1648/**
1649 * @ingroup hashmap
1650 * Destroy a hash map. Will not free any values
1651 * stored in the hash map!
1652 *
1653 * @param map the map
1654 */
1655void
1656GNUNET_CONTAINER_multiuuidmap_destroy (
1657 struct GNUNET_CONTAINER_MultiUuidmap *map);
1658
1659
1660/**
1661 * @ingroup hashmap
1662 * Given a key find a value in the map matching the key.
1663 *
1664 * @param map the map
1665 * @param key what to look for
1666 * @return NULL if no value was found; note that
1667 * this is indistinguishable from values that just
1668 * happen to be NULL; use "contains" to test for
1669 * key-value pairs with value NULL
1670 */
1671void *
1672GNUNET_CONTAINER_multiuuidmap_get (
1673 const struct GNUNET_CONTAINER_MultiUuidmap *map,
1674 const struct GNUNET_Uuid *key);
1675
1676
1677/**
1678 * @ingroup hashmap
1679 * Remove the given key-value pair from the map. Note that if the
1680 * key-value pair is in the map multiple times, only one of the pairs
1681 * will be removed.
1682 *
1683 * @param map the map
1684 * @param key key of the key-value pair
1685 * @param value value of the key-value pair
1686 * @return #GNUNET_YES on success, #GNUNET_NO if the key-value pair
1687 * is not in the map
1688 */
1689int
1690GNUNET_CONTAINER_multiuuidmap_remove (struct GNUNET_CONTAINER_MultiUuidmap *map,
1691 const struct GNUNET_Uuid *key,
1692 const void *value);
1693
1694/**
1695 * @ingroup hashmap
1696 * Remove all entries for the given key from the map.
1697 * Note that the values would not be "freed".
1698 *
1699 * @param map the map
1700 * @param key identifies values to be removed
1701 * @return number of values removed
1702 */
1703int
1704GNUNET_CONTAINER_multiuuidmap_remove_all (
1705 struct GNUNET_CONTAINER_MultiUuidmap *map,
1706 const struct GNUNET_Uuid *key);
1707
1708
1709/**
1710 * @ingroup hashmap
1711 * Check if the map contains any value under the given
1712 * key (including values that are NULL).
1713 *
1714 * @param map the map
1715 * @param key the key to test if a value exists for it
1716 * @return #GNUNET_YES if such a value exists,
1717 * #GNUNET_NO if not
1718 */
1719int
1720GNUNET_CONTAINER_multiuuidmap_contains (
1721 const struct GNUNET_CONTAINER_MultiUuidmap *map,
1722 const struct GNUNET_Uuid *key);
1723
1724
1725/**
1726 * @ingroup hashmap
1727 * Check if the map contains the given value under the given
1728 * key.
1729 *
1730 * @param map the map
1731 * @param key the key to test if a value exists for it
1732 * @param value value to test for
1733 * @return #GNUNET_YES if such a value exists,
1734 * #GNUNET_NO if not
1735 */
1736int
1737GNUNET_CONTAINER_multiuuidmap_contains_value (
1738 const struct GNUNET_CONTAINER_MultiUuidmap *map,
1739 const struct GNUNET_Uuid *key,
1740 const void *value);
1741
1742
1743/**
1744 * @ingroup hashmap
1745 * Store a key-value pair in the map.
1746 *
1747 * @param map the map
1748 * @param key key to use
1749 * @param value value to use
1750 * @param opt options for put
1751 * @return #GNUNET_OK on success,
1752 * #GNUNET_NO if a value was replaced (with REPLACE)
1753 * #GNUNET_SYSERR if #GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY was the option and the
1754 * value already exists
1755 */
1756int
1757GNUNET_CONTAINER_multiuuidmap_put (
1758 struct GNUNET_CONTAINER_MultiUuidmap *map,
1759 const struct GNUNET_Uuid *key,
1760 void *value,
1761 enum GNUNET_CONTAINER_MultiHashMapOption opt);
1762
1763
1764/**
1765 * @ingroup hashmap
1766 * Get the number of key-value pairs in the map.
1767 *
1768 * @param map the map
1769 * @return the number of key value pairs
1770 */
1771unsigned int
1772GNUNET_CONTAINER_multiuuidmap_size (
1773 const struct GNUNET_CONTAINER_MultiUuidmap *map);
1774
1775
1776/**
1777 * @ingroup hashmap
1778 * Iterate over all entries in the map.
1779 *
1780 * @param map the map
1781 * @param it function to call on each entry
1782 * @param it_cls extra argument to @a it
1783 * @return the number of key value pairs processed,
1784 * #GNUNET_SYSERR if it aborted iteration
1785 */
1786int
1787GNUNET_CONTAINER_multiuuidmap_iterate (
1788 struct GNUNET_CONTAINER_MultiUuidmap *map,
1789 GNUNET_CONTAINER_MultiUuidmapIterator it,
1790 void *it_cls);
1791
1792
1793struct GNUNET_CONTAINER_MultiUuidmapIterator;
1794
1795
1796/**
1797 * @ingroup hashmap
1798 * Create an iterator for a multihashmap.
1799 * The iterator can be used to retrieve all the elements in the multihashmap
1800 * one by one, without having to handle all elements at once (in contrast to
1801 * #GNUNET_CONTAINER_multiuuidmap_iterate). Note that the iterator can not be
1802 * used anymore if elements have been removed from @a map after the creation of
1803 * the iterator, or 'map' has been destroyed. Adding elements to @a map may
1804 * result in skipped or repeated elements.
1805 *
1806 * @param map the map to create an iterator for
1807 * @return an iterator over the given multihashmap @a map
1808 */
1809struct GNUNET_CONTAINER_MultiUuidmapIterator *
1810GNUNET_CONTAINER_multiuuidmap_iterator_create (
1811 const struct GNUNET_CONTAINER_MultiUuidmap *map);
1812
1813
1814/**
1815 * @ingroup hashmap
1816 * Retrieve the next element from the hash map at the iterator's
1817 * position. If there are no elements left, #GNUNET_NO is returned,
1818 * and @a key and @a value are not modified. This operation is only
1819 * allowed if no elements have been removed from the multihashmap
1820 * since the creation of @a iter, and the map has not been destroyed.
1821 * Adding elements may result in repeating or skipping elements.
1822 *
1823 * @param iter the iterator to get the next element from
1824 * @param key pointer to store the key in, can be NULL
1825 * @param value pointer to store the value in, can be NULL
1826 * @return #GNUNET_YES we returned an element,
1827 * #GNUNET_NO if we are out of elements
1828 */
1829int
1830GNUNET_CONTAINER_multiuuidmap_iterator_next (
1831 struct GNUNET_CONTAINER_MultiUuidmapIterator *iter,
1832 struct GNUNET_Uuid *key,
1833 const void **value);
1834
1835
1836/**
1837 * @ingroup hashmap
1838 * Destroy a multiuuidmap iterator.
1839 *
1840 * @param iter the iterator to destroy
1841 */
1842void
1843GNUNET_CONTAINER_multiuuidmap_iterator_destroy (
1844 struct GNUNET_CONTAINER_MultiUuidmapIterator *iter);
1845
1846
1847/**
1848 * @ingroup hashmap
1849 * Iterate over all entries in the map that match a particular key.
1850 *
1851 * @param map the map
1852 * @param key public key that the entries must correspond to
1853 * @param it function to call on each entry
1854 * @param it_cls extra argument to @a it
1855 * @return the number of key value pairs processed,
1856 * #GNUNET_SYSERR if it aborted iteration
1857 */
1858int
1859GNUNET_CONTAINER_multiuuidmap_get_multiple (
1860 struct GNUNET_CONTAINER_MultiUuidmap *map,
1861 const struct GNUNET_Uuid *key,
1862 GNUNET_CONTAINER_MultiUuidmapIterator it,
1863 void *it_cls);
1864
1865
1866/**
1867 * @ingroup hashmap
1868 * Call @a it on a random value from the map, or not at all
1869 * if the map is empty. Note that this function has linear
1870 * complexity (in the size of the map).
1871 *
1872 * @param map the map
1873 * @param it function to call on a random entry
1874 * @param it_cls extra argument to @a it
1875 * @return the number of key value pairs processed, zero or one.
1876 */
1877unsigned int
1878GNUNET_CONTAINER_multiuuidmap_get_random (
1879 const struct GNUNET_CONTAINER_MultiUuidmap *map,
1880 GNUNET_CONTAINER_MultiUuidmapIterator it,
1881 void *it_cls);
1555 1882
1556 1883
1557/* Version of multihashmap with 32 bit keys */ 1884/* Version of multihashmap with 32 bit keys */
@@ -1582,10 +1909,9 @@ struct GNUNET_CONTAINER_MultiHashMap32Iterator;
1582 * iterate, 1909 * iterate,
1583 * #GNUNET_NO if not. 1910 * #GNUNET_NO if not.
1584 */ 1911 */
1585typedef int 1912typedef int (*GNUNET_CONTAINER_HashMapIterator32) (void *cls,
1586(*GNUNET_CONTAINER_HashMapIterator32) (void *cls, 1913 uint32_t key,
1587 uint32_t key, 1914 void *value);
1588 void *value);
1589 1915
1590 1916
1591/** 1917/**
@@ -1607,7 +1933,8 @@ GNUNET_CONTAINER_multihashmap32_create (unsigned int len);
1607 * @param map the map 1933 * @param map the map
1608 */ 1934 */
1609void 1935void
1610GNUNET_CONTAINER_multihashmap32_destroy (struct GNUNET_CONTAINER_MultiHashMap32 *map); 1936GNUNET_CONTAINER_multihashmap32_destroy (
1937 struct GNUNET_CONTAINER_MultiHashMap32 *map);
1611 1938
1612 1939
1613/** 1940/**
@@ -1618,8 +1945,8 @@ GNUNET_CONTAINER_multihashmap32_destroy (struct GNUNET_CONTAINER_MultiHashMap32
1618 * @return the number of key value pairs 1945 * @return the number of key value pairs
1619 */ 1946 */
1620unsigned int 1947unsigned int
1621GNUNET_CONTAINER_multihashmap32_size (const struct 1948GNUNET_CONTAINER_multihashmap32_size (
1622 GNUNET_CONTAINER_MultiHashMap32 *map); 1949 const struct GNUNET_CONTAINER_MultiHashMap32 *map);
1623 1950
1624 1951
1625/** 1952/**
@@ -1634,9 +1961,9 @@ GNUNET_CONTAINER_multihashmap32_size (const struct
1634 * key-value pairs with value NULL 1961 * key-value pairs with value NULL
1635 */ 1962 */
1636void * 1963void *
1637GNUNET_CONTAINER_multihashmap32_get (const struct 1964GNUNET_CONTAINER_multihashmap32_get (
1638 GNUNET_CONTAINER_MultiHashMap32 *map, 1965 const struct GNUNET_CONTAINER_MultiHashMap32 *map,
1639 uint32_t key); 1966 uint32_t key);
1640 1967
1641 1968
1642/** 1969/**
@@ -1650,9 +1977,10 @@ GNUNET_CONTAINER_multihashmap32_get (const struct
1650 * #GNUNET_SYSERR if it aborted iteration 1977 * #GNUNET_SYSERR if it aborted iteration
1651 */ 1978 */
1652int 1979int
1653GNUNET_CONTAINER_multihashmap32_iterate (struct GNUNET_CONTAINER_MultiHashMap32 *map, 1980GNUNET_CONTAINER_multihashmap32_iterate (
1654 GNUNET_CONTAINER_HashMapIterator32 it, 1981 struct GNUNET_CONTAINER_MultiHashMap32 *map,
1655 void *it_cls); 1982 GNUNET_CONTAINER_HashMapIterator32 it,
1983 void *it_cls);
1656 1984
1657 1985
1658/** 1986/**
@@ -1668,9 +1996,10 @@ GNUNET_CONTAINER_multihashmap32_iterate (struct GNUNET_CONTAINER_MultiHashMap32
1668 * is not in the map 1996 * is not in the map
1669 */ 1997 */
1670int 1998int
1671GNUNET_CONTAINER_multihashmap32_remove (struct GNUNET_CONTAINER_MultiHashMap32 *map, 1999GNUNET_CONTAINER_multihashmap32_remove (
1672 uint32_t key, 2000 struct GNUNET_CONTAINER_MultiHashMap32 *map,
1673 const void *value); 2001 uint32_t key,
2002 const void *value);
1674 2003
1675 2004
1676/** 2005/**
@@ -1683,8 +2012,9 @@ GNUNET_CONTAINER_multihashmap32_remove (struct GNUNET_CONTAINER_MultiHashMap32 *
1683 * @return number of values removed 2012 * @return number of values removed
1684 */ 2013 */
1685int 2014int
1686GNUNET_CONTAINER_multihashmap32_remove_all (struct GNUNET_CONTAINER_MultiHashMap32 *map, 2015GNUNET_CONTAINER_multihashmap32_remove_all (
1687 uint32_t key); 2016 struct GNUNET_CONTAINER_MultiHashMap32 *map,
2017 uint32_t key);
1688 2018
1689 2019
1690/** 2020/**
@@ -1698,8 +2028,9 @@ GNUNET_CONTAINER_multihashmap32_remove_all (struct GNUNET_CONTAINER_MultiHashMap
1698 * #GNUNET_NO if not 2028 * #GNUNET_NO if not
1699 */ 2029 */
1700int 2030int
1701GNUNET_CONTAINER_multihashmap32_contains (const struct GNUNET_CONTAINER_MultiHashMap32 *map, 2031GNUNET_CONTAINER_multihashmap32_contains (
1702 uint32_t key); 2032 const struct GNUNET_CONTAINER_MultiHashMap32 *map,
2033 uint32_t key);
1703 2034
1704 2035
1705/** 2036/**
@@ -1714,9 +2045,10 @@ GNUNET_CONTAINER_multihashmap32_contains (const struct GNUNET_CONTAINER_MultiHas
1714 * #GNUNET_NO if not 2045 * #GNUNET_NO if not
1715 */ 2046 */
1716int 2047int
1717GNUNET_CONTAINER_multihashmap32_contains_value (const struct GNUNET_CONTAINER_MultiHashMap32 *map, 2048GNUNET_CONTAINER_multihashmap32_contains_value (
1718 uint32_t key, 2049 const struct GNUNET_CONTAINER_MultiHashMap32 *map,
1719 const void *value); 2050 uint32_t key,
2051 const void *value);
1720 2052
1721 2053
1722/** 2054/**
@@ -1733,10 +2065,11 @@ GNUNET_CONTAINER_multihashmap32_contains_value (const struct GNUNET_CONTAINER_Mu
1733 * value already exists 2065 * value already exists
1734 */ 2066 */
1735int 2067int
1736GNUNET_CONTAINER_multihashmap32_put (struct GNUNET_CONTAINER_MultiHashMap32 *map, 2068GNUNET_CONTAINER_multihashmap32_put (
1737 uint32_t key, 2069 struct GNUNET_CONTAINER_MultiHashMap32 *map,
1738 void *value, 2070 uint32_t key,
1739 enum GNUNET_CONTAINER_MultiHashMapOption opt); 2071 void *value,
2072 enum GNUNET_CONTAINER_MultiHashMapOption opt);
1740 2073
1741 2074
1742/** 2075/**
@@ -1751,10 +2084,11 @@ GNUNET_CONTAINER_multihashmap32_put (struct GNUNET_CONTAINER_MultiHashMap32 *map
1751 * #GNUNET_SYSERR if it aborted iteration 2084 * #GNUNET_SYSERR if it aborted iteration
1752 */ 2085 */
1753int 2086int
1754GNUNET_CONTAINER_multihashmap32_get_multiple (struct GNUNET_CONTAINER_MultiHashMap32 *map, 2087GNUNET_CONTAINER_multihashmap32_get_multiple (
1755 uint32_t key, 2088 struct GNUNET_CONTAINER_MultiHashMap32 *map,
1756 GNUNET_CONTAINER_HashMapIterator32 it, 2089 uint32_t key,
1757 void *it_cls); 2090 GNUNET_CONTAINER_HashMapIterator32 it,
2091 void *it_cls);
1758 2092
1759 2093
1760/** 2094/**
@@ -1770,7 +2104,8 @@ GNUNET_CONTAINER_multihashmap32_get_multiple (struct GNUNET_CONTAINER_MultiHashM
1770 * @return an iterator over the given multihashmap map 2104 * @return an iterator over the given multihashmap map
1771 */ 2105 */
1772struct GNUNET_CONTAINER_MultiHashMap32Iterator * 2106struct GNUNET_CONTAINER_MultiHashMap32Iterator *
1773GNUNET_CONTAINER_multihashmap32_iterator_create (const struct GNUNET_CONTAINER_MultiHashMap32 *map); 2107GNUNET_CONTAINER_multihashmap32_iterator_create (
2108 const struct GNUNET_CONTAINER_MultiHashMap32 *map);
1774 2109
1775 2110
1776/** 2111/**
@@ -1788,9 +2123,10 @@ GNUNET_CONTAINER_multihashmap32_iterator_create (const struct GNUNET_CONTAINER_M
1788 * #GNUNET_NO if we are out of elements 2123 * #GNUNET_NO if we are out of elements
1789 */ 2124 */
1790int 2125int
1791GNUNET_CONTAINER_multihashmap32_iterator_next (struct GNUNET_CONTAINER_MultiHashMap32Iterator *iter, 2126GNUNET_CONTAINER_multihashmap32_iterator_next (
1792 uint32_t *key, 2127 struct GNUNET_CONTAINER_MultiHashMap32Iterator *iter,
1793 const void **value); 2128 uint32_t *key,
2129 const void **value);
1794 2130
1795 2131
1796/** 2132/**
@@ -1799,7 +2135,8 @@ GNUNET_CONTAINER_multihashmap32_iterator_next (struct GNUNET_CONTAINER_MultiHash
1799 * @param iter the iterator to destroy 2135 * @param iter the iterator to destroy
1800 */ 2136 */
1801void 2137void
1802GNUNET_CONTAINER_multihashmap32_iterator_destroy (struct GNUNET_CONTAINER_MultiHashMapIterator *iter); 2138GNUNET_CONTAINER_multihashmap32_iterator_destroy (
2139 struct GNUNET_CONTAINER_MultiHashMapIterator *iter);
1803 2140
1804 2141
1805/* ******************** doubly-linked list *************** */ 2142/* ******************** doubly-linked list *************** */
@@ -1814,16 +2151,19 @@ GNUNET_CONTAINER_multihashmap32_iterator_destroy (struct GNUNET_CONTAINER_MultiH
1814 * @param tail pointer to the tail of the DLL 2151 * @param tail pointer to the tail of the DLL
1815 * @param element element to insert 2152 * @param element element to insert
1816 */ 2153 */
1817#define GNUNET_CONTAINER_DLL_insert(head,tail,element) do { \ 2154#define GNUNET_CONTAINER_DLL_insert(head, tail, element) \
1818 GNUNET_assert ( ( (element)->prev == NULL) && ((head) != (element))); \ 2155 do \
1819 GNUNET_assert ( ( (element)->next == NULL) && ((tail) != (element))); \ 2156 { \
1820 (element)->next = (head); \ 2157 GNUNET_assert (((element)->prev == NULL) && ((head) != (element))); \
1821 (element)->prev = NULL; \ 2158 GNUNET_assert (((element)->next == NULL) && ((tail) != (element))); \
1822 if ((tail) == NULL) \ 2159 (element)->next = (head); \
1823 (tail) = element; \ 2160 (element)->prev = NULL; \
1824 else \ 2161 if ((tail) == NULL) \
1825 (head)->prev = element; \ 2162 (tail) = element; \
1826 (head) = (element); } while (0) 2163 else \
2164 (head)->prev = element; \
2165 (head) = (element); \
2166 } while (0)
1827 2167
1828 2168
1829/** 2169/**
@@ -1835,16 +2175,19 @@ GNUNET_CONTAINER_multihashmap32_iterator_destroy (struct GNUNET_CONTAINER_MultiH
1835 * @param tail pointer to the tail of the DLL 2175 * @param tail pointer to the tail of the DLL
1836 * @param element element to insert 2176 * @param element element to insert
1837 */ 2177 */
1838#define GNUNET_CONTAINER_DLL_insert_tail(head,tail,element) do { \ 2178#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element) \
1839 GNUNET_assert ( ( (element)->prev == NULL) && ((head) != (element))); \ 2179 do \
1840 GNUNET_assert ( ( (element)->next == NULL) && ((tail) != (element))); \ 2180 { \
1841 (element)->prev = (tail); \ 2181 GNUNET_assert (((element)->prev == NULL) && ((head) != (element))); \
1842 (element)->next = NULL; \ 2182 GNUNET_assert (((element)->next == NULL) && ((tail) != (element))); \
1843 if ((head) == NULL) \ 2183 (element)->prev = (tail); \
1844 (head) = element; \ 2184 (element)->next = NULL; \
1845 else \ 2185 if ((head) == NULL) \
1846 (tail)->next = element; \ 2186 (head) = element; \
1847 (tail) = (element); } while (0) 2187 else \
2188 (tail)->next = element; \
2189 (tail) = (element); \
2190 } while (0)
1848 2191
1849 2192
1850/** 2193/**
@@ -1857,24 +2200,27 @@ GNUNET_CONTAINER_multihashmap32_iterator_destroy (struct GNUNET_CONTAINER_MultiH
1857 * @param other prior element, NULL for insertion at head of DLL 2200 * @param other prior element, NULL for insertion at head of DLL
1858 * @param element element to insert 2201 * @param element element to insert
1859 */ 2202 */
1860#define GNUNET_CONTAINER_DLL_insert_after(head,tail,other,element) do { \ 2203#define GNUNET_CONTAINER_DLL_insert_after(head, tail, other, element) \
1861 GNUNET_assert ( ( (element)->prev == NULL) && ((head) != (element))); \ 2204 do \
1862 GNUNET_assert ( ( (element)->next == NULL) && ((tail) != (element))); \ 2205 { \
1863 (element)->prev = (other); \ 2206 GNUNET_assert (((element)->prev == NULL) && ((head) != (element))); \
1864 if (NULL == other) \ 2207 GNUNET_assert (((element)->next == NULL) && ((tail) != (element))); \
1865 { \ 2208 (element)->prev = (other); \
1866 (element)->next = (head); \ 2209 if (NULL == other) \
1867 (head) = (element); \ 2210 { \
1868 } \ 2211 (element)->next = (head); \
1869 else \ 2212 (head) = (element); \
1870 { \ 2213 } \
1871 (element)->next = (other)->next; \ 2214 else \
1872 (other)->next = (element); \ 2215 { \
1873 } \ 2216 (element)->next = (other)->next; \
1874 if (NULL == (element)->next) \ 2217 (other)->next = (element); \
1875 (tail) = (element); \ 2218 } \
1876 else \ 2219 if (NULL == (element)->next) \
1877 (element)->next->prev = (element); } while (0) 2220 (tail) = (element); \
2221 else \
2222 (element)->next->prev = (element); \
2223 } while (0)
1878 2224
1879 2225
1880/** 2226/**
@@ -1887,24 +2233,27 @@ GNUNET_CONTAINER_multihashmap32_iterator_destroy (struct GNUNET_CONTAINER_MultiH
1887 * @param other prior element, NULL for insertion at head of DLL 2233 * @param other prior element, NULL for insertion at head of DLL
1888 * @param element element to insert 2234 * @param element element to insert
1889 */ 2235 */
1890#define GNUNET_CONTAINER_DLL_insert_before(head,tail,other,element) do { \ 2236#define GNUNET_CONTAINER_DLL_insert_before(head, tail, other, element) \
1891 GNUNET_assert ( ( (element)->prev == NULL) && ((head) != (element))); \ 2237 do \
1892 GNUNET_assert ( ( (element)->next == NULL) && ((tail) != (element))); \ 2238 { \
1893 (element)->next = (other); \ 2239 GNUNET_assert (((element)->prev == NULL) && ((head) != (element))); \
1894 if (NULL == other) \ 2240 GNUNET_assert (((element)->next == NULL) && ((tail) != (element))); \
1895 { \ 2241 (element)->next = (other); \
1896 (element)->prev = (tail); \ 2242 if (NULL == other) \
1897 (tail) = (element); \ 2243 { \
1898 } \ 2244 (element)->prev = (tail); \
1899 else \ 2245 (tail) = (element); \
1900 { \ 2246 } \
1901 (element)->prev = (other)->prev; \ 2247 else \
1902 (other)->prev = (element); \ 2248 { \
1903 } \ 2249 (element)->prev = (other)->prev; \
1904 if (NULL == (element)->prev) \ 2250 (other)->prev = (element); \
1905 (head) = (element); \ 2251 } \
1906 else \ 2252 if (NULL == (element)->prev) \
1907 (element)->prev->next = (element); } while (0) 2253 (head) = (element); \
2254 else \
2255 (element)->prev->next = (element); \
2256 } while (0)
1908 2257
1909 2258
1910/** 2259/**
@@ -1921,19 +2270,22 @@ GNUNET_CONTAINER_multihashmap32_iterator_destroy (struct GNUNET_CONTAINER_MultiH
1921 * @param tail pointer to the tail of the DLL 2270 * @param tail pointer to the tail of the DLL
1922 * @param element element to remove 2271 * @param element element to remove
1923 */ 2272 */
1924#define GNUNET_CONTAINER_DLL_remove(head,tail,element) do { \ 2273#define GNUNET_CONTAINER_DLL_remove(head, tail, element) \
1925 GNUNET_assert ( ( (element)->prev != NULL) || ((head) == (element))); \ 2274 do \
1926 GNUNET_assert ( ( (element)->next != NULL) || ((tail) == (element))); \ 2275 { \
1927 if ((element)->prev == NULL) \ 2276 GNUNET_assert (((element)->prev != NULL) || ((head) == (element))); \
1928 (head) = (element)->next; \ 2277 GNUNET_assert (((element)->next != NULL) || ((tail) == (element))); \
1929 else \ 2278 if ((element)->prev == NULL) \
1930 (element)->prev->next = (element)->next; \ 2279 (head) = (element)->next; \
1931 if ((element)->next == NULL) \ 2280 else \
1932 (tail) = (element)->prev; \ 2281 (element)->prev->next = (element)->next; \
1933 else \ 2282 if ((element)->next == NULL) \
1934 (element)->next->prev = (element)->prev; \ 2283 (tail) = (element)->prev; \
1935 (element)->next = NULL; \ 2284 else \
1936 (element)->prev = NULL; } while (0) 2285 (element)->next->prev = (element)->prev; \
2286 (element)->next = NULL; \
2287 (element)->prev = NULL; \
2288 } while (0)
1937 2289
1938 2290
1939/* ************ Multi-DLL interface, allows DLL elements to be 2291/* ************ Multi-DLL interface, allows DLL elements to be
@@ -1949,16 +2301,19 @@ GNUNET_CONTAINER_multihashmap32_iterator_destroy (struct GNUNET_CONTAINER_MultiH
1949 * @param tail pointer to the tail of the MDLL 2301 * @param tail pointer to the tail of the MDLL
1950 * @param element element to insert 2302 * @param element element to insert
1951 */ 2303 */
1952#define GNUNET_CONTAINER_MDLL_insert(mdll,head,tail,element) do { \ 2304#define GNUNET_CONTAINER_MDLL_insert(mdll, head, tail, element) \
1953 GNUNET_assert ( ( (element)->prev_##mdll == NULL) && ((head) != (element))); \ 2305 do \
1954 GNUNET_assert ( ( (element)->next_##mdll == NULL) && ((tail) != (element))); \ 2306 { \
1955 (element)->next_##mdll = (head); \ 2307 GNUNET_assert (((element)->prev_##mdll == NULL) && ((head) != (element))); \
1956 (element)->prev_##mdll = NULL; \ 2308 GNUNET_assert (((element)->next_##mdll == NULL) && ((tail) != (element))); \
1957 if ((tail) == NULL) \ 2309 (element)->next_##mdll = (head); \
1958 (tail) = element; \ 2310 (element)->prev_##mdll = NULL; \
1959 else \ 2311 if ((tail) == NULL) \
1960 (head)->prev_##mdll = element; \ 2312 (tail) = element; \
1961 (head) = (element); } while (0) 2313 else \
2314 (head)->prev_##mdll = element; \
2315 (head) = (element); \
2316 } while (0)
1962 2317
1963 2318
1964/** 2319/**
@@ -1971,16 +2326,19 @@ GNUNET_CONTAINER_multihashmap32_iterator_destroy (struct GNUNET_CONTAINER_MultiH
1971 * @param tail pointer to the tail of the MDLL 2326 * @param tail pointer to the tail of the MDLL
1972 * @param element element to insert 2327 * @param element element to insert
1973 */ 2328 */
1974#define GNUNET_CONTAINER_MDLL_insert_tail(mdll,head,tail,element) do { \ 2329#define GNUNET_CONTAINER_MDLL_insert_tail(mdll, head, tail, element) \
1975 GNUNET_assert ( ( (element)->prev_##mdll == NULL) && ((head) != (element))); \ 2330 do \
1976 GNUNET_assert ( ( (element)->next_##mdll == NULL) && ((tail) != (element))); \ 2331 { \
1977 (element)->prev_##mdll = (tail); \ 2332 GNUNET_assert (((element)->prev_##mdll == NULL) && ((head) != (element))); \
1978 (element)->next_##mdll = NULL; \ 2333 GNUNET_assert (((element)->next_##mdll == NULL) && ((tail) != (element))); \
1979 if ((head) == NULL) \ 2334 (element)->prev_##mdll = (tail); \
1980 (head) = element; \ 2335 (element)->next_##mdll = NULL; \
1981 else \ 2336 if ((head) == NULL) \
1982 (tail)->next_##mdll = element; \ 2337 (head) = element; \
1983 (tail) = (element); } while (0) 2338 else \
2339 (tail)->next_##mdll = element; \
2340 (tail) = (element); \
2341 } while (0)
1984 2342
1985 2343
1986/** 2344/**
@@ -1994,24 +2352,27 @@ GNUNET_CONTAINER_multihashmap32_iterator_destroy (struct GNUNET_CONTAINER_MultiH
1994 * @param other prior element, NULL for insertion at head of MDLL 2352 * @param other prior element, NULL for insertion at head of MDLL
1995 * @param element element to insert 2353 * @param element element to insert
1996 */ 2354 */
1997#define GNUNET_CONTAINER_MDLL_insert_after(mdll,head,tail,other,element) do { \ 2355#define GNUNET_CONTAINER_MDLL_insert_after(mdll, head, tail, other, element) \
1998 GNUNET_assert ( ( (element)->prev_##mdll == NULL) && ((head) != (element))); \ 2356 do \
1999 GNUNET_assert ( ( (element)->next_##mdll == NULL) && ((tail) != (element))); \ 2357 { \
2000 (element)->prev_##mdll = (other); \ 2358 GNUNET_assert (((element)->prev_##mdll == NULL) && ((head) != (element))); \
2001 if (NULL == other) \ 2359 GNUNET_assert (((element)->next_##mdll == NULL) && ((tail) != (element))); \
2002 { \ 2360 (element)->prev_##mdll = (other); \
2003 (element)->next_##mdll = (head); \ 2361 if (NULL == other) \
2004 (head) = (element); \ 2362 { \
2005 } \ 2363 (element)->next_##mdll = (head); \
2006 else \ 2364 (head) = (element); \
2007 { \ 2365 } \
2008 (element)->next_##mdll = (other)->next_##mdll; \ 2366 else \
2009 (other)->next_##mdll = (element); \ 2367 { \
2010 } \ 2368 (element)->next_##mdll = (other)->next_##mdll; \
2011 if (NULL == (element)->next_##mdll) \ 2369 (other)->next_##mdll = (element); \
2012 (tail) = (element); \ 2370 } \
2013 else \ 2371 if (NULL == (element)->next_##mdll) \
2014 (element)->next_##mdll->prev_##mdll = (element); } while (0) 2372 (tail) = (element); \
2373 else \
2374 (element)->next_##mdll->prev_##mdll = (element); \
2375 } while (0)
2015 2376
2016 2377
2017/** 2378/**
@@ -2025,24 +2386,27 @@ GNUNET_CONTAINER_multihashmap32_iterator_destroy (struct GNUNET_CONTAINER_MultiH
2025 * @param other prior element, NULL for insertion at head of MDLL 2386 * @param other prior element, NULL for insertion at head of MDLL
2026 * @param element element to insert 2387 * @param element element to insert
2027 */ 2388 */
2028#define GNUNET_CONTAINER_MDLL_insert_before(mdll,head,tail,other,element) do { \ 2389#define GNUNET_CONTAINER_MDLL_insert_before(mdll, head, tail, other, element) \
2029 GNUNET_assert ( ( (element)->prev_##mdll == NULL) && ((head) != (element))); \ 2390 do \
2030 GNUNET_assert ( ( (element)->next_##mdll == NULL) && ((tail) != (element))); \ 2391 { \
2031 (element)->next_##mdll = (other); \ 2392 GNUNET_assert (((element)->prev_##mdll == NULL) && ((head) != (element))); \
2032 if (NULL == other) \ 2393 GNUNET_assert (((element)->next_##mdll == NULL) && ((tail) != (element))); \
2033 { \ 2394 (element)->next_##mdll = (other); \
2034 (element)->prev = (tail); \ 2395 if (NULL == other) \
2035 (tail) = (element); \ 2396 { \
2036 } \ 2397 (element)->prev = (tail); \
2037 else \ 2398 (tail) = (element); \
2038 { \ 2399 } \
2039 (element)->prev_##mdll = (other)->prev_##mdll; \ 2400 else \
2040 (other)->prev_##mdll = (element); \ 2401 { \
2041 } \ 2402 (element)->prev_##mdll = (other)->prev_##mdll; \
2042 if (NULL == (element)->prev_##mdll) \ 2403 (other)->prev_##mdll = (element); \
2043 (head) = (element); \ 2404 } \
2044 else \ 2405 if (NULL == (element)->prev_##mdll) \
2045 (element)->prev_##mdll->next_##mdll = (element); } while (0) 2406 (head) = (element); \
2407 else \
2408 (element)->prev_##mdll->next_##mdll = (element); \
2409 } while (0)
2046 2410
2047 2411
2048/** 2412/**
@@ -2056,20 +2420,22 @@ GNUNET_CONTAINER_multihashmap32_iterator_destroy (struct GNUNET_CONTAINER_MultiH
2056 * @param tail pointer to the tail of the MDLL 2420 * @param tail pointer to the tail of the MDLL
2057 * @param element element to remove 2421 * @param element element to remove
2058 */ 2422 */
2059#define GNUNET_CONTAINER_MDLL_remove(mdll,head,tail,element) do { \ 2423#define GNUNET_CONTAINER_MDLL_remove(mdll, head, tail, element) \
2060 GNUNET_assert ( ( (element)->prev_##mdll != NULL) || ((head) == (element))); \ 2424 do \
2061 GNUNET_assert ( ( (element)->next_##mdll != NULL) || ((tail) == (element))); \ 2425 { \
2062 if ((element)->prev_##mdll == NULL) \ 2426 GNUNET_assert (((element)->prev_##mdll != NULL) || ((head) == (element))); \
2063 (head) = (element)->next_##mdll; \ 2427 GNUNET_assert (((element)->next_##mdll != NULL) || ((tail) == (element))); \
2064 else \ 2428 if ((element)->prev_##mdll == NULL) \
2065 (element)->prev_##mdll->next_##mdll = (element)->next_##mdll; \ 2429 (head) = (element)->next_##mdll; \
2066 if ((element)->next_##mdll == NULL) \ 2430 else \
2067 (tail) = (element)->prev_##mdll; \ 2431 (element)->prev_##mdll->next_##mdll = (element)->next_##mdll; \
2068 else \ 2432 if ((element)->next_##mdll == NULL) \
2069 (element)->next_##mdll->prev_##mdll = (element)->prev_##mdll; \ 2433 (tail) = (element)->prev_##mdll; \
2070 (element)->next_##mdll = NULL; \ 2434 else \
2071 (element)->prev_##mdll = NULL; } while (0) 2435 (element)->next_##mdll->prev_##mdll = (element)->prev_##mdll; \
2072 2436 (element)->next_##mdll = NULL; \
2437 (element)->prev_##mdll = NULL; \
2438 } while (0)
2073 2439
2074 2440
2075/** 2441/**
@@ -2085,44 +2451,36 @@ GNUNET_CONTAINER_multihashmap32_iterator_destroy (struct GNUNET_CONTAINER_MultiH
2085 * @param[in,out] tail tail of DLL 2451 * @param[in,out] tail tail of DLL
2086 * @param element element to insert 2452 * @param element element to insert
2087 */ 2453 */
2088#define GNUNET_CONTAINER_DLL_insert_sorted(TYPE,comparator,comparator_cls,head,tail,element) do { \ 2454#define GNUNET_CONTAINER_DLL_insert_sorted(TYPE, \
2089 if ( (NULL == head) || \ 2455 comparator, \
2090 (0 < comparator (comparator_cls, \ 2456 comparator_cls, \
2091 element, \ 2457 head, \
2092 head)) ) \ 2458 tail, \
2093 { \ 2459 element) \
2094 /* insert at head, element < head */ \ 2460 do \
2095 GNUNET_CONTAINER_DLL_insert (head, \ 2461 { \
2096 tail, \ 2462 if ((NULL == head) || (0 < comparator (comparator_cls, element, head))) \
2097 element); \ 2463 { \
2098 } \ 2464 /* insert at head, element < head */ \
2099 else \ 2465 GNUNET_CONTAINER_DLL_insert (head, tail, element); \
2100 { \ 2466 } \
2101 TYPE *pos; \ 2467 else \
2102 \ 2468 { \
2103 for (pos = head; \ 2469 TYPE *pos; \
2104 NULL != pos; \ 2470 \
2105 pos = pos->next) \ 2471 for (pos = head; NULL != pos; pos = pos->next) \
2106 if (0 < \ 2472 if (0 < comparator (comparator_cls, element, pos)) \
2107 comparator (comparator_cls, \ 2473 break; /* element < pos */ \
2108 element, \ 2474 if (NULL == pos) /* => element > tail */ \
2109 pos)) \ 2475 { \
2110 break; /* element < pos */ \ 2476 GNUNET_CONTAINER_DLL_insert_tail (head, tail, element); \
2111 if (NULL == pos) /* => element > tail */ \ 2477 } \
2112 { \ 2478 else /* prev < element < pos */ \
2113 GNUNET_CONTAINER_DLL_insert_tail (head, \ 2479 { \
2114 tail, \ 2480 GNUNET_CONTAINER_DLL_insert_after (head, tail, pos->prev, element); \
2115 element); \ 2481 } \
2116 } \ 2482 } \
2117 else /* prev < element < pos */ \ 2483 } while (0)
2118 { \
2119 GNUNET_CONTAINER_DLL_insert_after (head, \
2120 tail, \
2121 pos->prev, \
2122 element); \
2123 } \
2124 } \
2125} while (0)
2126 2484
2127 2485
2128/* ******************** Heap *************** */ 2486/* ******************** Heap *************** */
@@ -2236,7 +2594,8 @@ GNUNET_CONTAINER_heap_get_size (const struct GNUNET_CONTAINER_Heap *heap);
2236 * @return cost of the node 2594 * @return cost of the node
2237 */ 2595 */
2238GNUNET_CONTAINER_HeapCostType 2596GNUNET_CONTAINER_HeapCostType
2239GNUNET_CONTAINER_heap_node_get_cost (const struct GNUNET_CONTAINER_HeapNode *node); 2597GNUNET_CONTAINER_heap_node_get_cost (
2598 const struct GNUNET_CONTAINER_HeapNode *node);
2240 2599
2241 2600
2242/** 2601/**
@@ -2250,11 +2609,11 @@ GNUNET_CONTAINER_heap_node_get_cost (const struct GNUNET_CONTAINER_HeapNode *nod
2250 * @return #GNUNET_YES if we should continue to iterate, 2609 * @return #GNUNET_YES if we should continue to iterate,
2251 * #GNUNET_NO if not. 2610 * #GNUNET_NO if not.
2252 */ 2611 */
2253typedef int 2612typedef int (*GNUNET_CONTAINER_HeapIterator) (
2254(*GNUNET_CONTAINER_HeapIterator) (void *cls, 2613 void *cls,
2255 struct GNUNET_CONTAINER_HeapNode *node, 2614 struct GNUNET_CONTAINER_HeapNode *node,
2256 void *element, 2615 void *element,
2257 GNUNET_CONTAINER_HeapCostType cost); 2616 GNUNET_CONTAINER_HeapCostType cost);
2258 2617
2259 2618
2260/** 2619/**
@@ -2335,7 +2694,7 @@ GNUNET_CONTAINER_heap_update_cost (struct GNUNET_CONTAINER_HeapNode *node,
2335 GNUNET_CONTAINER_HeapCostType new_cost); 2694 GNUNET_CONTAINER_HeapCostType new_cost);
2336 2695
2337 2696
2338#if 0 /* keep Emacsens' auto-indent happy */ 2697#if 0 /* keep Emacsens' auto-indent happy */
2339{ 2698{
2340#endif 2699#endif
2341#ifdef __cplusplus 2700#ifdef __cplusplus
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c
index 18a80b3c5..eb3cc2de9 100644
--- a/src/transport/gnunet-service-tng.c
+++ b/src/transport/gnunet-service-tng.c
@@ -33,8 +33,6 @@
33 * do NOT forward it to peers _other_ than the origin, as 33 * do NOT forward it to peers _other_ than the origin, as
34 * there is clearly a better path directly from the origin to 34 * there is clearly a better path directly from the origin to
35 * whatever else we could reach. 35 * whatever else we could reach.
36 * - AcknowledgementUUIDPs are overkill with 256 bits (128 would do)
37 * => Need 128 bit hash map though! [BANDWIDTH, MEMORY]
38 * - queue_send_msg by API design has to make a copy 36 * - queue_send_msg by API design has to make a copy
39 * of the payload, and route_message on top of that requires a malloc/free. 37 * of the payload, and route_message on top of that requires a malloc/free.
40 * Change design to approximate "zero" copy better... [CPU] 38 * Change design to approximate "zero" copy better... [CPU]
@@ -345,9 +343,9 @@ struct MessageUUIDP
345struct AcknowledgementUUIDP 343struct AcknowledgementUUIDP
346{ 344{
347 /** 345 /**
348 * The UUID value. Not actually a hash, but a random value. 346 * The UUID value.
349 */ 347 */
350 struct GNUNET_ShortHashCode value; 348 struct GNUNET_Uuid value;
351}; 349};
352 350
353 351
@@ -2736,7 +2734,7 @@ static struct GNUNET_CONTAINER_MultiPeerMap *ack_cummulators;
2736 * Map of pending acknowledgements, mapping `struct AcknowledgementUUID` to 2734 * Map of pending acknowledgements, mapping `struct AcknowledgementUUID` to
2737 * a `struct PendingAcknowledgement`. 2735 * a `struct PendingAcknowledgement`.
2738 */ 2736 */
2739static struct GNUNET_CONTAINER_MultiShortmap *pending_acks; 2737static struct GNUNET_CONTAINER_MultiUuidmap *pending_acks;
2740 2738
2741/** 2739/**
2742 * Map from PIDs to `struct DistanceVector` entries describing 2740 * Map from PIDs to `struct DistanceVector` entries describing
@@ -2910,9 +2908,9 @@ free_pending_acknowledgement (struct PendingAcknowledgement *pa)
2910 pa->queue = NULL; 2908 pa->queue = NULL;
2911 } 2909 }
2912 GNUNET_assert (GNUNET_YES == 2910 GNUNET_assert (GNUNET_YES ==
2913 GNUNET_CONTAINER_multishortmap_remove (pending_acks, 2911 GNUNET_CONTAINER_multiuuidmap_remove (pending_acks,
2914 &pa->ack_uuid.value, 2912 &pa->ack_uuid.value,
2915 pa)); 2913 pa));
2916 GNUNET_free (pa); 2914 GNUNET_free (pa);
2917} 2915}
2918 2916
@@ -5468,7 +5466,7 @@ cummulative_ack (const struct GNUNET_PeerIdentity *pid,
5468 5466
5469 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 5467 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5470 "Scheduling ACK %s for transmission to %s\n", 5468 "Scheduling ACK %s for transmission to %s\n",
5471 GNUNET_sh2s (&ack_uuid->value), 5469 GNUNET_uuid2s (&ack_uuid->value),
5472 GNUNET_i2s (pid)); 5470 GNUNET_i2s (pid));
5473 ac = GNUNET_CONTAINER_multipeermap_get (ack_cummulators, pid); 5471 ac = GNUNET_CONTAINER_multipeermap_get (ack_cummulators, pid);
5474 if (NULL == ac) 5472 if (NULL == ac)
@@ -5743,7 +5741,7 @@ handle_reliability_box (void *cls,
5743 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 5741 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5744 "Received reliability box from %s with UUID %s of type %u\n", 5742 "Received reliability box from %s with UUID %s of type %u\n",
5745 GNUNET_i2s (&cmc->im.sender), 5743 GNUNET_i2s (&cmc->im.sender),
5746 GNUNET_sh2s (&rb->ack_uuid.value), 5744 GNUNET_uuid2s (&rb->ack_uuid.value),
5747 (unsigned int) ntohs (inbox->type)); 5745 (unsigned int) ntohs (inbox->type));
5748 rtt = GNUNET_TIME_UNIT_SECONDS; /* FIXME: should base this on "RTT", but we 5746 rtt = GNUNET_TIME_UNIT_SECONDS; /* FIXME: should base this on "RTT", but we
5749 do not really have an RTT for the 5747 do not really have an RTT for the
@@ -5981,13 +5979,13 @@ handle_reliability_ack (void *cls,
5981 for (unsigned int i = 0; i < n_acks; i++) 5979 for (unsigned int i = 0; i < n_acks; i++)
5982 { 5980 {
5983 pa = 5981 pa =
5984 GNUNET_CONTAINER_multishortmap_get (pending_acks, &ack[i].ack_uuid.value); 5982 GNUNET_CONTAINER_multiuuidmap_get (pending_acks, &ack[i].ack_uuid.value);
5985 if (NULL == pa) 5983 if (NULL == pa)
5986 { 5984 {
5987 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 5985 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
5988 "Received ACK from %s with UUID %s which is unknown to us!\n", 5986 "Received ACK from %s with UUID %s which is unknown to us!\n",
5989 GNUNET_i2s (&cmc->im.sender), 5987 GNUNET_i2s (&cmc->im.sender),
5990 GNUNET_sh2s (&ack[i].ack_uuid.value)); 5988 GNUNET_uuid2s (&ack[i].ack_uuid.value));
5991 GNUNET_STATISTICS_update ( 5989 GNUNET_STATISTICS_update (
5992 GST_stats, 5990 GST_stats,
5993 "# FRAGMENT_ACKS dropped, no matching pending message", 5991 "# FRAGMENT_ACKS dropped, no matching pending message",
@@ -5998,7 +5996,7 @@ handle_reliability_ack (void *cls,
5998 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 5996 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5999 "Received ACK from %s with UUID %s\n", 5997 "Received ACK from %s with UUID %s\n",
6000 GNUNET_i2s (&cmc->im.sender), 5998 GNUNET_i2s (&cmc->im.sender),
6001 GNUNET_sh2s (&ack[i].ack_uuid.value)); 5999 GNUNET_uuid2s (&ack[i].ack_uuid.value));
6002 handle_acknowledged (pa, GNUNET_TIME_relative_ntoh (ack[i].ack_delay)); 6000 handle_acknowledged (pa, GNUNET_TIME_relative_ntoh (ack[i].ack_delay));
6003 } 6001 }
6004 6002
@@ -8412,7 +8410,7 @@ prepare_pending_acknowledgement (struct Queue *queue,
8412 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, 8410 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
8413 &pa->ack_uuid, 8411 &pa->ack_uuid,
8414 sizeof (pa->ack_uuid)); 8412 sizeof (pa->ack_uuid));
8415 } while (GNUNET_YES != GNUNET_CONTAINER_multishortmap_put ( 8413 } while (GNUNET_YES != GNUNET_CONTAINER_multiuuidmap_put (
8416 pending_acks, 8414 pending_acks,
8417 &pa->ack_uuid.value, 8415 &pa->ack_uuid.value,
8418 pa, 8416 pa,
@@ -8425,7 +8423,7 @@ prepare_pending_acknowledgement (struct Queue *queue,
8425 pa->message_size = pm->bytes_msg; 8423 pa->message_size = pm->bytes_msg;
8426 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 8424 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
8427 "Waiting for ACKnowledgment `%s' for <%llu>\n", 8425 "Waiting for ACKnowledgment `%s' for <%llu>\n",
8428 GNUNET_sh2s (&pa->ack_uuid.value), 8426 GNUNET_uuid2s (&pa->ack_uuid.value),
8429 pm->logging_uuid); 8427 pm->logging_uuid);
8430 return pa; 8428 return pa;
8431} 8429}
@@ -10017,9 +10015,7 @@ free_validation_state_cb (void *cls,
10017 * @return #GNUNET_OK (always) 10015 * @return #GNUNET_OK (always)
10018 */ 10016 */
10019static int 10017static int
10020free_pending_ack_cb (void *cls, 10018free_pending_ack_cb (void *cls, const struct GNUNET_Uuid *key, void *value)
10021 const struct GNUNET_ShortHashCode *key,
10022 void *value)
10023{ 10019{
10024 struct PendingAcknowledgement *pa = value; 10020 struct PendingAcknowledgement *pa = value;
10025 10021
@@ -10085,10 +10081,10 @@ do_shutdown (void *cls)
10085 NULL); 10081 NULL);
10086 GNUNET_CONTAINER_multipeermap_destroy (ack_cummulators); 10082 GNUNET_CONTAINER_multipeermap_destroy (ack_cummulators);
10087 ack_cummulators = NULL; 10083 ack_cummulators = NULL;
10088 GNUNET_CONTAINER_multishortmap_iterate (pending_acks, 10084 GNUNET_CONTAINER_multiuuidmap_iterate (pending_acks,
10089 &free_pending_ack_cb, 10085 &free_pending_ack_cb,
10090 NULL); 10086 NULL);
10091 GNUNET_CONTAINER_multishortmap_destroy (pending_acks); 10087 GNUNET_CONTAINER_multiuuidmap_destroy (pending_acks);
10092 pending_acks = NULL; 10088 pending_acks = NULL;
10093 GNUNET_break (0 == GNUNET_CONTAINER_multipeermap_size (neighbours)); 10089 GNUNET_break (0 == GNUNET_CONTAINER_multipeermap_size (neighbours));
10094 GNUNET_CONTAINER_multipeermap_destroy (neighbours); 10090 GNUNET_CONTAINER_multipeermap_destroy (neighbours);
@@ -10142,7 +10138,7 @@ run (void *cls,
10142 hello_mono_time = GNUNET_TIME_absolute_get_monotonic (c); 10138 hello_mono_time = GNUNET_TIME_absolute_get_monotonic (c);
10143 GST_cfg = c; 10139 GST_cfg = c;
10144 backtalkers = GNUNET_CONTAINER_multipeermap_create (16, GNUNET_YES); 10140 backtalkers = GNUNET_CONTAINER_multipeermap_create (16, GNUNET_YES);
10145 pending_acks = GNUNET_CONTAINER_multishortmap_create (32768, GNUNET_YES); 10141 pending_acks = GNUNET_CONTAINER_multiuuidmap_create (32768, GNUNET_YES);
10146 ack_cummulators = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_YES); 10142 ack_cummulators = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_YES);
10147 neighbours = GNUNET_CONTAINER_multipeermap_create (1024, GNUNET_YES); 10143 neighbours = GNUNET_CONTAINER_multipeermap_create (1024, GNUNET_YES);
10148 links = GNUNET_CONTAINER_multipeermap_create (512, GNUNET_YES); 10144 links = GNUNET_CONTAINER_multipeermap_create (512, GNUNET_YES);
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index 8a99197f8..fe5cc6e72 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -78,6 +78,7 @@ libgnunetutil_la_SOURCES = \
78 container_meta_data.c \ 78 container_meta_data.c \
79 container_multihashmap.c \ 79 container_multihashmap.c \
80 container_multishortmap.c \ 80 container_multishortmap.c \
81 container_multiuuidmap.c \
81 container_multipeermap.c \ 82 container_multipeermap.c \
82 container_multihashmap32.c \ 83 container_multihashmap32.c \
83 crypto_symmetric.c \ 84 crypto_symmetric.c \
diff --git a/src/util/common_logging.c b/src/util/common_logging.c
index 5052134f8..b5678e5be 100644
--- a/src/util/common_logging.c
+++ b/src/util/common_logging.c
@@ -107,7 +107,8 @@ static __thread struct GNUNET_AsyncScopeSave current_async_scope;
107 * Note that this message maybe truncated to the first BULK_TRACK_SIZE 107 * Note that this message maybe truncated to the first BULK_TRACK_SIZE
108 * characters, in which case it is NOT 0-terminated! 108 * characters, in which case it is NOT 0-terminated!
109 */ 109 */
110static GNUNET_THREAD_LOCAL char last_bulk[BULK_TRACK_SIZE] __attribute__ ((nonstring)); 110static GNUNET_THREAD_LOCAL char last_bulk[BULK_TRACK_SIZE]
111 __attribute__ ((nonstring));
111 112
112/** 113/**
113 * Type of the last bulk message. 114 * Type of the last bulk message.
@@ -211,7 +212,7 @@ struct LogDef
211}; 212};
212 213
213 214
214#if !defined(GNUNET_CULL_LOGGING) 215#if ! defined(GNUNET_CULL_LOGGING)
215/** 216/**
216 * Dynamic array of logging definitions 217 * Dynamic array of logging definitions
217 */ 218 */
@@ -263,17 +264,17 @@ get_type (const char *log)
263{ 264{
264 if (NULL == log) 265 if (NULL == log)
265 return GNUNET_ERROR_TYPE_UNSPECIFIED; 266 return GNUNET_ERROR_TYPE_UNSPECIFIED;
266 if (0 == strcasecmp (log, _("DEBUG"))) 267 if (0 == strcasecmp (log, _ ("DEBUG")))
267 return GNUNET_ERROR_TYPE_DEBUG; 268 return GNUNET_ERROR_TYPE_DEBUG;
268 if (0 == strcasecmp (log, _("INFO"))) 269 if (0 == strcasecmp (log, _ ("INFO")))
269 return GNUNET_ERROR_TYPE_INFO; 270 return GNUNET_ERROR_TYPE_INFO;
270 if (0 == strcasecmp (log, _("MESSAGE"))) 271 if (0 == strcasecmp (log, _ ("MESSAGE")))
271 return GNUNET_ERROR_TYPE_MESSAGE; 272 return GNUNET_ERROR_TYPE_MESSAGE;
272 if (0 == strcasecmp (log, _("WARNING"))) 273 if (0 == strcasecmp (log, _ ("WARNING")))
273 return GNUNET_ERROR_TYPE_WARNING; 274 return GNUNET_ERROR_TYPE_WARNING;
274 if (0 == strcasecmp (log, _("ERROR"))) 275 if (0 == strcasecmp (log, _ ("ERROR")))
275 return GNUNET_ERROR_TYPE_ERROR; 276 return GNUNET_ERROR_TYPE_ERROR;
276 if (0 == strcasecmp (log, _("NONE"))) 277 if (0 == strcasecmp (log, _ ("NONE")))
277 return GNUNET_ERROR_TYPE_NONE; 278 return GNUNET_ERROR_TYPE_NONE;
278 return GNUNET_ERROR_TYPE_INVALID; 279 return GNUNET_ERROR_TYPE_INVALID;
279} 280}
@@ -292,7 +293,7 @@ GNUNET_abort_ ()
292} 293}
293 294
294 295
295#if !defined(GNUNET_CULL_LOGGING) 296#if ! defined(GNUNET_CULL_LOGGING)
296/** 297/**
297 * Utility function - reallocates logdefs array to be twice as large. 298 * Utility function - reallocates logdefs array to be twice as large.
298 */ 299 */
@@ -353,7 +354,7 @@ setup_log_file (const struct tm *tm)
353 if (0 == strftime (fn, sizeof (fn), log_file_name, tm)) 354 if (0 == strftime (fn, sizeof (fn), log_file_name, tm))
354 return GNUNET_SYSERR; 355 return GNUNET_SYSERR;
355 leftsquare = strrchr (fn, '['); 356 leftsquare = strrchr (fn, '[');
356 if ( (NULL != leftsquare) && (']' == leftsquare[1]) ) 357 if ((NULL != leftsquare) && (']' == leftsquare[1]))
357 { 358 {
358 char *logfile_copy = GNUNET_strdup (fn); 359 char *logfile_copy = GNUNET_strdup (fn);
359 360
@@ -371,8 +372,7 @@ setup_log_file (const struct tm *tm)
371 return GNUNET_OK; /* no change */ 372 return GNUNET_OK; /* no change */
372 log_rotate (last_fn); 373 log_rotate (last_fn);
373 strcpy (last_fn, fn); 374 strcpy (last_fn, fn);
374 if (GNUNET_SYSERR == 375 if (GNUNET_SYSERR == GNUNET_DISK_directory_create_for_file (fn))
375 GNUNET_DISK_directory_create_for_file (fn))
376 { 376 {
377 fprintf (stderr, 377 fprintf (stderr,
378 "Failed to create directory for `%s': %s\n", 378 "Failed to create directory for `%s': %s\n",
@@ -381,14 +381,12 @@ setup_log_file (const struct tm *tm)
381 return GNUNET_SYSERR; 381 return GNUNET_SYSERR;
382 } 382 }
383#if WINDOWS 383#if WINDOWS
384 altlog_fd = OPEN (fn, O_APPEND | 384 altlog_fd =
385 O_BINARY | 385 OPEN (fn, O_APPEND | O_BINARY | O_WRONLY | O_CREAT, _S_IREAD | _S_IWRITE);
386 O_WRONLY | O_CREAT,
387 _S_IREAD | _S_IWRITE);
388#else 386#else
389 altlog_fd = OPEN (fn, O_APPEND | 387 altlog_fd = OPEN (fn,
390 O_WRONLY | O_CREAT, 388 O_APPEND | O_WRONLY | O_CREAT,
391 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 389 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
392#endif 390#endif
393 if (-1 != altlog_fd) 391 if (-1 != altlog_fd)
394 { 392 {
@@ -512,7 +510,7 @@ GNUNET_get_log_call_status (int caller_level,
512 /* We have no definitions to override globally configured log level, 510 /* We have no definitions to override globally configured log level,
513 * so just use it right away. 511 * so just use it right away.
514 */ 512 */
515 if ( (min_level >= 0) && (GNUNET_NO == gnunet_force_log_present) ) 513 if ((min_level >= 0) && (GNUNET_NO == gnunet_force_log_present))
516 return caller_level <= min_level; 514 return caller_level <= min_level;
517 515
518 /* Only look for forced definitions? */ 516 /* Only look for forced definitions? */
@@ -520,7 +518,7 @@ GNUNET_get_log_call_status (int caller_level,
520 for (i = 0; i < logdefs_len; i++) 518 for (i = 0; i < logdefs_len; i++)
521 { 519 {
522 ld = &logdefs[i]; 520 ld = &logdefs[i];
523 if (( (!force_only) || ld->force) && 521 if (((! force_only) || ld->force) &&
524 (line >= ld->from_line && line <= ld->to_line) && 522 (line >= ld->from_line && line <= ld->to_line) &&
525 (0 == regexec (&ld->component_regex, comp, 0, NULL, 0)) && 523 (0 == regexec (&ld->component_regex, comp, 0, NULL, 0)) &&
526 (0 == regexec (&ld->file_regex, file, 0, NULL, 0)) && 524 (0 == regexec (&ld->file_regex, file, 0, NULL, 0)) &&
@@ -591,73 +589,79 @@ parse_definitions (const char *constname, int force)
591 { 589 {
592 switch (p[0]) 590 switch (p[0])
593 { 591 {
594 case ';': /* found a field separator */ 592 case ';': /* found a field separator */
595 p[0] = '\0'; 593 p[0] = '\0';
596 switch (state) 594 switch (state)
597 { 595 {
598 case 0: /* within a component name */ 596 case 0: /* within a component name */
599 comp = start; 597 comp = start;
600 break; 598 break;
601 case 1: /* within a file name */ 599 case 1: /* within a file name */
602 file = start; 600 file = start;
603 break; 601 break;
604 case 2: /* within a function name */ 602 case 2: /* within a function name */
605 /* after a file name there must be a function name */ 603 /* after a file name there must be a function name */
606 function = start; 604 function = start;
607 break; 605 break;
608 case 3: /* within a from-to line range */ 606 case 3: /* within a from-to line range */
609 if (strlen (start) > 0) 607 if (strlen (start) > 0)
610 { 608 {
611 errno = 0; 609 errno = 0;
612 from_line = strtol (start, &t, 10); 610 from_line = strtol (start, &t, 10);
613 if ( (0 != errno) || (from_line < 0) ) 611 if ((0 != errno) || (from_line < 0))
614 { 612 {
615 GNUNET_free (def); 613 GNUNET_free (def);
616 return counter; 614 return counter;
617 } 615 }
618 if ( (t < p) && ('-' == t[0]) ) 616 if ((t < p) && ('-' == t[0]))
619 { 617 {
620 errno = 0; 618 errno = 0;
621 start = t + 1; 619 start = t + 1;
622 to_line = strtol (start, &t, 10); 620 to_line = strtol (start, &t, 10);
623 if ( (0 != errno) || (to_line < 0) || (t != p) ) 621 if ((0 != errno) || (to_line < 0) || (t != p))
624 { 622 {
625 GNUNET_free (def); 623 GNUNET_free (def);
626 return counter; 624 return counter;
627 } 625 }
628 } 626 }
629 else /* one number means "match this line only" */ 627 else /* one number means "match this line only" */
630 to_line = from_line; 628 to_line = from_line;
631 } 629 }
632 else /* default to 0-max */ 630 else /* default to 0-max */
633 { 631 {
634 from_line = 0; 632 from_line = 0;
635 to_line = INT_MAX; 633 to_line = INT_MAX;
636 } 634 }
637 break; 635 break;
638 default: 636 default:
639 fprintf(stderr, 637 fprintf (
640 _("ERROR: Unable to parse log definition: Syntax error at `%s'.\n"), 638 stderr,
641 p); 639 _ ("ERROR: Unable to parse log definition: Syntax error at `%s'.\n"),
640 p);
642 break; 641 break;
643 } 642 }
644 start = p + 1; 643 start = p + 1;
645 state++; 644 state++;
646 break; 645 break;
647 case '\0': /* found EOL */ 646 case '\0': /* found EOL */
648 keep_looking = 0; 647 keep_looking = 0;
649 /* fall through to '/' */ 648 /* fall through to '/' */
650 case '/': /* found a definition separator */ 649 case '/': /* found a definition separator */
651 switch (state) 650 switch (state)
652 { 651 {
653 case 4: /* within a log level */ 652 case 4: /* within a log level */
654 p[0] = '\0'; 653 p[0] = '\0';
655 state = 0; 654 state = 0;
656 level = get_type ((const char *) start); 655 level = get_type ((const char *) start);
657 if ( (GNUNET_ERROR_TYPE_INVALID == level) || 656 if ((GNUNET_ERROR_TYPE_INVALID == level) ||
658 (GNUNET_ERROR_TYPE_UNSPECIFIED == level) || 657 (GNUNET_ERROR_TYPE_UNSPECIFIED == level) ||
659 (0 != add_definition (comp, file, function, from_line, to_line, 658 (0 != add_definition (comp,
660 level, force)) ) 659 file,
660 function,
661 from_line,
662 to_line,
663 level,
664 force)))
661 { 665 {
662 GNUNET_free (def); 666 GNUNET_free (def);
663 return counter; 667 return counter;
@@ -666,9 +670,10 @@ parse_definitions (const char *constname, int force)
666 start = p + 1; 670 start = p + 1;
667 break; 671 break;
668 default: 672 default:
669 fprintf(stderr, 673 fprintf (
670 _("ERROR: Unable to parse log definition: Syntax error at `%s'.\n"), 674 stderr,
671 p); 675 _ ("ERROR: Unable to parse log definition: Syntax error at `%s'.\n"),
676 p);
672 break; 677 break;
673 } 678 }
674 default: 679 default:
@@ -688,7 +693,7 @@ parse_all_definitions ()
688{ 693{
689 if (GNUNET_NO == gnunet_force_log_parsed) 694 if (GNUNET_NO == gnunet_force_log_parsed)
690 gnunet_force_log_present = 695 gnunet_force_log_present =
691 parse_definitions ("GNUNET_FORCE_LOG", 1) > 0 ? GNUNET_YES : GNUNET_NO; 696 parse_definitions ("GNUNET_FORCE_LOG", 1) > 0 ? GNUNET_YES : GNUNET_NO;
692 gnunet_force_log_parsed = GNUNET_YES; 697 gnunet_force_log_parsed = GNUNET_YES;
693 698
694 if (GNUNET_NO == gnunet_log_parsed) 699 if (GNUNET_NO == gnunet_log_parsed)
@@ -707,14 +712,12 @@ parse_all_definitions ()
707 * @return #GNUNET_OK on success 712 * @return #GNUNET_OK on success
708 */ 713 */
709int 714int
710GNUNET_log_setup (const char *comp, 715GNUNET_log_setup (const char *comp, const char *loglevel, const char *logfile)
711 const char *loglevel,
712 const char *logfile)
713{ 716{
714 const char *env_logfile; 717 const char *env_logfile;
715 718
716 min_level = get_type (loglevel); 719 min_level = get_type (loglevel);
717#if !defined(GNUNET_CULL_LOGGING) 720#if ! defined(GNUNET_CULL_LOGGING)
718 parse_all_definitions (); 721 parse_all_definitions ();
719#endif 722#endif
720#ifdef WINDOWS 723#ifdef WINDOWS
@@ -761,8 +764,7 @@ GNUNET_log_setup (const char *comp,
761 * @param logger_cls closure for @a logger 764 * @param logger_cls closure for @a logger
762 */ 765 */
763void 766void
764GNUNET_logger_add (GNUNET_Logger logger, 767GNUNET_logger_add (GNUNET_Logger logger, void *logger_cls)
765 void *logger_cls)
766{ 768{
767 struct CustomLogger *entry; 769 struct CustomLogger *entry;
768 770
@@ -781,8 +783,7 @@ GNUNET_logger_add (GNUNET_Logger logger,
781 * @param logger_cls closure for @a logger 783 * @param logger_cls closure for @a logger
782 */ 784 */
783void 785void
784GNUNET_logger_remove (GNUNET_Logger logger, 786GNUNET_logger_remove (GNUNET_Logger logger, void *logger_cls)
785 void *logger_cls)
786{ 787{
787 struct CustomLogger *pos; 788 struct CustomLogger *pos;
788 struct CustomLogger *prev; 789 struct CustomLogger *prev;
@@ -828,8 +829,7 @@ output_message (enum GNUNET_ErrorType kind,
828 EnterCriticalSection (&output_message_cs); 829 EnterCriticalSection (&output_message_cs);
829#endif 830#endif
830 /* only use the standard logger if no custom loggers are present */ 831 /* only use the standard logger if no custom loggers are present */
831 if ( (NULL != GNUNET_stderr) && 832 if ((NULL != GNUNET_stderr) && (NULL == loggers))
832 (NULL == loggers) )
833 { 833 {
834 if (kind == GNUNET_ERROR_TYPE_MESSAGE) 834 if (kind == GNUNET_ERROR_TYPE_MESSAGE)
835 { 835 {
@@ -841,9 +841,7 @@ output_message (enum GNUNET_ErrorType kind,
841 * this way if the output is going to logfiles or robots 841 * this way if the output is going to logfiles or robots
842 * instead. 842 * instead.
843 */ 843 */
844 FPRINTF (GNUNET_stderr, 844 FPRINTF (GNUNET_stderr, "* %s", msg);
845 "* %s",
846 msg);
847 } 845 }
848 else if (GNUNET_YES == current_async_scope.have_scope) 846 else if (GNUNET_YES == current_async_scope.have_scope)
849 { 847 {
@@ -881,11 +879,7 @@ output_message (enum GNUNET_ErrorType kind,
881 pos = loggers; 879 pos = loggers;
882 while (NULL != pos) 880 while (NULL != pos)
883 { 881 {
884 pos->logger (pos->logger_cls, 882 pos->logger (pos->logger_cls, kind, comp, datestr, msg);
885 kind,
886 comp,
887 datestr,
888 msg);
889 pos = pos->next; 883 pos = pos->next;
890 } 884 }
891#if WINDOWS 885#if WINDOWS
@@ -907,8 +901,7 @@ flush_bulk (const char *datestr)
907 char *last; 901 char *last;
908 const char *ft; 902 const char *ft;
909 903
910 if ( (0 == last_bulk_time.abs_value_us) || 904 if ((0 == last_bulk_time.abs_value_us) || (0 == last_bulk_repeat))
911 (0 == last_bulk_repeat) )
912 return; 905 return;
913 rev = 0; 906 rev = 0;
914 last = memchr (last_bulk, '\0', BULK_TRACK_SIZE); 907 last = memchr (last_bulk, '\0', BULK_TRACK_SIZE);
@@ -921,11 +914,17 @@ flush_bulk (const char *datestr)
921 rev = 1; 914 rev = 1;
922 last[0] = '\0'; 915 last[0] = '\0';
923 } 916 }
924 ft = GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration 917 ft =
925 (last_bulk_time), GNUNET_YES); 918 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (
926 snprintf (msg, sizeof (msg), 919 last_bulk_time),
927 _("Message `%.*s' repeated %u times in the last %s\n"), 920 GNUNET_YES);
928 BULK_TRACK_SIZE, last_bulk, last_bulk_repeat, ft); 921 snprintf (msg,
922 sizeof (msg),
923 _ ("Message `%.*s' repeated %u times in the last %s\n"),
924 BULK_TRACK_SIZE,
925 last_bulk,
926 last_bulk_repeat,
927 ft);
929 if (rev == 1) 928 if (rev == 1)
930 last[0] = '\n'; 929 last[0] = '\n';
931 output_message (last_bulk_kind, last_bulk_comp, datestr, msg); 930 output_message (last_bulk_kind, last_bulk_comp, datestr, msg);
@@ -941,8 +940,7 @@ flush_bulk (const char *datestr)
941 * @param check_reset #GNUNET_YES to assert that the log skip counter is currently zero 940 * @param check_reset #GNUNET_YES to assert that the log skip counter is currently zero
942 */ 941 */
943void 942void
944GNUNET_log_skip (int n, 943GNUNET_log_skip (int n, int check_reset)
945 int check_reset)
946{ 944{
947 int ok; 945 int ok;
948 946
@@ -993,15 +991,10 @@ mylog (enum GNUNET_ErrorType kind,
993 va_list vacp; 991 va_list vacp;
994 992
995 va_copy (vacp, va); 993 va_copy (vacp, va);
996 size = VSNPRINTF (NULL, 994 size = VSNPRINTF (NULL, 0, message, vacp) + 1;
997 0,
998 message,
999 vacp) + 1;
1000 GNUNET_assert (0 != size); 995 GNUNET_assert (0 != size);
1001 va_end (vacp); 996 va_end (vacp);
1002 memset (date, 997 memset (date, 0, DATE_STR_SIZE);
1003 0,
1004 DATE_STR_SIZE);
1005 { 998 {
1006 char buf[size]; 999 char buf[size];
1007 long long offset; 1000 long long offset;
@@ -1022,24 +1015,19 @@ mylog (enum GNUNET_ErrorType kind,
1022 else 1015 else
1023 { 1016 {
1024 if (0 == 1017 if (0 ==
1025 strftime (date2, 1018 strftime (date2, DATE_STR_SIZE, "%b %d %H:%M:%S-%%020llu", tmptr))
1026 DATE_STR_SIZE, 1019 abort ();
1027 "%b %d %H:%M:%S-%%020llu", 1020 if (0 > snprintf (date,
1028 tmptr)) 1021 sizeof (date),
1029 abort (); 1022 date2,
1030 if (0 > 1023 (long long) (pc.QuadPart /
1031 snprintf (date, 1024 (performance_frequency.QuadPart / 1000))))
1032 sizeof (date), 1025 abort ();
1033 date2,
1034 (long long) (pc.QuadPart /
1035 (performance_frequency.QuadPart / 1000))))
1036 abort ();
1037 } 1026 }
1038#else 1027#else
1039 struct timeval timeofday; 1028 struct timeval timeofday;
1040 1029
1041 gettimeofday (&timeofday, 1030 gettimeofday (&timeofday, NULL);
1042 NULL);
1043 offset = GNUNET_TIME_get_offset (); 1031 offset = GNUNET_TIME_get_offset ();
1044 if (offset > 0) 1032 if (offset > 0)
1045 { 1033 {
@@ -1047,80 +1035,59 @@ mylog (enum GNUNET_ErrorType kind,
1047 timeofday.tv_usec += (offset % 1000LL) * 1000LL; 1035 timeofday.tv_usec += (offset % 1000LL) * 1000LL;
1048 if (timeofday.tv_usec > 1000000LL) 1036 if (timeofday.tv_usec > 1000000LL)
1049 { 1037 {
1050 timeofday.tv_usec -= 1000000LL; 1038 timeofday.tv_usec -= 1000000LL;
1051 timeofday.tv_sec++; 1039 timeofday.tv_sec++;
1052 } 1040 }
1053 } 1041 }
1054 else 1042 else
1055 { 1043 {
1056 timeofday.tv_sec += offset / 1000LL; 1044 timeofday.tv_sec += offset / 1000LL;
1057 if (timeofday.tv_usec > - (offset % 1000LL) * 1000LL) 1045 if (timeofday.tv_usec > -(offset % 1000LL) * 1000LL)
1058 { 1046 {
1059 timeofday.tv_usec += (offset % 1000LL) * 1000LL; 1047 timeofday.tv_usec += (offset % 1000LL) * 1000LL;
1060 } 1048 }
1061 else 1049 else
1062 { 1050 {
1063 timeofday.tv_usec += 1000000LL + (offset % 1000LL) * 1000LL; 1051 timeofday.tv_usec += 1000000LL + (offset % 1000LL) * 1000LL;
1064 timeofday.tv_sec--; 1052 timeofday.tv_sec--;
1065 } 1053 }
1066 } 1054 }
1067 tmptr = localtime (&timeofday.tv_sec); 1055 tmptr = localtime (&timeofday.tv_sec);
1068 if (NULL == tmptr) 1056 if (NULL == tmptr)
1069 { 1057 {
1070 strcpy (date, 1058 strcpy (date, "localtime error");
1071 "localtime error");
1072 } 1059 }
1073 else 1060 else
1074 { 1061 {
1075 if (0 == 1062 if (0 == strftime (date2, DATE_STR_SIZE, "%b %d %H:%M:%S-%%06u", tmptr))
1076 strftime (date2, 1063 abort ();
1077 DATE_STR_SIZE, 1064 if (0 > snprintf (date, sizeof (date), date2, timeofday.tv_usec))
1078 "%b %d %H:%M:%S-%%06u", 1065 abort ();
1079 tmptr))
1080 abort ();
1081 if (0 >
1082 snprintf (date,
1083 sizeof (date),
1084 date2,
1085 timeofday.tv_usec))
1086 abort ();
1087 } 1066 }
1088#endif 1067#endif
1089 VSNPRINTF (buf, 1068 VSNPRINTF (buf, size, message, va);
1090 size,
1091 message,
1092 va);
1093#if ! (defined(GNUNET_CULL_LOGGING) || TALER_WALLET_ONLY) 1069#if ! (defined(GNUNET_CULL_LOGGING) || TALER_WALLET_ONLY)
1094 if (NULL != tmptr) 1070 if (NULL != tmptr)
1095 (void) setup_log_file (tmptr); 1071 (void) setup_log_file (tmptr);
1096#endif 1072#endif
1097 if ((0 != (kind & GNUNET_ERROR_TYPE_BULK)) && 1073 if ((0 != (kind & GNUNET_ERROR_TYPE_BULK)) &&
1098 (0 != last_bulk_time.abs_value_us) && 1074 (0 != last_bulk_time.abs_value_us) &&
1099 (0 == strncmp (buf, 1075 (0 == strncmp (buf, last_bulk, sizeof (last_bulk))))
1100 last_bulk,
1101 sizeof (last_bulk))))
1102 { 1076 {
1103 last_bulk_repeat++; 1077 last_bulk_repeat++;
1104 if ( (GNUNET_TIME_absolute_get_duration (last_bulk_time).rel_value_us > 1078 if ((GNUNET_TIME_absolute_get_duration (last_bulk_time).rel_value_us >
1105 BULK_DELAY_THRESHOLD) || 1079 BULK_DELAY_THRESHOLD) ||
1106 (last_bulk_repeat > BULK_REPEAT_THRESHOLD) ) 1080 (last_bulk_repeat > BULK_REPEAT_THRESHOLD))
1107 flush_bulk (date); 1081 flush_bulk (date);
1108 return; 1082 return;
1109 } 1083 }
1110 flush_bulk (date); 1084 flush_bulk (date);
1111 strncpy (last_bulk, 1085 strncpy (last_bulk, buf, sizeof (last_bulk));
1112 buf,
1113 sizeof (last_bulk));
1114 last_bulk_repeat = 0; 1086 last_bulk_repeat = 0;
1115 last_bulk_kind = kind; 1087 last_bulk_kind = kind;
1116 last_bulk_time = GNUNET_TIME_absolute_get (); 1088 last_bulk_time = GNUNET_TIME_absolute_get ();
1117 strncpy (last_bulk_comp, 1089 strncpy (last_bulk_comp, comp, COMP_TRACK_SIZE);
1118 comp, 1090 output_message (kind, comp, date, buf);
1119 COMP_TRACK_SIZE);
1120 output_message (kind,
1121 comp,
1122 date,
1123 buf);
1124 } 1091 }
1125} 1092}
1126 1093
@@ -1133,8 +1100,7 @@ mylog (enum GNUNET_ErrorType kind,
1133 * @param ... arguments for format string 1100 * @param ... arguments for format string
1134 */ 1101 */
1135void 1102void
1136GNUNET_log_nocheck (enum GNUNET_ErrorType kind, 1103GNUNET_log_nocheck (enum GNUNET_ErrorType kind, const char *message, ...)
1137 const char *message, ...)
1138{ 1104{
1139 va_list va; 1105 va_list va;
1140 1106
@@ -1154,8 +1120,10 @@ GNUNET_log_nocheck (enum GNUNET_ErrorType kind,
1154 * @param ... arguments for format string 1120 * @param ... arguments for format string
1155 */ 1121 */
1156void 1122void
1157GNUNET_log_from_nocheck (enum GNUNET_ErrorType kind, const char *comp, 1123GNUNET_log_from_nocheck (enum GNUNET_ErrorType kind,
1158 const char *message, ...) 1124 const char *comp,
1125 const char *message,
1126 ...)
1159{ 1127{
1160 va_list va; 1128 va_list va;
1161 char comp_w_pid[128]; 1129 char comp_w_pid[128];
@@ -1180,18 +1148,18 @@ const char *
1180GNUNET_error_type_to_string (enum GNUNET_ErrorType kind) 1148GNUNET_error_type_to_string (enum GNUNET_ErrorType kind)
1181{ 1149{
1182 if ((kind & GNUNET_ERROR_TYPE_ERROR) > 0) 1150 if ((kind & GNUNET_ERROR_TYPE_ERROR) > 0)
1183 return _("ERROR"); 1151 return _ ("ERROR");
1184 if ((kind & GNUNET_ERROR_TYPE_WARNING) > 0) 1152 if ((kind & GNUNET_ERROR_TYPE_WARNING) > 0)
1185 return _("WARNING"); 1153 return _ ("WARNING");
1186 if ((kind & GNUNET_ERROR_TYPE_MESSAGE) > 0) 1154 if ((kind & GNUNET_ERROR_TYPE_MESSAGE) > 0)
1187 return _("MESSAGE"); 1155 return _ ("MESSAGE");
1188 if ((kind & GNUNET_ERROR_TYPE_INFO) > 0) 1156 if ((kind & GNUNET_ERROR_TYPE_INFO) > 0)
1189 return _("INFO"); 1157 return _ ("INFO");
1190 if ((kind & GNUNET_ERROR_TYPE_DEBUG) > 0) 1158 if ((kind & GNUNET_ERROR_TYPE_DEBUG) > 0)
1191 return _("DEBUG"); 1159 return _ ("DEBUG");
1192 if ((kind & ~GNUNET_ERROR_TYPE_BULK) == 0) 1160 if ((kind & ~GNUNET_ERROR_TYPE_BULK) == 0)
1193 return _("NONE"); 1161 return _ ("NONE");
1194 return _("INVALID"); 1162 return _ ("INVALID");
1195} 1163}
1196 1164
1197 1165
@@ -1202,7 +1170,7 @@ GNUNET_error_type_to_string (enum GNUNET_ErrorType kind)
1202 * @return string form; will be overwritten by next call to GNUNET_h2s. 1170 * @return string form; will be overwritten by next call to GNUNET_h2s.
1203 */ 1171 */
1204const char * 1172const char *
1205GNUNET_h2s (const struct GNUNET_HashCode * hc) 1173GNUNET_h2s (const struct GNUNET_HashCode *hc)
1206{ 1174{
1207 static GNUNET_THREAD_LOCAL struct GNUNET_CRYPTO_HashAsciiEncoded ret; 1175 static GNUNET_THREAD_LOCAL struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1208 1176
@@ -1223,7 +1191,7 @@ GNUNET_h2s (const struct GNUNET_HashCode * hc)
1223 * @return string form; will be overwritten by next call to GNUNET_h2s. 1191 * @return string form; will be overwritten by next call to GNUNET_h2s.
1224 */ 1192 */
1225const char * 1193const char *
1226GNUNET_h2s2 (const struct GNUNET_HashCode * hc) 1194GNUNET_h2s2 (const struct GNUNET_HashCode *hc)
1227{ 1195{
1228 static struct GNUNET_CRYPTO_HashAsciiEncoded ret; 1196 static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1229 1197
@@ -1248,11 +1216,8 @@ GNUNET_p2s (const struct GNUNET_CRYPTO_EddsaPublicKey *p)
1248 static struct GNUNET_CRYPTO_HashAsciiEncoded ret; 1216 static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1249 struct GNUNET_HashCode hc; 1217 struct GNUNET_HashCode hc;
1250 1218
1251 GNUNET_CRYPTO_hash (p, 1219 GNUNET_CRYPTO_hash (p, sizeof (*p), &hc);
1252 sizeof (*p), 1220 GNUNET_CRYPTO_hash_to_enc (&hc, &ret);
1253 &hc);
1254 GNUNET_CRYPTO_hash_to_enc (&hc,
1255 &ret);
1256 ret.encoding[6] = '\0'; 1221 ret.encoding[6] = '\0';
1257 return (const char *) ret.encoding; 1222 return (const char *) ret.encoding;
1258} 1223}
@@ -1273,11 +1238,8 @@ GNUNET_p2s2 (const struct GNUNET_CRYPTO_EddsaPublicKey *p)
1273 static struct GNUNET_CRYPTO_HashAsciiEncoded ret; 1238 static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1274 struct GNUNET_HashCode hc; 1239 struct GNUNET_HashCode hc;
1275 1240
1276 GNUNET_CRYPTO_hash (p, 1241 GNUNET_CRYPTO_hash (p, sizeof (*p), &hc);
1277 sizeof (*p), 1242 GNUNET_CRYPTO_hash_to_enc (&hc, &ret);
1278 &hc);
1279 GNUNET_CRYPTO_hash_to_enc (&hc,
1280 &ret);
1281 ret.encoding[6] = '\0'; 1243 ret.encoding[6] = '\0';
1282 return (const char *) ret.encoding; 1244 return (const char *) ret.encoding;
1283} 1245}
@@ -1298,11 +1260,8 @@ GNUNET_e2s (const struct GNUNET_CRYPTO_EcdhePublicKey *p)
1298 static struct GNUNET_CRYPTO_HashAsciiEncoded ret; 1260 static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1299 struct GNUNET_HashCode hc; 1261 struct GNUNET_HashCode hc;
1300 1262
1301 GNUNET_CRYPTO_hash (p, 1263 GNUNET_CRYPTO_hash (p, sizeof (*p), &hc);
1302 sizeof (*p), 1264 GNUNET_CRYPTO_hash_to_enc (&hc, &ret);
1303 &hc);
1304 GNUNET_CRYPTO_hash_to_enc (&hc,
1305 &ret);
1306 ret.encoding[6] = '\0'; 1265 ret.encoding[6] = '\0';
1307 return (const char *) ret.encoding; 1266 return (const char *) ret.encoding;
1308} 1267}
@@ -1323,11 +1282,8 @@ GNUNET_e2s2 (const struct GNUNET_CRYPTO_EcdhePublicKey *p)
1323 static struct GNUNET_CRYPTO_HashAsciiEncoded ret; 1282 static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1324 struct GNUNET_HashCode hc; 1283 struct GNUNET_HashCode hc;
1325 1284
1326 GNUNET_CRYPTO_hash (p, 1285 GNUNET_CRYPTO_hash (p, sizeof (*p), &hc);
1327 sizeof (*p), 1286 GNUNET_CRYPTO_hash_to_enc (&hc, &ret);
1328 &hc);
1329 GNUNET_CRYPTO_hash_to_enc (&hc,
1330 &ret);
1331 ret.encoding[6] = '\0'; 1287 ret.encoding[6] = '\0';
1332 return (const char *) ret.encoding; 1288 return (const char *) ret.encoding;
1333} 1289}
@@ -1347,10 +1303,27 @@ GNUNET_sh2s (const struct GNUNET_ShortHashCode *shc)
1347{ 1303{
1348 static char buf[64]; 1304 static char buf[64];
1349 1305
1350 GNUNET_STRINGS_data_to_string (shc, 1306 GNUNET_STRINGS_data_to_string (shc, sizeof (*shc), buf, sizeof (buf));
1351 sizeof (*shc), 1307 buf[6] = '\0';
1352 buf, 1308 return (const char *) buf;
1353 sizeof (buf)); 1309}
1310
1311
1312/**
1313 * @ingroup logging
1314 * Convert a UUID to a string (for printing debug messages).
1315 * This is one of the very few calls in the entire API that is
1316 * NOT reentrant!
1317 *
1318 * @param uuid the UUID
1319 * @return string
1320 */
1321const char *
1322GNUNET_uuid2s (const struct GNUNET_Uuid *uuid)
1323{
1324 static char buf[32];
1325
1326 GNUNET_STRINGS_data_to_string (uuid, sizeof (*uuid), buf, sizeof (buf));
1354 buf[6] = '\0'; 1327 buf[6] = '\0';
1355 return (const char *) buf; 1328 return (const char *) buf;
1356} 1329}
@@ -1365,7 +1338,7 @@ GNUNET_sh2s (const struct GNUNET_ShortHashCode *shc)
1365 * @return string form; will be overwritten by next call to GNUNET_h2s_full. 1338 * @return string form; will be overwritten by next call to GNUNET_h2s_full.
1366 */ 1339 */
1367const char * 1340const char *
1368GNUNET_h2s_full (const struct GNUNET_HashCode * hc) 1341GNUNET_h2s_full (const struct GNUNET_HashCode *hc)
1369{ 1342{
1370 static struct GNUNET_CRYPTO_HashAsciiEncoded ret; 1343 static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1371 1344
@@ -1391,9 +1364,7 @@ GNUNET_i2s (const struct GNUNET_PeerIdentity *pid)
1391 if (NULL == pid) 1364 if (NULL == pid)
1392 return "NULL"; 1365 return "NULL";
1393 ret = GNUNET_CRYPTO_eddsa_public_key_to_string (&pid->public_key); 1366 ret = GNUNET_CRYPTO_eddsa_public_key_to_string (&pid->public_key);
1394 strncpy (buf, 1367 strncpy (buf, ret, sizeof (buf) - 1);
1395 ret,
1396 sizeof (buf) - 1);
1397 GNUNET_free (ret); 1368 GNUNET_free (ret);
1398 buf[4] = '\0'; 1369 buf[4] = '\0';
1399 return buf; 1370 return buf;
@@ -1419,9 +1390,7 @@ GNUNET_i2s2 (const struct GNUNET_PeerIdentity *pid)
1419 if (NULL == pid) 1390 if (NULL == pid)
1420 return "NULL"; 1391 return "NULL";
1421 ret = GNUNET_CRYPTO_eddsa_public_key_to_string (&pid->public_key); 1392 ret = GNUNET_CRYPTO_eddsa_public_key_to_string (&pid->public_key);
1422 strncpy (buf, 1393 strncpy (buf, ret, sizeof (buf) - 1);
1423 ret,
1424 sizeof (buf) - 1);
1425 GNUNET_free (ret); 1394 GNUNET_free (ret);
1426 buf[4] = '\0'; 1395 buf[4] = '\0';
1427 return buf; 1396 return buf;
@@ -1459,12 +1428,12 @@ GNUNET_i2s_full (const struct GNUNET_PeerIdentity *pid)
1459 * will be overwritten by next call to #GNUNET_a2s. 1428 * will be overwritten by next call to #GNUNET_a2s.
1460 */ 1429 */
1461const char * 1430const char *
1462GNUNET_a2s (const struct sockaddr *addr, 1431GNUNET_a2s (const struct sockaddr *addr, socklen_t addrlen)
1463 socklen_t addrlen)
1464{ 1432{
1465#ifndef WINDOWS 1433#ifndef WINDOWS
1466#define LEN GNUNET_MAX ((INET6_ADDRSTRLEN + 8), \ 1434#define LEN \
1467 (1 + sizeof (struct sockaddr_un) - sizeof (sa_family_t))) 1435 GNUNET_MAX ((INET6_ADDRSTRLEN + 8), \
1436 (1 + sizeof (struct sockaddr_un) - sizeof (sa_family_t)))
1468#else 1437#else
1469#define LEN (INET6_ADDRSTRLEN + 8) 1438#define LEN (INET6_ADDRSTRLEN + 8)
1470#endif 1439#endif
@@ -1477,24 +1446,18 @@ GNUNET_a2s (const struct sockaddr *addr,
1477 unsigned int off; 1446 unsigned int off;
1478 1447
1479 if (addr == NULL) 1448 if (addr == NULL)
1480 return _("unknown address"); 1449 return _ ("unknown address");
1481 switch (addr->sa_family) 1450 switch (addr->sa_family)
1482 { 1451 {
1483 case AF_INET: 1452 case AF_INET:
1484 if (addrlen != sizeof (struct sockaddr_in)) 1453 if (addrlen != sizeof (struct sockaddr_in))
1485 return "<invalid v4 address>"; 1454 return "<invalid v4 address>";
1486 v4 = (const struct sockaddr_in *) addr; 1455 v4 = (const struct sockaddr_in *) addr;
1487 inet_ntop (AF_INET, 1456 inet_ntop (AF_INET, &v4->sin_addr, buf, INET_ADDRSTRLEN);
1488 &v4->sin_addr,
1489 buf,
1490 INET_ADDRSTRLEN);
1491 if (0 == ntohs (v4->sin_port)) 1457 if (0 == ntohs (v4->sin_port))
1492 return buf; 1458 return buf;
1493 strcat (buf, ":"); 1459 strcat (buf, ":");
1494 GNUNET_snprintf (b2, 1460 GNUNET_snprintf (b2, sizeof (b2), "%u", ntohs (v4->sin_port));
1495 sizeof (b2),
1496 "%u",
1497 ntohs (v4->sin_port));
1498 strcat (buf, b2); 1461 strcat (buf, b2);
1499 return buf; 1462 return buf;
1500 case AF_INET6: 1463 case AF_INET6:
@@ -1502,19 +1465,12 @@ GNUNET_a2s (const struct sockaddr *addr,
1502 return "<invalid v4 address>"; 1465 return "<invalid v4 address>";
1503 v6 = (const struct sockaddr_in6 *) addr; 1466 v6 = (const struct sockaddr_in6 *) addr;
1504 buf[0] = '['; 1467 buf[0] = '[';
1505 inet_ntop (AF_INET6, 1468 inet_ntop (AF_INET6, &v6->sin6_addr, &buf[1], INET6_ADDRSTRLEN);
1506 &v6->sin6_addr,
1507 &buf[1],
1508 INET6_ADDRSTRLEN);
1509 if (0 == ntohs (v6->sin6_port)) 1469 if (0 == ntohs (v6->sin6_port))
1510 return &buf[1]; 1470 return &buf[1];
1511 strcat (buf, "]:"); 1471 strcat (buf, "]:");
1512 GNUNET_snprintf (b2, 1472 GNUNET_snprintf (b2, sizeof (b2), "%u", ntohs (v6->sin6_port));
1513 sizeof (b2), 1473 strcat (buf, b2);
1514 "%u",
1515 ntohs (v6->sin6_port));
1516 strcat (buf,
1517 b2);
1518 return buf; 1474 return buf;
1519 case AF_UNIX: 1475 case AF_UNIX:
1520 if (addrlen <= sizeof (sa_family_t)) 1476 if (addrlen <= sizeof (sa_family_t))
@@ -1532,7 +1488,7 @@ GNUNET_a2s (const struct sockaddr *addr,
1532 &un->sun_path[off]); 1488 &un->sun_path[off]);
1533 return buf; 1489 return buf;
1534 default: 1490 default:
1535 return _("invalid address"); 1491 return _ ("invalid address");
1536 } 1492 }
1537} 1493}
1538 1494
@@ -1546,13 +1502,14 @@ GNUNET_a2s (const struct sockaddr *addr,
1546 */ 1502 */
1547void 1503void
1548GNUNET_log_config_missing (enum GNUNET_ErrorType kind, 1504GNUNET_log_config_missing (enum GNUNET_ErrorType kind,
1549 const char *section, 1505 const char *section,
1550 const char *option) 1506 const char *option)
1551{ 1507{
1552 GNUNET_log (kind, 1508 GNUNET_log (kind,
1553 _("Configuration fails to specify option `%s' in section `%s'!\n"), 1509 _ (
1554 option, 1510 "Configuration fails to specify option `%s' in section `%s'!\n"),
1555 section); 1511 option,
1512 section);
1556} 1513}
1557 1514
1558 1515
@@ -1566,13 +1523,17 @@ GNUNET_log_config_missing (enum GNUNET_ErrorType kind,
1566 */ 1523 */
1567void 1524void
1568GNUNET_log_config_invalid (enum GNUNET_ErrorType kind, 1525GNUNET_log_config_invalid (enum GNUNET_ErrorType kind,
1569 const char *section, 1526 const char *section,
1570 const char *option, 1527 const char *option,
1571 const char *required) 1528 const char *required)
1572{ 1529{
1573 GNUNET_log (kind, 1530 GNUNET_log (
1574 _("Configuration specifies invalid value for option `%s' in section `%s': %s\n"), 1531 kind,
1575 option, section, required); 1532 _ (
1533 "Configuration specifies invalid value for option `%s' in section `%s': %s\n"),
1534 option,
1535 section,
1536 required);
1576} 1537}
1577 1538
1578 1539
@@ -1633,15 +1594,14 @@ GNUNET_async_scope_get (struct GNUNET_AsyncScopeSave *scope_ret)
1633/** 1594/**
1634 * Initializer 1595 * Initializer
1635 */ 1596 */
1636void __attribute__ ((constructor)) 1597void __attribute__ ((constructor)) GNUNET_util_cl_init ()
1637GNUNET_util_cl_init ()
1638{ 1598{
1639 GNUNET_stderr = stderr; 1599 GNUNET_stderr = stderr;
1640#ifdef MINGW 1600#ifdef MINGW
1641 GNInitWinEnv (NULL); 1601 GNInitWinEnv (NULL);
1642#endif 1602#endif
1643#if WINDOWS 1603#if WINDOWS
1644 if (!InitializeCriticalSectionAndSpinCount (&output_message_cs, 0x00000400)) 1604 if (! InitializeCriticalSectionAndSpinCount (&output_message_cs, 0x00000400))
1645 GNUNET_abort_ (); 1605 GNUNET_abort_ ();
1646#endif 1606#endif
1647} 1607}
@@ -1650,8 +1610,7 @@ GNUNET_util_cl_init ()
1650/** 1610/**
1651 * Destructor 1611 * Destructor
1652 */ 1612 */
1653void __attribute__ ((destructor)) 1613void __attribute__ ((destructor)) GNUNET_util_cl_fini ()
1654GNUNET_util_cl_fini ()
1655{ 1614{
1656#if WINDOWS 1615#if WINDOWS
1657 DeleteCriticalSection (&output_message_cs); 1616 DeleteCriticalSection (&output_message_cs);
diff --git a/src/util/container_multiuuidmap.c b/src/util/container_multiuuidmap.c
new file mode 100644
index 000000000..49eb64cfe
--- /dev/null
+++ b/src/util/container_multiuuidmap.c
@@ -0,0 +1,1015 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2008, 2012 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19*/
20/**
21 * @file util/container_multiuuidmap.c
22 * @brief hash map for UUIDs where the same key may be present multiple times
23 * @author Christian Grothoff
24 */
25
26#include "platform.h"
27#include "gnunet_util_lib.h"
28
29#define LOG(kind, ...) \
30 GNUNET_log_from (kind, "util-container-multiuuidmap", __VA_ARGS__)
31
32/**
33 * Maximum recursion depth for callbacks of
34 * #GNUNET_CONTAINER_multihashmap_get_multiple() themselve s
35 * again calling #GNUNET_CONTAINER_multihashmap_get_multiple().
36 * Should be totally excessive, but if violated we die.
37 */
38#define NEXT_CACHE_SIZE 16
39
40
41/**
42 * An entry in the hash map with the full key.
43 */
44struct BigMapEntry
45{
46
47 /**
48 * Value of the entry.
49 */
50 void *value;
51
52 /**
53 * If there is a hash collision, we create a linked list.
54 */
55 struct BigMapEntry *next;
56
57 /**
58 * Key for the entry.
59 */
60 struct GNUNET_Uuid key;
61};
62
63
64/**
65 * An entry in the hash map with just a pointer to the key.
66 */
67struct SmallMapEntry
68{
69
70 /**
71 * Value of the entry.
72 */
73 void *value;
74
75 /**
76 * If there is a hash collision, we create a linked list.
77 */
78 struct SmallMapEntry *next;
79
80 /**
81 * Key for the entry.
82 */
83 const struct GNUNET_Uuid *key;
84};
85
86
87/**
88 * Entry in the map.
89 */
90union MapEntry
91{
92 /**
93 * Variant used if map entries only contain a pointer to the key.
94 */
95 struct SmallMapEntry *sme;
96
97 /**
98 * Variant used if map entries contain the full key.
99 */
100 struct BigMapEntry *bme;
101};
102
103
104/**
105 * Internal representation of the hash map.
106 */
107struct GNUNET_CONTAINER_MultiUuidmap
108{
109 /**
110 * All of our buckets.
111 */
112 union MapEntry *map;
113
114 /**
115 * Number of entries in the map.
116 */
117 unsigned int size;
118
119 /**
120 * Length of the "map" array.
121 */
122 unsigned int map_length;
123
124 /**
125 * #GNUNET_NO if the map entries are of type 'struct BigMapEntry',
126 * #GNUNET_YES if the map entries are of type 'struct SmallMapEntry'.
127 */
128 int use_small_entries;
129
130 /**
131 * Counts the destructive modifications (grow, remove)
132 * to the map, so that iterators can check if they are still valid.
133 */
134 unsigned int modification_counter;
135
136 /**
137 * Map entries indicating iteration positions currently
138 * in use by #GNUNET_CONTAINER_multihashmap_get_multiple().
139 * Only used up to @e next_cache_off.
140 */
141 union MapEntry next_cache[NEXT_CACHE_SIZE];
142
143 /**
144 * Offset of @e next_cache entries in use, must be smaller
145 * than #NEXT_CACHE_SIZE.
146 */
147 unsigned int next_cache_off;
148};
149
150
151/**
152 * Cursor into a multiuuidmap.
153 * Allows to enumerate elements asynchronously.
154 */
155struct GNUNET_CONTAINER_MultiUuidmapIterator
156{
157 /**
158 * Position in the bucket 'idx'
159 */
160 union MapEntry me;
161
162 /**
163 * Current bucket index.
164 */
165 unsigned int idx;
166
167 /**
168 * Modification counter as observed on the map when the iterator
169 * was created.
170 */
171 unsigned int modification_counter;
172
173 /**
174 * Map that we are iterating over.
175 */
176 const struct GNUNET_CONTAINER_MultiUuidmap *map;
177};
178
179
180/**
181 * Create a multi hash map.
182 *
183 * @param len initial size (map will grow as needed)
184 * @param do_not_copy_keys #GNUNET_NO is always safe and should be used by default;
185 * #GNUNET_YES means that on 'put', the 'key' does not have
186 * to be copied as the destination of the pointer is
187 * guaranteed to be life as long as the value is stored in
188 * the hashmap. This can significantly reduce memory
189 * consumption, but of course is also a recipie for
190 * heap corruption if the assumption is not true. Only
191 * use this if (1) memory use is important in this case and
192 * (2) you have triple-checked that the invariant holds
193 * @return NULL on error
194 */
195struct GNUNET_CONTAINER_MultiUuidmap *
196GNUNET_CONTAINER_multiuuidmap_create (unsigned int len, int do_not_copy_keys)
197{
198 struct GNUNET_CONTAINER_MultiUuidmap *map;
199
200 GNUNET_assert (len > 0);
201 map = GNUNET_new (struct GNUNET_CONTAINER_MultiUuidmap);
202 map->map = GNUNET_malloc_large (len * sizeof (union MapEntry));
203 if (NULL == map->map)
204 {
205 GNUNET_free (map);
206 return NULL;
207 }
208 map->map_length = len;
209 map->use_small_entries = do_not_copy_keys;
210 return map;
211}
212
213
214/**
215 * Destroy a hash map. Will not free any values
216 * stored in the hash map!
217 *
218 * @param map the map
219 */
220void
221GNUNET_CONTAINER_multiuuidmap_destroy (
222 struct GNUNET_CONTAINER_MultiUuidmap *map)
223{
224 GNUNET_assert (0 == map->next_cache_off);
225 for (unsigned int i = 0; i < map->map_length; i++)
226 {
227 union MapEntry me;
228
229 me = map->map[i];
230 if (map->use_small_entries)
231 {
232 struct SmallMapEntry *sme;
233 struct SmallMapEntry *nxt;
234
235 nxt = me.sme;
236 while (NULL != (sme = nxt))
237 {
238 nxt = sme->next;
239 GNUNET_free (sme);
240 }
241 me.sme = NULL;
242 }
243 else
244 {
245 struct BigMapEntry *bme;
246 struct BigMapEntry *nxt;
247
248 nxt = me.bme;
249 while (NULL != (bme = nxt))
250 {
251 nxt = bme->next;
252 GNUNET_free (bme);
253 }
254 me.bme = NULL;
255 }
256 }
257 GNUNET_free (map->map);
258 GNUNET_free (map);
259}
260
261
262/**
263 * Compute the index of the bucket for the given key.
264 *
265 * @param map hash map for which to compute the index
266 * @param key what key should the index be computed for
267 * @return offset into the "map" array of "map"
268 */
269static unsigned int
270idx_of (const struct GNUNET_CONTAINER_MultiUuidmap *map,
271 const struct GNUNET_Uuid *key)
272{
273 unsigned int kx;
274
275 GNUNET_assert (NULL != map);
276 GNUNET_memcpy (&kx, key, sizeof (kx));
277 return kx % map->map_length;
278}
279
280
281/**
282 * Get the number of key-value pairs in the map.
283 *
284 * @param map the map
285 * @return the number of key value pairs
286 */
287unsigned int
288GNUNET_CONTAINER_multiuuidmap_size (
289 const struct GNUNET_CONTAINER_MultiUuidmap *map)
290{
291 return map->size;
292}
293
294
295/**
296 * Given a key find a value in the map matching the key.
297 *
298 * @param map the map
299 * @param key what to look for
300 * @return NULL if no value was found; note that
301 * this is indistinguishable from values that just
302 * happen to be NULL; use "contains" to test for
303 * key-value pairs with value NULL
304 */
305void *
306GNUNET_CONTAINER_multiuuidmap_get (
307 const struct GNUNET_CONTAINER_MultiUuidmap *map,
308 const struct GNUNET_Uuid *key)
309{
310 union MapEntry me;
311
312 me = map->map[idx_of (map, key)];
313 if (map->use_small_entries)
314 {
315 for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
316 if (0 == GNUNET_memcmp (key, sme->key))
317 return sme->value;
318 }
319 else
320 {
321 for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
322 if (0 == GNUNET_memcmp (key, &bme->key))
323 return bme->value;
324 }
325 return NULL;
326}
327
328
329/**
330 * Iterate over all entries in the map.
331 *
332 * @param map the map
333 * @param it function to call on each entry
334 * @param it_cls extra argument to @a it
335 * @return the number of key value pairs processed,
336 * #GNUNET_SYSERR if it aborted iteration
337 */
338int
339GNUNET_CONTAINER_multiuuidmap_iterate (
340 struct GNUNET_CONTAINER_MultiUuidmap *map,
341 GNUNET_CONTAINER_MultiUuidmapIterator it,
342 void *it_cls)
343{
344 int count;
345 union MapEntry me;
346 union MapEntry *ce;
347 struct GNUNET_Uuid kc;
348
349 count = 0;
350 GNUNET_assert (NULL != map);
351 ce = &map->next_cache[map->next_cache_off];
352 GNUNET_assert (++map->next_cache_off < NEXT_CACHE_SIZE);
353 for (unsigned int i = 0; i < map->map_length; i++)
354 {
355 me = map->map[i];
356 if (map->use_small_entries)
357 {
358 struct SmallMapEntry *sme;
359
360 ce->sme = me.sme;
361 while (NULL != (sme = ce->sme))
362 {
363 ce->sme = sme->next;
364 if ((NULL != it) && (GNUNET_OK != it (it_cls, sme->key, sme->value)))
365 {
366 GNUNET_assert (--map->next_cache_off < NEXT_CACHE_SIZE);
367 return GNUNET_SYSERR;
368 }
369 count++;
370 }
371 }
372 else
373 {
374 struct BigMapEntry *bme;
375
376 ce->bme = me.bme;
377 while (NULL != (bme = ce->bme))
378 {
379 ce->bme = bme->next;
380 if (NULL != it)
381 {
382 kc = bme->key;
383 if (GNUNET_OK != it (it_cls, &kc, bme->value))
384 {
385 GNUNET_assert (--map->next_cache_off < NEXT_CACHE_SIZE);
386 return GNUNET_SYSERR;
387 }
388 }
389 count++;
390 }
391 }
392 }
393 GNUNET_assert (--map->next_cache_off < NEXT_CACHE_SIZE);
394 return count;
395}
396
397
398/**
399 * We are about to free() the @a bme, make sure it is not in
400 * the list of next values for any iterator in the @a map's next_cache.
401 *
402 * @param map the map to check
403 * @param bme the entry that is about to be free'd
404 */
405static void
406update_next_cache_bme (struct GNUNET_CONTAINER_MultiUuidmap *map,
407 const struct BigMapEntry *bme)
408{
409 for (unsigned int i = 0; i < map->next_cache_off; i++)
410 if (map->next_cache[i].bme == bme)
411 map->next_cache[i].bme = bme->next;
412}
413
414
415/**
416 * We are about to free() the @a sme, make sure it is not in
417 * the list of next values for any iterator in the @a map's next_cache.
418 *
419 * @param map the map to check
420 * @param sme the entry that is about to be free'd
421 */
422static void
423update_next_cache_sme (struct GNUNET_CONTAINER_MultiUuidmap *map,
424 const struct SmallMapEntry *sme)
425{
426 for (unsigned int i = 0; i < map->next_cache_off; i++)
427 if (map->next_cache[i].sme == sme)
428 map->next_cache[i].sme = sme->next;
429}
430
431
432/**
433 * Remove the given key-value pair from the map. Note that if the
434 * key-value pair is in the map multiple times, only one of the pairs
435 * will be removed.
436 *
437 * @param map the map
438 * @param key key of the key-value pair
439 * @param value value of the key-value pair
440 * @return #GNUNET_YES on success, #GNUNET_NO if the key-value pair
441 * is not in the map
442 */
443int
444GNUNET_CONTAINER_multiuuidmap_remove (struct GNUNET_CONTAINER_MultiUuidmap *map,
445 const struct GNUNET_Uuid *key,
446 const void *value)
447{
448 union MapEntry me;
449 unsigned int i;
450
451 map->modification_counter++;
452 i = idx_of (map, key);
453 me = map->map[i];
454 if (map->use_small_entries)
455 {
456 struct SmallMapEntry *p = NULL;
457
458 for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
459 {
460 if ((0 == GNUNET_memcmp (key, sme->key)) && (value == sme->value))
461 {
462 if (NULL == p)
463 map->map[i].sme = sme->next;
464 else
465 p->next = sme->next;
466 update_next_cache_sme (map, sme);
467 GNUNET_free (sme);
468 map->size--;
469 return GNUNET_YES;
470 }
471 p = sme;
472 }
473 }
474 else
475 {
476 struct BigMapEntry *p = NULL;
477
478 for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
479 {
480 if ((0 == GNUNET_memcmp (key, &bme->key)) && (value == bme->value))
481 {
482 if (NULL == p)
483 map->map[i].bme = bme->next;
484 else
485 p->next = bme->next;
486 update_next_cache_bme (map, bme);
487 GNUNET_free (bme);
488 map->size--;
489 return GNUNET_YES;
490 }
491 p = bme;
492 }
493 }
494 return GNUNET_NO;
495}
496
497
498/**
499 * Remove all entries for the given key from the map.
500 * Note that the values would not be "freed".
501 *
502 * @param map the map
503 * @param key identifies values to be removed
504 * @return number of values removed
505 */
506int
507GNUNET_CONTAINER_multiuuidmap_remove_all (
508 struct GNUNET_CONTAINER_MultiUuidmap *map,
509 const struct GNUNET_Uuid *key)
510{
511 union MapEntry me;
512 unsigned int i;
513 int ret;
514
515 map->modification_counter++;
516
517 ret = 0;
518 i = idx_of (map, key);
519 me = map->map[i];
520 if (map->use_small_entries)
521 {
522 struct SmallMapEntry *sme;
523 struct SmallMapEntry *p;
524
525 p = NULL;
526 sme = me.sme;
527 while (NULL != sme)
528 {
529 if (0 == GNUNET_memcmp (key, sme->key))
530 {
531 if (NULL == p)
532 map->map[i].sme = sme->next;
533 else
534 p->next = sme->next;
535 update_next_cache_sme (map, sme);
536 GNUNET_free (sme);
537 map->size--;
538 if (NULL == p)
539 sme = map->map[i].sme;
540 else
541 sme = p->next;
542 ret++;
543 }
544 else
545 {
546 p = sme;
547 sme = sme->next;
548 }
549 }
550 }
551 else
552 {
553 struct BigMapEntry *bme;
554 struct BigMapEntry *p;
555
556 p = NULL;
557 bme = me.bme;
558 while (NULL != bme)
559 {
560 if (0 == GNUNET_memcmp (key, &bme->key))
561 {
562 if (NULL == p)
563 map->map[i].bme = bme->next;
564 else
565 p->next = bme->next;
566 update_next_cache_bme (map, bme);
567 GNUNET_free (bme);
568 map->size--;
569 if (NULL == p)
570 bme = map->map[i].bme;
571 else
572 bme = p->next;
573 ret++;
574 }
575 else
576 {
577 p = bme;
578 bme = bme->next;
579 }
580 }
581 }
582 return ret;
583}
584
585
586/**
587 * Check if the map contains any value under the given
588 * key (including values that are NULL).
589 *
590 * @param map the map
591 * @param key the key to test if a value exists for it
592 * @return #GNUNET_YES if such a value exists,
593 * #GNUNET_NO if not
594 */
595int
596GNUNET_CONTAINER_multiuuidmap_contains (
597 const struct GNUNET_CONTAINER_MultiUuidmap *map,
598 const struct GNUNET_Uuid *key)
599{
600 union MapEntry me;
601
602 me = map->map[idx_of (map, key)];
603 if (map->use_small_entries)
604 {
605 for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
606 if (0 == GNUNET_memcmp (key, sme->key))
607 return GNUNET_YES;
608 }
609 else
610 {
611 for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
612 if (0 == GNUNET_memcmp (key, &bme->key))
613 return GNUNET_YES;
614 }
615 return GNUNET_NO;
616}
617
618
619/**
620 * Check if the map contains the given value under the given
621 * key.
622 *
623 * @param map the map
624 * @param key the key to test if a value exists for it
625 * @param value value to test for
626 * @return #GNUNET_YES if such a value exists,
627 * #GNUNET_NO if not
628 */
629int
630GNUNET_CONTAINER_multiuuidmap_contains_value (
631 const struct GNUNET_CONTAINER_MultiUuidmap *map,
632 const struct GNUNET_Uuid *key,
633 const void *value)
634{
635 union MapEntry me;
636
637 me = map->map[idx_of (map, key)];
638 if (map->use_small_entries)
639 {
640 for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
641 if ((0 == GNUNET_memcmp (key, sme->key)) && (sme->value == value))
642 return GNUNET_YES;
643 }
644 else
645 {
646 for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
647 if ((0 == GNUNET_memcmp (key, &bme->key)) && (bme->value == value))
648 return GNUNET_YES;
649 }
650 return GNUNET_NO;
651}
652
653
654/**
655 * Grow the given map to a more appropriate size.
656 *
657 * @param map the hash map to grow
658 */
659static void
660grow (struct GNUNET_CONTAINER_MultiUuidmap *map)
661{
662 union MapEntry *old_map;
663 union MapEntry *new_map;
664 unsigned int old_len;
665 unsigned int new_len;
666 unsigned int idx;
667
668 old_map = map->map;
669 old_len = map->map_length;
670 new_len = old_len * 2;
671 if (0 == new_len) /* 2^31 * 2 == 0 */
672 new_len = old_len; /* never use 0 */
673 if (new_len == old_len)
674 return; /* nothing changed */
675 new_map = GNUNET_malloc_large (new_len * sizeof (union MapEntry));
676 if (NULL == new_map)
677 return; /* grow not possible */
678 map->modification_counter++;
679 map->map_length = new_len;
680 map->map = new_map;
681 for (unsigned int i = 0; i < old_len; i++)
682 {
683 if (map->use_small_entries)
684 {
685 struct SmallMapEntry *sme;
686
687 while (NULL != (sme = old_map[i].sme))
688 {
689 old_map[i].sme = sme->next;
690 idx = idx_of (map, sme->key);
691 sme->next = new_map[idx].sme;
692 new_map[idx].sme = sme;
693 }
694 }
695 else
696 {
697 struct BigMapEntry *bme;
698
699 while (NULL != (bme = old_map[i].bme))
700 {
701 old_map[i].bme = bme->next;
702 idx = idx_of (map, &bme->key);
703 bme->next = new_map[idx].bme;
704 new_map[idx].bme = bme;
705 }
706 }
707 }
708 GNUNET_free (old_map);
709}
710
711
712/**
713 * Store a key-value pair in the map.
714 *
715 * @param map the map
716 * @param key key to use
717 * @param value value to use
718 * @param opt options for put
719 * @return #GNUNET_OK on success,
720 * #GNUNET_NO if a value was replaced (with REPLACE)
721 * #GNUNET_SYSERR if #GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY was the option and the
722 * value already exists
723 */
724int
725GNUNET_CONTAINER_multiuuidmap_put (struct GNUNET_CONTAINER_MultiUuidmap *map,
726 const struct GNUNET_Uuid *key,
727 void *value,
728 enum GNUNET_CONTAINER_MultiHashMapOption opt)
729{
730 union MapEntry me;
731 unsigned int i;
732
733 i = idx_of (map, key);
734 if ((opt != GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE) &&
735 (opt != GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
736 {
737 me = map->map[i];
738 if (map->use_small_entries)
739 {
740 for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
741 if (0 == GNUNET_memcmp (key, sme->key))
742 {
743 if (opt == GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)
744 return GNUNET_SYSERR;
745 sme->value = value;
746 return GNUNET_NO;
747 }
748 }
749 else
750 {
751 for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
752 if (0 == GNUNET_memcmp (key, &bme->key))
753 {
754 if (opt == GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)
755 return GNUNET_SYSERR;
756 bme->value = value;
757 return GNUNET_NO;
758 }
759 }
760 }
761 if (map->size / 3 >= map->map_length / 4)
762 {
763 grow (map);
764 i = idx_of (map, key);
765 }
766 if (map->use_small_entries)
767 {
768 struct SmallMapEntry *sme;
769
770 sme = GNUNET_new (struct SmallMapEntry);
771 sme->key = key;
772 sme->value = value;
773 sme->next = map->map[i].sme;
774 map->map[i].sme = sme;
775 }
776 else
777 {
778 struct BigMapEntry *bme;
779
780 bme = GNUNET_new (struct BigMapEntry);
781 bme->key = *key;
782 bme->value = value;
783 bme->next = map->map[i].bme;
784 map->map[i].bme = bme;
785 }
786 map->size++;
787 return GNUNET_OK;
788}
789
790
791/**
792 * Iterate over all entries in the map that match a particular key.
793 *
794 * @param map the map
795 * @param key key that the entries must correspond to
796 * @param it function to call on each entry
797 * @param it_cls extra argument to @a it
798 * @return the number of key value pairs processed,
799 * #GNUNET_SYSERR if it aborted iteration
800 */
801int
802GNUNET_CONTAINER_multiuuidmap_get_multiple (
803 struct GNUNET_CONTAINER_MultiUuidmap *map,
804 const struct GNUNET_Uuid *key,
805 GNUNET_CONTAINER_MultiUuidmapIterator it,
806 void *it_cls)
807{
808 int count;
809 union MapEntry me;
810 union MapEntry *ce;
811
812 ce = &map->next_cache[map->next_cache_off];
813 GNUNET_assert (++map->next_cache_off < NEXT_CACHE_SIZE);
814 count = 0;
815 me = map->map[idx_of (map, key)];
816 if (map->use_small_entries)
817 {
818 struct SmallMapEntry *sme;
819
820 ce->sme = me.sme;
821 while (NULL != (sme = ce->sme))
822 {
823 ce->sme = sme->next;
824 if (0 != GNUNET_memcmp (key, sme->key))
825 continue;
826 if ((NULL != it) && (GNUNET_OK != it (it_cls, key, sme->value)))
827 {
828 GNUNET_assert (--map->next_cache_off < NEXT_CACHE_SIZE);
829 return GNUNET_SYSERR;
830 }
831 count++;
832 }
833 }
834 else
835 {
836 struct BigMapEntry *bme;
837
838 ce->bme = me.bme;
839 while (NULL != (bme = ce->bme))
840 {
841 ce->bme = bme->next;
842 if (0 != GNUNET_memcmp (key, &bme->key))
843 continue;
844 if ((NULL != it) && (GNUNET_OK != it (it_cls, key, bme->value)))
845 {
846 GNUNET_assert (--map->next_cache_off < NEXT_CACHE_SIZE);
847 return GNUNET_SYSERR;
848 }
849 count++;
850 }
851 }
852 GNUNET_assert (--map->next_cache_off < NEXT_CACHE_SIZE);
853 return count;
854}
855
856
857/**
858 * @ingroup hashmap
859 * Call @a it on a random value from the map, or not at all
860 * if the map is empty. Note that this function has linear
861 * complexity (in the size of the map).
862 *
863 * @param map the map
864 * @param it function to call on a random entry
865 * @param it_cls extra argument to @a it
866 * @return the number of key value pairs processed, zero or one.
867 */
868unsigned int
869GNUNET_CONTAINER_multiuuidmap_get_random (
870 const struct GNUNET_CONTAINER_MultiUuidmap *map,
871 GNUNET_CONTAINER_MultiUuidmapIterator it,
872 void *it_cls)
873{
874 unsigned int off;
875 union MapEntry me;
876
877 if (0 == map->size)
878 return 0;
879 if (NULL == it)
880 return 1;
881 off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, map->size);
882 for (unsigned int idx = 0; idx < map->map_length; idx++)
883 {
884 me = map->map[idx];
885 if (map->use_small_entries)
886 {
887 for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
888 {
889 if (0 == off)
890 {
891 if (GNUNET_OK != it (it_cls, sme->key, sme->value))
892 return GNUNET_SYSERR;
893 return 1;
894 }
895 off--;
896 }
897 }
898 else
899 {
900 for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
901 {
902 if (0 == off)
903 {
904 if (GNUNET_OK != it (it_cls, &bme->key, bme->value))
905 return GNUNET_SYSERR;
906 return 1;
907 }
908 off--;
909 }
910 }
911 }
912 GNUNET_break (0);
913 return GNUNET_SYSERR;
914}
915
916
917/**
918 * Create an iterator for a multiuuidmap.
919 * The iterator can be used to retrieve all the elements in the multiuuidmap
920 * one by one, without having to handle all elements at once (in contrast to
921 * #GNUNET_CONTAINER_multiuuidmap_iterate). Note that the iterator can not be
922 * used anymore if elements have been removed from 'map' after the creation of
923 * the iterator, or 'map' has been destroyed. Adding elements to 'map' may
924 * result in skipped or repeated elements.
925 *
926 * @param map the map to create an iterator for
927 * @return an iterator over the given multiuuidmap 'map'
928 */
929struct GNUNET_CONTAINER_MultiUuidmapIterator *
930GNUNET_CONTAINER_multiuuidmap_iterator_create (
931 const struct GNUNET_CONTAINER_MultiUuidmap *map)
932{
933 struct GNUNET_CONTAINER_MultiUuidmapIterator *iter;
934
935 iter = GNUNET_new (struct GNUNET_CONTAINER_MultiUuidmapIterator);
936 iter->map = map;
937 iter->modification_counter = map->modification_counter;
938 iter->me = map->map[0];
939 return iter;
940}
941
942
943/**
944 * Retrieve the next element from the hash map at the iterator's position.
945 * If there are no elements left, GNUNET_NO is returned, and 'key' and 'value'
946 * are not modified.
947 * This operation is only allowed if no elements have been removed from the
948 * multiuuidmap since the creation of 'iter', and the map has not been destroyed.
949 * Adding elements may result in repeating or skipping elements.
950 *
951 * @param iter the iterator to get the next element from
952 * @param key pointer to store the key in, can be NULL
953 * @param value pointer to store the value in, can be NULL
954 * @return #GNUNET_YES we returned an element,
955 * #GNUNET_NO if we are out of elements
956 */
957int
958GNUNET_CONTAINER_multiuuidmap_iterator_next (
959 struct GNUNET_CONTAINER_MultiUuidmapIterator *iter,
960 struct GNUNET_Uuid *key,
961 const void **value)
962{
963 /* make sure the map has not been modified */
964 GNUNET_assert (iter->modification_counter == iter->map->modification_counter);
965
966 /* look for the next entry, skipping empty buckets */
967 while (1)
968 {
969 if (iter->idx >= iter->map->map_length)
970 return GNUNET_NO;
971 if (GNUNET_YES == iter->map->use_small_entries)
972 {
973 if (NULL != iter->me.sme)
974 {
975 if (NULL != key)
976 *key = *iter->me.sme->key;
977 if (NULL != value)
978 *value = iter->me.sme->value;
979 iter->me.sme = iter->me.sme->next;
980 return GNUNET_YES;
981 }
982 }
983 else
984 {
985 if (NULL != iter->me.bme)
986 {
987 if (NULL != key)
988 *key = iter->me.bme->key;
989 if (NULL != value)
990 *value = iter->me.bme->value;
991 iter->me.bme = iter->me.bme->next;
992 return GNUNET_YES;
993 }
994 }
995 iter->idx += 1;
996 if (iter->idx < iter->map->map_length)
997 iter->me = iter->map->map[iter->idx];
998 }
999}
1000
1001
1002/**
1003 * Destroy a multiuuidmap iterator.
1004 *
1005 * @param iter the iterator to destroy
1006 */
1007void
1008GNUNET_CONTAINER_multiuuidmap_iterator_destroy (
1009 struct GNUNET_CONTAINER_MultiUuidmapIterator *iter)
1010{
1011 GNUNET_free (iter);
1012}
1013
1014
1015/* end of container_multiuuidmap.c */