diff options
author | Christian Grothoff <christian@grothoff.org> | 2015-04-28 15:05:12 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2015-04-28 15:05:12 +0000 |
commit | 7581e114280c0c33f375b5d3ba49508b82680755 (patch) | |
tree | d24afeeda69f94b70d1dc325db06810a4b0b1be0 /src/util | |
parent | 553909348c19833330ad94d7a1064eaf48f97e3f (diff) | |
download | gnunet-7581e114280c0c33f375b5d3ba49508b82680755.tar.gz gnunet-7581e114280c0c33f375b5d3ba49508b82680755.zip |
extending datacache API with function to return random element, implemented (only) in heap plugin right now
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/container_multihashmap.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/src/util/container_multihashmap.c b/src/util/container_multihashmap.c index 789e8f370..80545176d 100644 --- a/src/util/container_multihashmap.c +++ b/src/util/container_multihashmap.c | |||
@@ -839,6 +839,79 @@ GNUNET_CONTAINER_multihashmap_get_multiple (const struct | |||
839 | 839 | ||
840 | 840 | ||
841 | /** | 841 | /** |
842 | * @ingroup hashmap | ||
843 | * Call @a it on a random value from the map, or not at all | ||
844 | * if the map is empty. | ||
845 | * | ||
846 | * @param map the map | ||
847 | * @param it function to call on a random entry | ||
848 | * @param it_cls extra argument to @a it | ||
849 | * @return the number of key value pairs processed, zero or one. | ||
850 | */ | ||
851 | unsigned int | ||
852 | GNUNET_CONTAINER_multihashmap_get_random (const struct GNUNET_CONTAINER_MultiHashMap *map, | ||
853 | GNUNET_CONTAINER_HashMapIterator it, | ||
854 | void *it_cls) | ||
855 | { | ||
856 | unsigned int off; | ||
857 | unsigned int idx; | ||
858 | union MapEntry me; | ||
859 | |||
860 | if (0 == map->size) | ||
861 | return 0; | ||
862 | if (NULL == it) | ||
863 | return 1; | ||
864 | off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, | ||
865 | map->size); | ||
866 | for (idx = 0; idx < map->map_length; idx++) | ||
867 | { | ||
868 | me = map->map[idx]; | ||
869 | if (map->use_small_entries) | ||
870 | { | ||
871 | struct SmallMapEntry *sme; | ||
872 | struct SmallMapEntry *nxt; | ||
873 | |||
874 | nxt = me.sme; | ||
875 | while (NULL != (sme = nxt)) | ||
876 | { | ||
877 | nxt = sme->next; | ||
878 | if (0 == off) | ||
879 | { | ||
880 | if (GNUNET_OK != it (it_cls, | ||
881 | sme->key, | ||
882 | sme->value)) | ||
883 | return GNUNET_SYSERR; | ||
884 | return 1; | ||
885 | } | ||
886 | off--; | ||
887 | } | ||
888 | } | ||
889 | else | ||
890 | { | ||
891 | struct BigMapEntry *bme; | ||
892 | struct BigMapEntry *nxt; | ||
893 | |||
894 | nxt = me.bme; | ||
895 | while (NULL != (bme = nxt)) | ||
896 | { | ||
897 | nxt = bme->next; | ||
898 | if (0 == off) | ||
899 | { | ||
900 | if (GNUNET_OK != it (it_cls, | ||
901 | &bme->key, bme->value)) | ||
902 | return GNUNET_SYSERR; | ||
903 | return 1; | ||
904 | } | ||
905 | off--; | ||
906 | } | ||
907 | } | ||
908 | } | ||
909 | GNUNET_break (0); | ||
910 | return GNUNET_SYSERR; | ||
911 | } | ||
912 | |||
913 | |||
914 | /** | ||
842 | * Create an iterator for a multihashmap. | 915 | * Create an iterator for a multihashmap. |
843 | * The iterator can be used to retrieve all the elements in the multihashmap | 916 | * The iterator can be used to retrieve all the elements in the multihashmap |
844 | * one by one, without having to handle all elements at once (in contrast to | 917 | * one by one, without having to handle all elements at once (in contrast to |