diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/include/gnunet_container_lib.h | 21 | ||||
-rw-r--r-- | src/util/container_multihashmap.c | 3 | ||||
-rw-r--r-- | src/util/container_multipeermap.c | 78 |
3 files changed, 97 insertions, 5 deletions
diff --git a/src/include/gnunet_container_lib.h b/src/include/gnunet_container_lib.h index 1ecf4f52a..d8886c504 100644 --- a/src/include/gnunet_container_lib.h +++ b/src/include/gnunet_container_lib.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2001-2013 Christian Grothoff (and other contributing authors) | 3 | Copyright (C) 2001-2015 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -857,7 +857,8 @@ GNUNET_CONTAINER_multihashmap_get_multiple (const struct GNUNET_CONTAINER_MultiH | |||
857 | /** | 857 | /** |
858 | * @ingroup hashmap | 858 | * @ingroup hashmap |
859 | * Call @a it on a random value from the map, or not at all | 859 | * Call @a it on a random value from the map, or not at all |
860 | * if the map is empty. | 860 | * if the map is empty. Note that this function has linear |
861 | * complexity (in the size of the map). | ||
861 | * | 862 | * |
862 | * @param map the map | 863 | * @param map the map |
863 | * @param it function to call on a random entry | 864 | * @param it function to call on a random entry |
@@ -1115,6 +1116,22 @@ GNUNET_CONTAINER_multipeermap_get_multiple (const struct GNUNET_CONTAINER_MultiP | |||
1115 | void *it_cls); | 1116 | void *it_cls); |
1116 | 1117 | ||
1117 | 1118 | ||
1119 | /** | ||
1120 | * @ingroup hashmap | ||
1121 | * Call @a it on a random value from the map, or not at all | ||
1122 | * if the map is empty. Note that this function has linear | ||
1123 | * complexity (in the size of the map). | ||
1124 | * | ||
1125 | * @param map the map | ||
1126 | * @param it function to call on a random entry | ||
1127 | * @param it_cls extra argument to @a it | ||
1128 | * @return the number of key value pairs processed, zero or one. | ||
1129 | */ | ||
1130 | unsigned int | ||
1131 | GNUNET_CONTAINER_multipeermap_get_random (const struct GNUNET_CONTAINER_MultiPeerMap *map, | ||
1132 | GNUNET_CONTAINER_PeerMapIterator it, | ||
1133 | void *it_cls); | ||
1134 | |||
1118 | 1135 | ||
1119 | /* Version of multihashmap with 32 bit keys */ | 1136 | /* Version of multihashmap with 32 bit keys */ |
1120 | 1137 | ||
diff --git a/src/util/container_multihashmap.c b/src/util/container_multihashmap.c index 80545176d..df6dd5704 100644 --- a/src/util/container_multihashmap.c +++ b/src/util/container_multihashmap.c | |||
@@ -841,7 +841,8 @@ GNUNET_CONTAINER_multihashmap_get_multiple (const struct | |||
841 | /** | 841 | /** |
842 | * @ingroup hashmap | 842 | * @ingroup hashmap |
843 | * Call @a it on a random value from the map, or not at all | 843 | * Call @a it on a random value from the map, or not at all |
844 | * if the map is empty. | 844 | * if the map is empty. Note that this function has linear |
845 | * complexity (in the size of the map). | ||
845 | * | 846 | * |
846 | * @param map the map | 847 | * @param map the map |
847 | * @param it function to call on a random entry | 848 | * @param it function to call on a random entry |
diff --git a/src/util/container_multipeermap.c b/src/util/container_multipeermap.c index bed9e6042..15517b92a 100644 --- a/src/util/container_multipeermap.c +++ b/src/util/container_multipeermap.c | |||
@@ -482,7 +482,7 @@ GNUNET_CONTAINER_multipeermap_remove_all (struct GNUNET_CONTAINER_MultiPeerMap | |||
482 | sme = map->map[i].sme; | 482 | sme = map->map[i].sme; |
483 | else | 483 | else |
484 | sme = p->next; | 484 | sme = p->next; |
485 | ret++; | 485 | ret++; |
486 | } | 486 | } |
487 | else | 487 | else |
488 | { | 488 | { |
@@ -645,7 +645,7 @@ grow (struct GNUNET_CONTAINER_MultiPeerMap *map) | |||
645 | struct BigMapEntry *bme; | 645 | struct BigMapEntry *bme; |
646 | 646 | ||
647 | while (NULL != (bme = old_map[i].bme)) | 647 | while (NULL != (bme = old_map[i].bme)) |
648 | { | 648 | { |
649 | old_map[i].bme = bme->next; | 649 | old_map[i].bme = bme->next; |
650 | idx = idx_of (map, &bme->key); | 650 | idx = idx_of (map, &bme->key); |
651 | bme->next = new_map[idx].bme; | 651 | bme->next = new_map[idx].bme; |
@@ -798,6 +798,80 @@ GNUNET_CONTAINER_multipeermap_get_multiple (const struct GNUNET_CONTAINER_MultiP | |||
798 | 798 | ||
799 | 799 | ||
800 | /** | 800 | /** |
801 | * @ingroup hashmap | ||
802 | * Call @a it on a random value from the map, or not at all | ||
803 | * if the map is empty. Note that this function has linear | ||
804 | * complexity (in the size of the map). | ||
805 | * | ||
806 | * @param map the map | ||
807 | * @param it function to call on a random entry | ||
808 | * @param it_cls extra argument to @a it | ||
809 | * @return the number of key value pairs processed, zero or one. | ||
810 | */ | ||
811 | unsigned int | ||
812 | GNUNET_CONTAINER_multipeermap_get_random (const struct GNUNET_CONTAINER_MultiPeerMap *map, | ||
813 | GNUNET_CONTAINER_PeerMapIterator it, | ||
814 | void *it_cls) | ||
815 | { | ||
816 | unsigned int off; | ||
817 | unsigned int idx; | ||
818 | union MapEntry me; | ||
819 | |||
820 | if (0 == map->size) | ||
821 | return 0; | ||
822 | if (NULL == it) | ||
823 | return 1; | ||
824 | off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, | ||
825 | map->size); | ||
826 | for (idx = 0; idx < map->map_length; idx++) | ||
827 | { | ||
828 | me = map->map[idx]; | ||
829 | if (map->use_small_entries) | ||
830 | { | ||
831 | struct SmallMapEntry *sme; | ||
832 | struct SmallMapEntry *nxt; | ||
833 | |||
834 | nxt = me.sme; | ||
835 | while (NULL != (sme = nxt)) | ||
836 | { | ||
837 | nxt = sme->next; | ||
838 | if (0 == off) | ||
839 | { | ||
840 | if (GNUNET_OK != it (it_cls, | ||
841 | sme->key, | ||
842 | sme->value)) | ||
843 | return GNUNET_SYSERR; | ||
844 | return 1; | ||
845 | } | ||
846 | off--; | ||
847 | } | ||
848 | } | ||
849 | else | ||
850 | { | ||
851 | struct BigMapEntry *bme; | ||
852 | struct BigMapEntry *nxt; | ||
853 | |||
854 | nxt = me.bme; | ||
855 | while (NULL != (bme = nxt)) | ||
856 | { | ||
857 | nxt = bme->next; | ||
858 | if (0 == off) | ||
859 | { | ||
860 | if (GNUNET_OK != it (it_cls, | ||
861 | &bme->key, bme->value)) | ||
862 | return GNUNET_SYSERR; | ||
863 | return 1; | ||
864 | } | ||
865 | off--; | ||
866 | } | ||
867 | } | ||
868 | } | ||
869 | GNUNET_break (0); | ||
870 | return GNUNET_SYSERR; | ||
871 | } | ||
872 | |||
873 | |||
874 | /** | ||
801 | * Create an iterator for a multipeermap. | 875 | * Create an iterator for a multipeermap. |
802 | * The iterator can be used to retrieve all the elements in the multipeermap | 876 | * The iterator can be used to retrieve all the elements in the multipeermap |
803 | * one by one, without having to handle all elements at once (in contrast to | 877 | * one by one, without having to handle all elements at once (in contrast to |