aboutsummaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-04-30 07:29:31 +0000
committerChristian Grothoff <christian@grothoff.org>2015-04-30 07:29:31 +0000
commita49b0f351926cf4376a58937a94e37426e3ae167 (patch)
treed2d36817e0cc65d0300385934474a29ecfcf353a /src/util
parent0b48745c1c6ec80a8e99bcdb9514e028b8656fe0 (diff)
downloadgnunet-a49b0f351926cf4376a58937a94e37426e3ae167.tar.gz
gnunet-a49b0f351926cf4376a58937a94e37426e3ae167.zip
adding GNUNET_CONTAINER_multipeermap_get_random
Diffstat (limited to 'src/util')
-rw-r--r--src/util/container_multihashmap.c3
-rw-r--r--src/util/container_multipeermap.c78
2 files changed, 78 insertions, 3 deletions
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 */
811unsigned int
812GNUNET_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