aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJulius Bünger <buenger@mytum.de>2018-10-01 20:05:40 +0200
committerJulius Bünger <buenger@mytum.de>2018-10-01 23:15:31 +0200
commit3823c7a71aa1b16df6c34ef3def45875289a6b3d (patch)
tree14fa9b007663823983fad8194202e8441a4588c0 /src
parentb3aad5bef2e78487251ef7fc766a510f9fc731c9 (diff)
downloadgnunet-3823c7a71aa1b16df6c34ef3def45875289a6b3d.tar.gz
gnunet-3823c7a71aa1b16df6c34ef3def45875289a6b3d.zip
Restructure implementation of view (towards subsampling)
Diffstat (limited to 'src')
-rw-r--r--src/rps/gnunet-service-rps.c81
-rw-r--r--src/rps/gnunet-service-rps_view.c160
-rw-r--r--src/rps/gnunet-service-rps_view.h51
-rw-r--r--src/rps/test_service_rps_view.c141
4 files changed, 244 insertions, 189 deletions
diff --git a/src/rps/gnunet-service-rps.c b/src/rps/gnunet-service-rps.c
index 3d9f9234c..5abbc692f 100644
--- a/src/rps/gnunet-service-rps.c
+++ b/src/rps/gnunet-service-rps.c
@@ -386,6 +386,11 @@ struct SubSampler
386 unsigned int view_size_est_min; 386 unsigned int view_size_est_min;
387 387
388 /** 388 /**
389 * @brief The view.
390 */
391 struct View *view;
392
393 /**
389 * Identifier for the main task that runs periodically. 394 * Identifier for the main task that runs periodically.
390 */ 395 */
391 struct GNUNET_SCHEDULER_Task *do_round_task; 396 struct GNUNET_SCHEDULER_Task *do_round_task;
@@ -2092,8 +2097,8 @@ insert_in_view (const struct GNUNET_PeerIdentity *peer)
2092 } 2097 }
2093 /* Open channel towards peer to keep connection open */ 2098 /* Open channel towards peer to keep connection open */
2094 indicate_sending_intention (peer); 2099 indicate_sending_intention (peer);
2095 ret = View_put (peer); 2100 ret = View_put (mss->view, peer);
2096 GNUNET_STATISTICS_set (stats, "view size", View_size(), GNUNET_NO); 2101 GNUNET_STATISTICS_set (stats, "view size", View_size(mss->view), GNUNET_NO);
2097 return ret; 2102 return ret;
2098} 2103}
2099 2104
@@ -2115,8 +2120,8 @@ send_view (const struct ClientContext *cli_ctx,
2115 2120
2116 if (NULL == view_array) 2121 if (NULL == view_array)
2117 { 2122 {
2118 view_size = View_size (); 2123 view_size = View_size (mss->view);
2119 view_array = View_get_as_array(); 2124 view_array = View_get_as_array(mss->view);
2120 } 2125 }
2121 2126
2122 ev = GNUNET_MQ_msg_extra (out_msg, 2127 ev = GNUNET_MQ_msg_extra (out_msg,
@@ -2172,8 +2177,8 @@ clients_notify_view_update (void)
2172 uint64_t num_peers; 2177 uint64_t num_peers;
2173 const struct GNUNET_PeerIdentity *view_array; 2178 const struct GNUNET_PeerIdentity *view_array;
2174 2179
2175 num_peers = View_size (); 2180 num_peers = View_size (mss->view);
2176 view_array = View_get_as_array(); 2181 view_array = View_get_as_array(mss->view);
2177 /* check size of view is small enough */ 2182 /* check size of view is small enough */
2178 if (GNUNET_MAX_MESSAGE_SIZE < num_peers) 2183 if (GNUNET_MAX_MESSAGE_SIZE < num_peers)
2179 { 2184 {
@@ -2485,7 +2490,7 @@ check_sending_channel_needed (const struct GNUNET_PeerIdentity *peer)
2485 if (GNUNET_YES == check_sending_channel_exists (peer)) 2490 if (GNUNET_YES == check_sending_channel_exists (peer))
2486 { 2491 {
2487 if ( (0 < RPS_sampler_count_id (mss->sampler, peer)) || 2492 if ( (0 < RPS_sampler_count_id (mss->sampler, peer)) ||
2488 (GNUNET_YES == View_contains_peer (peer)) || 2493 (GNUNET_YES == View_contains_peer (mss->view, peer)) ||
2489 (GNUNET_YES == CustomPeerMap_contains_peer (mss->push_map, peer)) || 2494 (GNUNET_YES == CustomPeerMap_contains_peer (mss->push_map, peer)) ||
2490 (GNUNET_YES == CustomPeerMap_contains_peer (mss->pull_map, peer)) || 2495 (GNUNET_YES == CustomPeerMap_contains_peer (mss->pull_map, peer)) ||
2491 (GNUNET_YES == check_peer_flag (peer, Peers_PULL_REPLY_PENDING))) 2496 (GNUNET_YES == check_peer_flag (peer, Peers_PULL_REPLY_PENDING)))
@@ -2506,7 +2511,7 @@ check_sending_channel_needed (const struct GNUNET_PeerIdentity *peer)
2506static void 2511static void
2507remove_peer (const struct GNUNET_PeerIdentity *peer) 2512remove_peer (const struct GNUNET_PeerIdentity *peer)
2508{ 2513{
2509 (void) View_remove_peer (peer); 2514 (void) View_remove_peer (mss->view, peer);
2510 CustomPeerMap_remove_peer (mss->pull_map, peer); 2515 CustomPeerMap_remove_peer (mss->pull_map, peer);
2511 CustomPeerMap_remove_peer (mss->push_map, peer); 2516 CustomPeerMap_remove_peer (mss->push_map, peer);
2512 RPS_sampler_reinitialise_by_value (mss->sampler, peer); 2517 RPS_sampler_reinitialise_by_value (mss->sampler, peer);
@@ -2538,7 +2543,7 @@ clean_peer (const struct GNUNET_PeerIdentity *peer)
2538 } 2543 }
2539 2544
2540 if ( (GNUNET_NO == check_peer_send_intention (peer)) && 2545 if ( (GNUNET_NO == check_peer_send_intention (peer)) &&
2541 (GNUNET_NO == View_contains_peer (peer)) && 2546 (GNUNET_NO == View_contains_peer (mss->view, peer)) &&
2542 (GNUNET_NO == CustomPeerMap_contains_peer (mss->push_map, peer)) && 2547 (GNUNET_NO == CustomPeerMap_contains_peer (mss->push_map, peer)) &&
2543 (GNUNET_NO == CustomPeerMap_contains_peer (mss->push_map, peer)) && 2548 (GNUNET_NO == CustomPeerMap_contains_peer (mss->push_map, peer)) &&
2544 (0 == RPS_sampler_count_id (mss->sampler, peer)) && 2549 (0 == RPS_sampler_count_id (mss->sampler, peer)) &&
@@ -2682,7 +2687,7 @@ new_subsampler (const char *shared_value,
2682 ss->push_map = CustomPeerMap_create (4); 2687 ss->push_map = CustomPeerMap_create (4);
2683 ss->pull_map = CustomPeerMap_create (4); 2688 ss->pull_map = CustomPeerMap_create (4);
2684 ss->view_size_est_min = sampler_size;; 2689 ss->view_size_est_min = sampler_size;;
2685 View_create (ss->view_size_est_min); 2690 ss->view = View_create (ss->view_size_est_min);
2686 GNUNET_STATISTICS_set (stats, 2691 GNUNET_STATISTICS_set (stats,
2687 "view size aim", 2692 "view size aim",
2688 ss->view_size_est_min, 2693 ss->view_size_est_min,
@@ -2748,7 +2753,7 @@ nse_callback (void *cls,
2748 2753
2749 /* If the NSE has changed adapt the lists accordingly */ 2754 /* If the NSE has changed adapt the lists accordingly */
2750 resize_wrapper (mss->sampler, mss->sampler_size_est_need); 2755 resize_wrapper (mss->sampler, mss->sampler_size_est_need);
2751 View_change_len (mss->view_size_est_need); 2756 View_change_len (mss->view, mss->view_size_est_need);
2752} 2757}
2753 2758
2754 2759
@@ -3043,8 +3048,8 @@ handle_peer_pull_request (void *cls,
3043 3048
3044 GNUNET_break_op (check_peer_known (peer)); 3049 GNUNET_break_op (check_peer_known (peer));
3045 GNUNET_CADET_receive_done (channel_ctx->channel); 3050 GNUNET_CADET_receive_done (channel_ctx->channel);
3046 view_array = View_get_as_array (); 3051 view_array = View_get_as_array (mss->view);
3047 send_pull_reply (peer, view_array, View_size ()); 3052 send_pull_reply (peer, view_array, View_size (mss->view));
3048} 3053}
3049 3054
3050 3055
@@ -3579,8 +3584,8 @@ do_round (void *cls)
3579 "Printing view:\n"); 3584 "Printing view:\n");
3580 to_file (mss->file_name_view_log, 3585 to_file (mss->file_name_view_log,
3581 "___ new round ___"); 3586 "___ new round ___");
3582 view_array = View_get_as_array (); 3587 view_array = View_get_as_array (mss->view);
3583 for (i = 0; i < View_size (); i++) 3588 for (i = 0; i < View_size (mss->view); i++)
3584 { 3589 {
3585 LOG (GNUNET_ERROR_TYPE_DEBUG, 3590 LOG (GNUNET_ERROR_TYPE_DEBUG,
3586 "\t%s\n", GNUNET_i2s (&view_array[i])); 3591 "\t%s\n", GNUNET_i2s (&view_array[i]));
@@ -3591,17 +3596,17 @@ do_round (void *cls)
3591 3596
3592 3597
3593 /* Send pushes and pull requests */ 3598 /* Send pushes and pull requests */
3594 if (0 < View_size ()) 3599 if (0 < View_size (mss->view))
3595 { 3600 {
3596 permut = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_STRONG, 3601 permut = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_STRONG,
3597 View_size ()); 3602 View_size (mss->view));
3598 3603
3599 /* Send PUSHes */ 3604 /* Send PUSHes */
3600 a_peers = ceil (alpha * View_size ()); 3605 a_peers = ceil (alpha * View_size (mss->view));
3601 3606
3602 LOG (GNUNET_ERROR_TYPE_DEBUG, 3607 LOG (GNUNET_ERROR_TYPE_DEBUG,
3603 "Going to send pushes to %u (ceil (%f * %u)) peers.\n", 3608 "Going to send pushes to %u (ceil (%f * %u)) peers.\n",
3604 a_peers, alpha, View_size ()); 3609 a_peers, alpha, View_size (mss->view));
3605 for (i = 0; i < a_peers; i++) 3610 for (i = 0; i < a_peers; i++)
3606 { 3611 {
3607 peer = view_array[permut[i]]; 3612 peer = view_array[permut[i]];
@@ -3610,17 +3615,17 @@ do_round (void *cls)
3610 } 3615 }
3611 3616
3612 /* Send PULL requests */ 3617 /* Send PULL requests */
3613 b_peers = ceil (beta * View_size ()); 3618 b_peers = ceil (beta * View_size (mss->view));
3614 first_border = a_peers; 3619 first_border = a_peers;
3615 second_border = a_peers + b_peers; 3620 second_border = a_peers + b_peers;
3616 if (second_border > View_size ()) 3621 if (second_border > View_size (mss->view))
3617 { 3622 {
3618 first_border = View_size () - b_peers; 3623 first_border = View_size (mss->view) - b_peers;
3619 second_border = View_size (); 3624 second_border = View_size (mss->view);
3620 } 3625 }
3621 LOG (GNUNET_ERROR_TYPE_DEBUG, 3626 LOG (GNUNET_ERROR_TYPE_DEBUG,
3622 "Going to send pulls to %u (ceil (%f * %u)) peers.\n", 3627 "Going to send pulls to %u (ceil (%f * %u)) peers.\n",
3623 b_peers, beta, View_size ()); 3628 b_peers, beta, View_size (mss->view));
3624 for (i = first_border; i < second_border; i++) 3629 for (i = first_border; i < second_border; i++)
3625 { 3630 {
3626 peer = view_array[permut[i]]; 3631 peer = view_array[permut[i]];
@@ -3651,13 +3656,15 @@ do_round (void *cls)
3651 3656
3652 peers_to_clean = NULL; 3657 peers_to_clean = NULL;
3653 peers_to_clean_size = 0; 3658 peers_to_clean_size = 0;
3654 GNUNET_array_grow (peers_to_clean, peers_to_clean_size, View_size ()); 3659 GNUNET_array_grow (peers_to_clean,
3660 peers_to_clean_size,
3661 View_size (mss->view));
3655 GNUNET_memcpy (peers_to_clean, 3662 GNUNET_memcpy (peers_to_clean,
3656 view_array, 3663 view_array,
3657 View_size () * sizeof (struct GNUNET_PeerIdentity)); 3664 View_size (mss->view) * sizeof (struct GNUNET_PeerIdentity));
3658 3665
3659 /* Seems like recreating is the easiest way of emptying the peermap */ 3666 /* Seems like recreating is the easiest way of emptying the peermap */
3660 View_clear (); 3667 View_clear (mss->view);
3661 to_file (mss->file_name_view_log, 3668 to_file (mss->file_name_view_log,
3662 "--- emptied ---"); 3669 "--- emptied ---");
3663 3670
@@ -3724,7 +3731,7 @@ do_round (void *cls)
3724 NULL); 3731 NULL);
3725 // TODO change the peer_flags accordingly 3732 // TODO change the peer_flags accordingly
3726 3733
3727 for (i = 0; i < View_size (); i++) 3734 for (i = 0; i < View_size (mss->view); i++)
3728 rem_from_list (&peers_to_clean, &peers_to_clean_size, &view_array[i]); 3735 rem_from_list (&peers_to_clean, &peers_to_clean_size, &view_array[i]);
3729 3736
3730 /* Clean peers that were removed from the view */ 3737 /* Clean peers that were removed from the view */
@@ -3741,10 +3748,10 @@ do_round (void *cls)
3741 } else { 3748 } else {
3742 LOG (GNUNET_ERROR_TYPE_DEBUG, "No update of the view.\n"); 3749 LOG (GNUNET_ERROR_TYPE_DEBUG, "No update of the view.\n");
3743 GNUNET_STATISTICS_update(stats, "# rounds blocked", 1, GNUNET_NO); 3750 GNUNET_STATISTICS_update(stats, "# rounds blocked", 1, GNUNET_NO);
3744 if (CustomPeerMap_size (mss->push_map) > alpha * View_size () && 3751 if (CustomPeerMap_size (mss->push_map) > alpha * View_size (mss->view) &&
3745 !(0 >= CustomPeerMap_size (mss->pull_map))) 3752 !(0 >= CustomPeerMap_size (mss->pull_map)))
3746 GNUNET_STATISTICS_update(stats, "# rounds blocked - too many pushes", 1, GNUNET_NO); 3753 GNUNET_STATISTICS_update(stats, "# rounds blocked - too many pushes", 1, GNUNET_NO);
3747 if (CustomPeerMap_size (mss->push_map) > alpha * View_size () && 3754 if (CustomPeerMap_size (mss->push_map) > alpha * View_size (mss->view) &&
3748 (0 >= CustomPeerMap_size (mss->pull_map))) 3755 (0 >= CustomPeerMap_size (mss->pull_map)))
3749 GNUNET_STATISTICS_update(stats, "# rounds blocked - too many pushes, no pull replies", 1, GNUNET_NO); 3756 GNUNET_STATISTICS_update(stats, "# rounds blocked - too many pushes, no pull replies", 1, GNUNET_NO);
3750 if (0 >= CustomPeerMap_size (mss->push_map) && 3757 if (0 >= CustomPeerMap_size (mss->push_map) &&
@@ -3754,7 +3761,7 @@ do_round (void *cls)
3754 (0 >= CustomPeerMap_size (mss->pull_map))) 3761 (0 >= CustomPeerMap_size (mss->pull_map)))
3755 GNUNET_STATISTICS_update(stats, "# rounds blocked - no pushes, no pull replies", 1, GNUNET_NO); 3762 GNUNET_STATISTICS_update(stats, "# rounds blocked - no pushes, no pull replies", 1, GNUNET_NO);
3756 if (0 >= CustomPeerMap_size (mss->pull_map) && 3763 if (0 >= CustomPeerMap_size (mss->pull_map) &&
3757 CustomPeerMap_size (mss->push_map) > alpha * View_size () && 3764 CustomPeerMap_size (mss->push_map) > alpha * View_size (mss->view) &&
3758 0 >= CustomPeerMap_size (mss->push_map)) 3765 0 >= CustomPeerMap_size (mss->push_map))
3759 GNUNET_STATISTICS_update(stats, "# rounds blocked - no pull replies", 1, GNUNET_NO); 3766 GNUNET_STATISTICS_update(stats, "# rounds blocked - no pull replies", 1, GNUNET_NO);
3760 } 3767 }
@@ -3769,16 +3776,16 @@ do_round (void *cls)
3769 GNUNET_NO); 3776 GNUNET_NO);
3770 GNUNET_STATISTICS_set (stats, 3777 GNUNET_STATISTICS_set (stats,
3771 "# peers in view at end of round", 3778 "# peers in view at end of round",
3772 View_size (), 3779 View_size (mss->view),
3773 GNUNET_NO); 3780 GNUNET_NO);
3774 3781
3775 LOG (GNUNET_ERROR_TYPE_DEBUG, 3782 LOG (GNUNET_ERROR_TYPE_DEBUG,
3776 "Received %u pushes and %u pulls last round (alpha (%.2f) * view_size (%u) = %.2f)\n", 3783 "Received %u pushes and %u pulls last round (alpha (%.2f) * view_size (mss->view%u) = %.2f)\n",
3777 CustomPeerMap_size (mss->push_map), 3784 CustomPeerMap_size (mss->push_map),
3778 CustomPeerMap_size (mss->pull_map), 3785 CustomPeerMap_size (mss->pull_map),
3779 alpha, 3786 alpha,
3780 View_size (), 3787 View_size (mss->view),
3781 alpha * View_size ()); 3788 alpha * View_size (mss->view));
3782 3789
3783 /* Update samplers */ 3790 /* Update samplers */
3784 for (i = 0; i < CustomPeerMap_size (mss->push_map); i++) 3791 for (i = 0; i < CustomPeerMap_size (mss->push_map); i++)
@@ -3808,7 +3815,7 @@ do_round (void *cls)
3808 3815
3809 GNUNET_STATISTICS_set (stats, 3816 GNUNET_STATISTICS_set (stats,
3810 "view size", 3817 "view size",
3811 View_size(), 3818 View_size(mss->view),
3812 GNUNET_NO); 3819 GNUNET_NO);
3813 3820
3814 struct GNUNET_TIME_Relative time_next_round; 3821 struct GNUNET_TIME_Relative time_next_round;
@@ -3943,7 +3950,7 @@ shutdown_task (void *cls)
3943 GNUNET_CADET_close_port (mss->cadet_port); 3950 GNUNET_CADET_close_port (mss->cadet_port);
3944 GNUNET_CADET_disconnect (mss->cadet_handle); 3951 GNUNET_CADET_disconnect (mss->cadet_handle);
3945 mss->cadet_handle = NULL; 3952 mss->cadet_handle = NULL;
3946 View_destroy (); 3953 View_destroy (mss->view);
3947 CustomPeerMap_destroy (mss->push_map); 3954 CustomPeerMap_destroy (mss->push_map);
3948 CustomPeerMap_destroy (mss->pull_map); 3955 CustomPeerMap_destroy (mss->pull_map);
3949 if (NULL != stats) 3956 if (NULL != stats)
diff --git a/src/rps/gnunet-service-rps_view.c b/src/rps/gnunet-service-rps_view.c
index 26a0b22bc..3af858e60 100644
--- a/src/rps/gnunet-service-rps_view.c
+++ b/src/rps/gnunet-service-rps_view.c
@@ -26,192 +26,221 @@
26#include "gnunet-service-rps_view.h" 26#include "gnunet-service-rps_view.h"
27#include <inttypes.h> 27#include <inttypes.h>
28 28
29struct View
30{
31 /**
32 * Array containing the peers
33 */
34 struct GNUNET_PeerIdentity *array;
29 35
30/** 36 /**
31 * Array containing the peers 37 * (Maximum) length of the view
32 */ 38 */
33static struct GNUNET_PeerIdentity *array; 39 uint32_t length;
34
35/**
36 * (Maximum) length of the view
37 */
38static uint32_t length;
39 40
40/** 41 /**
41 * Multipeermap containing the peers 42 * Multipeermap containing the peers
42 */ 43 */
43static struct GNUNET_CONTAINER_MultiPeerMap *mpm; 44 struct GNUNET_CONTAINER_MultiPeerMap *mpm;
45};
44 46
45 47
46/** 48/**
47 * Create an empty view. 49 * Create an empty view.
48 * 50 *
49 * @param len the maximum length for the view 51 * @param len the maximum length for the view
52 * @return The newly created view
50 */ 53 */
51void 54struct View *
52View_create (uint32_t len) 55View_create (uint32_t len)
53{ 56{
54 length = len; 57 struct View *view;
55 array = GNUNET_new_array (len, struct GNUNET_PeerIdentity); 58
56 mpm = GNUNET_CONTAINER_multipeermap_create (len, GNUNET_NO); /* might even be 59 view = GNUNET_new (struct View);
57 * set to _YES */ 60 view->length = len;
61 view->array = GNUNET_new_array (len, struct GNUNET_PeerIdentity);
62 view->mpm =
63 GNUNET_CONTAINER_multipeermap_create (len, GNUNET_NO); /* might even be
64 * set to _YES */
65 return view;
58} 66}
59 67
68
60/** 69/**
61 * Change length of view 70 * Change length of view
62 * 71 *
63 * If size is decreased, peers with higher indices are removed. 72 * If size is decreased, peers with higher indices are removed.
64 * 73 *
74 * @param view The view that is changed
65 * @param len the (maximum) length for the view 75 * @param len the (maximum) length for the view
66 */ 76 */
67void 77void
68View_change_len (uint32_t len) 78View_change_len (struct View *view,
79 uint32_t len)
69{ 80{
70 uint32_t i; 81 uint32_t i;
71 uint32_t *index; 82 uint32_t *index;
72 83
73 if (GNUNET_CONTAINER_multipeermap_size (mpm) < len) 84 if (GNUNET_CONTAINER_multipeermap_size (view->mpm) < len)
74 { /* Simply shrink */ 85 { /* Simply shrink */
75 /* We might simply clear and free the left over space */ 86 /* We might simply clear and free the left over space */
76 GNUNET_array_grow (array, length, len); 87 GNUNET_array_grow (view->array, view->length, len);
77 } 88 }
78 else /* We have to remove elements */ 89 else /* We have to remove elements */
79 { 90 {
80 /* TODO find a way to preserve indices */ 91 /* TODO find a way to preserve indices */
81 for (i = 0; i < len; i++) 92 for (i = 0; i < len; i++)
82 { 93 {
83 index = GNUNET_CONTAINER_multipeermap_get (mpm, &array[i]); 94 index = GNUNET_CONTAINER_multipeermap_get (view->mpm, &view->array[i]);
84 GNUNET_assert (NULL != index); 95 GNUNET_assert (NULL != index);
85 GNUNET_free (index); 96 GNUNET_free (index);
86 } 97 }
87 GNUNET_array_grow (array, length, len); 98 GNUNET_array_grow (view->array, view->length, len);
88 GNUNET_CONTAINER_multipeermap_destroy (mpm); 99 GNUNET_CONTAINER_multipeermap_destroy (view->mpm);
89 mpm = GNUNET_CONTAINER_multipeermap_create (len, GNUNET_NO); 100 view->mpm = GNUNET_CONTAINER_multipeermap_create (len, GNUNET_NO);
90 for (i = 0; i < len; i++) 101 for (i = 0; i < len; i++)
91 { 102 {
92 index = GNUNET_new (uint32_t); 103 index = GNUNET_new (uint32_t);
93 *index = i; 104 *index = i;
94 GNUNET_CONTAINER_multipeermap_put (mpm, &array[i], index, 105 GNUNET_CONTAINER_multipeermap_put (view->mpm, &view->array[i], index,
95 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); 106 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
96 } 107 }
97 } 108 }
98 GNUNET_assert (length == len); 109 GNUNET_assert (view->length == len);
99} 110}
100 111
112
101/** 113/**
102 * Get the view as an array 114 * Get the view as an array
103 * 115 *
116 * @param view The view of which the array representation is of interest
104 * @return the view in array representation 117 * @return the view in array representation
105 */ 118 */
106const struct GNUNET_PeerIdentity * 119const struct GNUNET_PeerIdentity *
107View_get_as_array () 120View_get_as_array (const struct View *view)
108{ 121{
109 return array; 122 return view->array;
110} 123}
111 124
125
112/** 126/**
113 * Get the size of the view 127 * Get the size of the view
114 * 128 *
129 * @param view The view of which the size should be returned
115 * @return current number of actually contained peers 130 * @return current number of actually contained peers
116 */ 131 */
117unsigned int 132unsigned int
118View_size () 133View_size (const struct View *view)
119{ 134{
120 return GNUNET_CONTAINER_multipeermap_size (mpm); 135 return GNUNET_CONTAINER_multipeermap_size (view->mpm);
121} 136}
122 137
138
123/** 139/**
124 * Insert peer into the view 140 * Insert peer into the view
125 * 141 *
142 * @param view The view to put the peer into
126 * @param peer the peer to insert 143 * @param peer the peer to insert
127 * 144 *
128 * @return GNUNET_OK if peer was actually inserted 145 * @return GNUNET_OK if peer was actually inserted
129 * GNUNET_NO if peer was not inserted 146 * GNUNET_NO if peer was not inserted
130 */ 147 */
131int 148int
132View_put (const struct GNUNET_PeerIdentity *peer) 149View_put (struct View *view,
150 const struct GNUNET_PeerIdentity *peer)
133{ 151{
134 uint32_t *index; 152 uint32_t *index;
135 153
136 if ((length <= View_size ()) || /* If array is 'full' */ 154 if ((view->length <= View_size (view)) || /* If array is 'full' */
137 (GNUNET_YES == View_contains_peer (peer))) 155 (GNUNET_YES == View_contains_peer (view, peer)))
138 { 156 {
139 return GNUNET_NO; 157 return GNUNET_NO;
140 } 158 }
141 else 159 else
142 { 160 {
143 index = GNUNET_new (uint32_t); 161 index = GNUNET_new (uint32_t);
144 *index = (uint32_t) View_size (); 162 *index = (uint32_t) View_size (view);
145 array[*index] = *peer; 163 view->array[*index] = *peer;
146 GNUNET_CONTAINER_multipeermap_put (mpm, peer, index, 164 GNUNET_CONTAINER_multipeermap_put (view->mpm, peer, index,
147 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); 165 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
148 return GNUNET_OK; 166 return GNUNET_OK;
149 } 167 }
150} 168}
151 169
170
152/** 171/**
153 * Check whether view contains a peer 172 * Check whether view contains a peer
154 * 173 *
174 * @param view The which is checked for a peer
155 * @param peer the peer to check for 175 * @param peer the peer to check for
156 * 176 *
157 * @return GNUNET_OK if view contains peer 177 * @return GNUNET_OK if view contains peer
158 * GNUNET_NO otherwise 178 * GNUNET_NO otherwise
159 */ 179 */
160int 180int
161View_contains_peer (const struct GNUNET_PeerIdentity *peer) 181View_contains_peer (const struct View *view,
182 const struct GNUNET_PeerIdentity *peer)
162{ 183{
163 return GNUNET_CONTAINER_multipeermap_contains (mpm, peer); 184 return GNUNET_CONTAINER_multipeermap_contains (view->mpm, peer);
164} 185}
165 186
187
166/** 188/**
167 * Remove peer from view 189 * Remove peer from view
168 * 190 *
191 * @param view The view of which to remove the peer
169 * @param peer the peer to remove 192 * @param peer the peer to remove
170 * 193 *
171 * @return GNUNET_OK if view contained peer and removed it successfully 194 * @return GNUNET_OK if view contained peer and removed it successfully
172 * GNUNET_NO if view does not contain peer 195 * GNUNET_NO if view does not contain peer
173 */ 196 */
174int 197int
175View_remove_peer (const struct GNUNET_PeerIdentity *peer) 198View_remove_peer (struct View *view,
199 const struct GNUNET_PeerIdentity *peer)
176{ 200{
177 uint32_t *index; 201 uint32_t *index;
178 uint32_t *swap_index; 202 uint32_t *swap_index;
179 uint32_t last_index; 203 uint32_t last_index;
180 204
181 if (GNUNET_NO == View_contains_peer (peer)) 205 if (GNUNET_NO == View_contains_peer (view, peer))
182 { 206 {
183 return GNUNET_NO; 207 return GNUNET_NO;
184 } 208 }
185 index = GNUNET_CONTAINER_multipeermap_get (mpm, peer); 209 index = GNUNET_CONTAINER_multipeermap_get (view->mpm, peer);
186 GNUNET_assert (NULL != index); 210 GNUNET_assert (NULL != index);
187 last_index = View_size () - 1; 211 last_index = View_size (view) - 1;
188 if (*index < last_index) 212 if (*index < last_index)
189 { /* Fill the 'gap' in the array with the last peer */ 213 { /* Fill the 'gap' in the array with the last peer */
190 array[*index] = array[last_index]; 214 view->array[*index] = view->array[last_index];
191 GNUNET_assert (GNUNET_YES == View_contains_peer (&array[last_index])); 215 GNUNET_assert (GNUNET_YES == View_contains_peer (view,
192 swap_index = GNUNET_CONTAINER_multipeermap_get (mpm, &array[last_index]); 216 &view->array[last_index]));
217 swap_index = GNUNET_CONTAINER_multipeermap_get (view->mpm,
218 &view->array[last_index]);
193 GNUNET_assert (NULL != swap_index); 219 GNUNET_assert (NULL != swap_index);
194 *swap_index = *index; 220 *swap_index = *index;
195 GNUNET_free (index); 221 GNUNET_free (index);
196 } 222 }
197 GNUNET_CONTAINER_multipeermap_remove_all (mpm, peer); 223 GNUNET_CONTAINER_multipeermap_remove_all (view->mpm, peer);
198 return GNUNET_OK; 224 return GNUNET_OK;
199} 225}
200 226
227
201/** 228/**
202 * Get a peer by index 229 * Get a peer by index
203 * 230 *
231 * @param view the view of which to get the peer
204 * @param index the index of the peer to get 232 * @param index the index of the peer to get
205 * 233 *
206 * @return peer to the corresponding index. 234 * @return peer to the corresponding index.
207 * NULL if this index is not known 235 * NULL if this index is not known
208 */ 236 */
209const struct GNUNET_PeerIdentity * 237const struct GNUNET_PeerIdentity *
210View_get_peer_by_index (uint32_t index) 238View_get_peer_by_index (const struct View *view,
239 uint32_t index)
211{ 240{
212 if (index < GNUNET_CONTAINER_multipeermap_size (mpm)) 241 if (index < GNUNET_CONTAINER_multipeermap_size (view->mpm))
213 { 242 {
214 return &array[index]; 243 return &view->array[index];
215 } 244 }
216 else 245 else
217 { 246 {
@@ -219,42 +248,41 @@ View_get_peer_by_index (uint32_t index)
219 } 248 }
220} 249}
221 250
251
222/** 252/**
223 * Clear the custom peer map 253 * Clear the view
224 *
225 * @param c_peer_map the custom peer map to look in
226 * 254 *
227 * @return size of the map 255 * @param view The view to clear
228 */ 256 */
229void 257void
230View_clear () 258View_clear (struct View *view)
231{ 259{
232 for (uint32_t i = 0; 0 < View_size (); i++) 260 for (uint32_t i = 0; 0 < View_size (view); i++)
233 { /* Need to free indices stored at peers */ 261 { /* Need to free indices stored at peers */
234 uint32_t *index; 262 uint32_t *index;
235 263
236 GNUNET_assert (GNUNET_YES == 264 GNUNET_assert (GNUNET_YES ==
237 GNUNET_CONTAINER_multipeermap_contains (mpm, &array[i])); 265 GNUNET_CONTAINER_multipeermap_contains (view->mpm, &view->array[i]));
238 index = GNUNET_CONTAINER_multipeermap_get (mpm, &array[i]); 266 index = GNUNET_CONTAINER_multipeermap_get (view->mpm, &view->array[i]);
239 GNUNET_assert (NULL != index); 267 GNUNET_assert (NULL != index);
240 GNUNET_free (index); 268 GNUNET_free (index);
241 GNUNET_CONTAINER_multipeermap_remove_all (mpm, &array[i]); 269 GNUNET_CONTAINER_multipeermap_remove_all (view->mpm, &view->array[i]);
242 } 270 }
243 GNUNET_assert (0 == View_size ()); 271 GNUNET_assert (0 == View_size (view));
244} 272}
245 273
246 274
247/** 275/**
248 * Destroy peermap. 276 * Destroy view.
249 * 277 *
250 * @param c_peer_map the map to destroy 278 * @param view the view to destroy
251 */ 279 */
252void 280void
253View_destroy () 281View_destroy (struct View *view)
254{ 282{
255 View_clear (); 283 View_clear (view);
256 GNUNET_free (array); 284 GNUNET_free (view->array);
257 GNUNET_CONTAINER_multipeermap_destroy (mpm); 285 GNUNET_CONTAINER_multipeermap_destroy (view->mpm);
258} 286}
259 287
260/* end of gnunet-service-rps_view.c */ 288/* end of gnunet-service-rps_view.c */
diff --git a/src/rps/gnunet-service-rps_view.h b/src/rps/gnunet-service-rps_view.h
index 127b49faf..a9017bab8 100644
--- a/src/rps/gnunet-service-rps_view.h
+++ b/src/rps/gnunet-service-rps_view.h
@@ -24,24 +24,29 @@
24#include "gnunet_util_lib.h" 24#include "gnunet_util_lib.h"
25#include <inttypes.h> 25#include <inttypes.h>
26 26
27struct View;
27 28
28/** 29/**
29 * Create an empty view. 30 * Create an empty view.
30 * 31 *
31 * @param len the maximum length for the view 32 * @param len the maximum length for the view
33 * @return The newly created view
32 */ 34 */
33void 35struct View *
34View_create (unsigned int len); 36View_create (unsigned int len);
35 37
38
36/** 39/**
37 * Change length of view 40 * Change length of view
38 * 41 *
39 * If size is decreased, peers with higher indices are removed. 42 * If size is decreased, peers with higher indices are removed.
40 * 43 *
44 * @param view The view that is changed
41 * @param len the (maximum) length for the view 45 * @param len the (maximum) length for the view
42 */ 46 */
43void 47void
44View_change_len (unsigned int len); 48View_change_len (struct View *view,
49 unsigned int len);
45 50
46/** 51/**
47 * Get the view as an array 52 * Get the view as an array
@@ -49,76 +54,90 @@ View_change_len (unsigned int len);
49 * @return the view in array representation 54 * @return the view in array representation
50 */ 55 */
51const struct GNUNET_PeerIdentity * 56const struct GNUNET_PeerIdentity *
52View_get_as_array (); 57View_get_as_array (const struct View *view);
58
53 59
54/** 60/**
55 * Get the size of the view 61 * Get the size of the view
56 * 62 *
63 * @param view The view of which the size should be returned
57 * @return current number of actually contained peers 64 * @return current number of actually contained peers
58 */ 65 */
59unsigned int 66unsigned int
60View_size (); 67View_size (const struct View *view);
68
61 69
62/** 70/**
63 * Insert peer into the view 71 * Insert peer into the view
64 * 72 *
73 * @param view The view to put the peer into
65 * @param peer the peer to insert 74 * @param peer the peer to insert
66 * 75 *
67 * @return GNUNET_OK if peer was actually inserted 76 * @return GNUNET_OK if peer was actually inserted
68 * GNUNET_NO if peer was not inserted 77 * GNUNET_NO if peer was not inserted
69 */ 78 */
70int 79int
71View_put (const struct GNUNET_PeerIdentity *peer); 80View_put (struct View *view,
81 const struct GNUNET_PeerIdentity *peer);
82
72 83
73/** 84/**
74 * Check whether view contains a peer 85 * Check whether view contains a peer
75 * 86 *
87 * @param view The which is checked for a peer
76 * @param peer the peer to check for 88 * @param peer the peer to check for
77 * 89 *
78 * @return GNUNET_OK if view contains peer 90 * @return GNUNET_OK if view contains peer
79 * GNUNET_NO otherwise 91 * GNUNET_NO otherwise
80 */ 92 */
81int 93int
82View_contains_peer (const struct GNUNET_PeerIdentity *peer); 94View_contains_peer (const struct View *view,
95 const struct GNUNET_PeerIdentity *peer);
96
83 97
84/** 98/**
85 * Remove peer from view 99 * Remove peer from view
86 * 100 *
101 * @param view The view of which to remove the peer
87 * @param peer the peer to remove 102 * @param peer the peer to remove
88 * 103 *
89 * @return GNUNET_OK if view contained peer and removed it successfully 104 * @return GNUNET_OK if view contained peer and removed it successfully
90 * GNUNET_NO if view does not contain peer 105 * GNUNET_NO if view does not contain peer
91 */ 106 */
92int 107int
93View_remove_peer (const struct GNUNET_PeerIdentity *peer); 108View_remove_peer (struct View *view,
109 const struct GNUNET_PeerIdentity *peer);
110
94 111
95/** 112/**
96 * Get a peer by index 113 * Get a peer by index
97 * 114 *
115 * @param view the view of which to get the peer
98 * @param index the index of the peer to get 116 * @param index the index of the peer to get
99 * 117 *
100 * @return peer to the corresponding index. 118 * @return peer to the corresponding index.
101 * NULL if this index is not known 119 * NULL if this index is not known
102 */ 120 */
103const struct GNUNET_PeerIdentity * 121const struct GNUNET_PeerIdentity *
104View_get_peer_by_index (uint32_t index); 122View_get_peer_by_index (const struct View *view,
123 uint32_t index);
124
105 125
106/** 126/**
107 * Clear the custom peer map 127 * Clear the view
108 * 128 *
109 * @param c_peer_map the custom peer map to look in 129 * @param view The view to clear
110 *
111 * @return size of the map
112 */ 130 */
113void 131void
114View_clear (); 132View_clear (struct View *view);
133
115 134
116/** 135/**
117 * Destroy peermap. 136 * Destroy view.
118 * 137 *
119 * @param c_peer_map the map to destroy 138 * @param view the view to destroy
120 */ 139 */
121void 140void
122View_destroy (); 141View_destroy (struct View *view);
123 142
124/* end of gnunet-service-rps_view.h */ 143/* end of gnunet-service-rps_view.h */
diff --git a/src/rps/test_service_rps_view.c b/src/rps/test_service_rps_view.c
index 16cf4b832..7418a16fc 100644
--- a/src/rps/test_service_rps_view.c
+++ b/src/rps/test_service_rps_view.c
@@ -22,114 +22,115 @@
22#include <platform.h> 22#include <platform.h>
23#include "gnunet-service-rps_view.h" 23#include "gnunet-service-rps_view.h"
24 24
25#define ABORT() { fprintf(stderr, "Error at %s:%d\n", __FILE__, __LINE__); View_destroy(); return 1; } 25#define ABORT() { fprintf(stderr, "Error at %s:%d\n", __FILE__, __LINE__); View_destroy(view); return 1; }
26#define CHECK(c) { if (! (c)) ABORT(); } 26#define CHECK(c) { if (! (c)) ABORT(); }
27 27
28 28
29static int 29static int
30check () 30check ()
31{ 31{
32 struct View *view;
32 struct GNUNET_PeerIdentity k1; 33 struct GNUNET_PeerIdentity k1;
33 struct GNUNET_PeerIdentity k2; 34 struct GNUNET_PeerIdentity k2;
34 const struct GNUNET_PeerIdentity *array; 35 const struct GNUNET_PeerIdentity *array;
35 int j; 36 unsigned int j;
36 37
37 View_create (3); 38 view = View_create (3);
38 memset (&k1, 0, sizeof (k1)); 39 memset (&k1, 0, sizeof (k1));
39 memset (&k2, 1, sizeof (k2)); 40 memset (&k2, 1, sizeof (k2));
40 CHECK (GNUNET_NO == View_contains_peer (&k1)); 41 CHECK (GNUNET_NO == View_contains_peer (view, &k1));
41 CHECK (GNUNET_NO == View_contains_peer (&k2)); 42 CHECK (GNUNET_NO == View_contains_peer (view, &k2));
42 CHECK (GNUNET_NO == View_remove_peer (&k1)); 43 CHECK (GNUNET_NO == View_remove_peer (view, &k1));
43 CHECK (GNUNET_NO == View_remove_peer (&k2)); 44 CHECK (GNUNET_NO == View_remove_peer (view, &k2));
44 CHECK (NULL == View_get_peer_by_index (0)); 45 CHECK (NULL == View_get_peer_by_index (view, 0));
45 CHECK (NULL == View_get_peer_by_index (1)); 46 CHECK (NULL == View_get_peer_by_index (view, 1));
46 View_clear (); /* See if assertions trigger */ 47 View_clear (view); /* See if assertions trigger */
47 CHECK (0 == View_size ()); 48 CHECK (0 == View_size (view));
48 49
49 CHECK (GNUNET_OK == View_put (&k1)); 50 CHECK (GNUNET_OK == View_put (view, &k1));
50 CHECK (1 == View_size ()); 51 CHECK (1 == View_size (view));
51 CHECK (GNUNET_NO == View_put (&k1)); 52 CHECK (GNUNET_NO == View_put (view, &k1));
52 CHECK (1 == View_size ()); 53 CHECK (1 == View_size (view));
53 CHECK (GNUNET_YES == View_contains_peer (&k1)); 54 CHECK (GNUNET_YES == View_contains_peer (view, &k1));
54 CHECK (GNUNET_OK == View_remove_peer (&k1)); 55 CHECK (GNUNET_OK == View_remove_peer (view, &k1));
55 CHECK (0 == View_size ()); 56 CHECK (0 == View_size (view));
56 CHECK (GNUNET_NO == View_contains_peer (&k1)); 57 CHECK (GNUNET_NO == View_contains_peer (view, &k1));
57 CHECK (GNUNET_NO == View_contains_peer (&k2)); 58 CHECK (GNUNET_NO == View_contains_peer (view, &k2));
58 59
59 CHECK (GNUNET_OK == View_put (&k1)); 60 CHECK (GNUNET_OK == View_put (view, &k1));
60 CHECK (1 == View_size ()); 61 CHECK (1 == View_size (view));
61 for (j = 0; j < 16; j++) 62 for (j = 0; j < 16; j++)
62 { 63 {
63 CHECK (GNUNET_NO == View_put (&k1)); 64 CHECK (GNUNET_NO == View_put (view, &k1));
64 } 65 }
65 CHECK (1 == View_size ()); 66 CHECK (1 == View_size (view));
66 CHECK (GNUNET_OK == View_put (&k2)); 67 CHECK (GNUNET_OK == View_put (view, &k2));
67 CHECK (2 == View_size ()); 68 CHECK (2 == View_size (view));
68 for (j = 0; j < 16; j++) 69 for (j = 0; j < 16; j++)
69 { 70 {
70 CHECK (GNUNET_NO == View_put (&k2)); 71 CHECK (GNUNET_NO == View_put (view, &k2));
71 } 72 }
72 CHECK (2 == View_size ()); 73 CHECK (2 == View_size (view));
73 74
74 /* iterate */ 75 /* iterate */
75 for (j = 0; j < View_size (); j++) 76 for (j = 0; j < View_size (view); j++)
76 { 77 {
77 CHECK (NULL != View_get_peer_by_index (j)); 78 CHECK (NULL != View_get_peer_by_index (view, j));
78 } 79 }
79 CHECK ((0 == memcmp (View_get_peer_by_index (0), 80 CHECK ((0 == memcmp (View_get_peer_by_index (view, 0),
80 &k1, sizeof (k1)))); 81 &k1, sizeof (k1))));
81 CHECK ((0 == memcmp (View_get_peer_by_index (1), 82 CHECK ((0 == memcmp (View_get_peer_by_index (view, 1),
82 &k2, sizeof (k2)))); 83 &k2, sizeof (k2))));
83 CHECK (GNUNET_OK == View_remove_peer (&k1)); 84 CHECK (GNUNET_OK == View_remove_peer (view, &k1));
84 CHECK (1 == View_size ()); 85 CHECK (1 == View_size (view));
85 CHECK (GNUNET_NO == View_contains_peer (&k1)); 86 CHECK (GNUNET_NO == View_contains_peer (view, &k1));
86 CHECK (GNUNET_YES == View_contains_peer (&k2)); 87 CHECK (GNUNET_YES == View_contains_peer (view, &k2));
87 CHECK (NULL != View_get_peer_by_index (0)); 88 CHECK (NULL != View_get_peer_by_index (view, 0));
88 CHECK (NULL == View_get_peer_by_index (1)); 89 CHECK (NULL == View_get_peer_by_index (view, 1));
89 90
90 View_clear (); 91 View_clear (view);
91 CHECK (0 == View_size ()); 92 CHECK (0 == View_size (view));
92 93
93 CHECK (GNUNET_OK == View_put (&k1)); 94 CHECK (GNUNET_OK == View_put (view, &k1));
94 CHECK (1 == View_size ()); 95 CHECK (1 == View_size (view));
95 CHECK (GNUNET_YES == View_contains_peer (&k1)); 96 CHECK (GNUNET_YES == View_contains_peer (view, &k1));
96 CHECK (GNUNET_OK == View_put (&k2)); 97 CHECK (GNUNET_OK == View_put (view, &k2));
97 CHECK (2 == View_size ()); 98 CHECK (2 == View_size (view));
98 CHECK (GNUNET_YES == View_contains_peer (&k2)); 99 CHECK (GNUNET_YES == View_contains_peer (view, &k2));
99 array = View_get_as_array (); 100 array = View_get_as_array (view);
100 CHECK (0 == memcmp (&array[0], &k1, sizeof (k1))); 101 CHECK (0 == memcmp (&array[0], &k1, sizeof (k1)));
101 CHECK (0 == memcmp (&array[1], &k2, sizeof (k2))); 102 CHECK (0 == memcmp (&array[1], &k2, sizeof (k2)));
102 View_clear (); 103 View_clear (view);
103 CHECK (0 == View_size ()); 104 CHECK (0 == View_size (view));
104 105
105 /*View_change_len () */ 106 /*View_change_len () */
106 CHECK (GNUNET_OK == View_put (&k1)); 107 CHECK (GNUNET_OK == View_put (view, &k1));
107 CHECK (GNUNET_OK == View_put (&k2)); 108 CHECK (GNUNET_OK == View_put (view, &k2));
108 CHECK (2 == View_size ()); 109 CHECK (2 == View_size (view));
109 View_change_len (4); 110 View_change_len (view, 4);
110 CHECK (2 == View_size ()); 111 CHECK (2 == View_size (view));
111 CHECK (GNUNET_YES == View_contains_peer (&k1)); 112 CHECK (GNUNET_YES == View_contains_peer (view, &k1));
112 CHECK (GNUNET_YES == View_contains_peer (&k2)); 113 CHECK (GNUNET_YES == View_contains_peer (view, &k2));
113 array = View_get_as_array (); 114 array = View_get_as_array (view);
114 CHECK (0 == memcmp (&array[0], &k1, sizeof (k1))); 115 CHECK (0 == memcmp (&array[0], &k1, sizeof (k1)));
115 CHECK (0 == memcmp (&array[1], &k2, sizeof (k2))); 116 CHECK (0 == memcmp (&array[1], &k2, sizeof (k2)));
116 View_change_len (1); 117 View_change_len (view, 1);
117 CHECK (1 == View_size ()); 118 CHECK (1 == View_size (view));
118 CHECK (GNUNET_YES == View_contains_peer (&k1)); 119 CHECK (GNUNET_YES == View_contains_peer (view, &k1));
119 CHECK (GNUNET_NO == View_contains_peer (&k2)); 120 CHECK (GNUNET_NO == View_contains_peer (view, &k2));
120 array = View_get_as_array (); 121 array = View_get_as_array (view);
121 CHECK (0 == memcmp (&array[0], &k1, sizeof (k1))); 122 CHECK (0 == memcmp (&array[0], &k1, sizeof (k1)));
122 View_clear (); 123 View_clear (view);
123 CHECK (0 == View_size ()); 124 CHECK (0 == View_size (view));
124 125
125 View_destroy (); 126 View_destroy (view);
126 127
127 return 0; 128 return 0;
128} 129}
129 130
130 131
131int 132int
132main (int argc, char *argv[]) 133main ()
133{ 134{
134 GNUNET_log_setup ("test_service_rps_peers", 135 GNUNET_log_setup ("test_service_rps_peers",
135 "WARNING", 136 "WARNING",