diff options
author | Christian Grothoff <christian@grothoff.org> | 2015-04-30 07:29:31 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2015-04-30 07:29:31 +0000 |
commit | a49b0f351926cf4376a58937a94e37426e3ae167 (patch) | |
tree | d2d36817e0cc65d0300385934474a29ecfcf353a /src/util/container_multipeermap.c | |
parent | 0b48745c1c6ec80a8e99bcdb9514e028b8656fe0 (diff) | |
download | gnunet-a49b0f351926cf4376a58937a94e37426e3ae167.tar.gz gnunet-a49b0f351926cf4376a58937a94e37426e3ae167.zip |
adding GNUNET_CONTAINER_multipeermap_get_random
Diffstat (limited to 'src/util/container_multipeermap.c')
-rw-r--r-- | src/util/container_multipeermap.c | 78 |
1 files changed, 76 insertions, 2 deletions
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 |