aboutsummaryrefslogtreecommitdiff
path: root/src/contrib/service/rps/gnunet-service-rps_sampler.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/contrib/service/rps/gnunet-service-rps_sampler.c')
-rw-r--r--src/contrib/service/rps/gnunet-service-rps_sampler.c268
1 files changed, 268 insertions, 0 deletions
diff --git a/src/contrib/service/rps/gnunet-service-rps_sampler.c b/src/contrib/service/rps/gnunet-service-rps_sampler.c
new file mode 100644
index 000000000..598cc887e
--- /dev/null
+++ b/src/contrib/service/rps/gnunet-service-rps_sampler.c
@@ -0,0 +1,268 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C)
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file rps/gnunet-service-rps_sampler.c
23 * @brief sampler implementation
24 * @author Julius Bünger
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_statistics_service.h"
29#include "rps.h"
30
31#include "rps-sampler_common.h"
32#include "gnunet-service-rps_sampler.h"
33#include "gnunet-service-rps_sampler_elem.h"
34
35#include <math.h>
36#include <inttypes.h>
37
38#include "rps-test_util.h"
39
40#define LOG(kind, ...) GNUNET_log_from (kind, "rps-sampler", __VA_ARGS__)
41
42
43// multiple 'clients'?
44
45// TODO check for overflows
46
47// TODO align message structs
48
49// hist_size_init, hist_size_max
50
51/***********************************************************************
52* WARNING: This section needs to be reviewed regarding the use of
53* functions providing (pseudo)randomness!
54***********************************************************************/
55
56// TODO care about invalid input of the caller (size 0 or less...)
57
58/**
59 * @brief Callback called each time a new peer was put into the sampler
60 *
61 * @param cls A possibly given closure
62 */
63typedef void
64(*SamplerNotifyUpdateCB) (void *cls);
65
66/**
67 * @brief Context for a callback. Contains callback and closure.
68 *
69 * Meant to be an entry in an DLL.
70 */
71struct SamplerNotifyUpdateCTX
72{
73 /**
74 * @brief The Callback to call on updates
75 */
76 SamplerNotifyUpdateCB notify_cb;
77
78 /**
79 * @brief The according closure.
80 */
81 void *cls;
82
83 /**
84 * @brief Next element in DLL.
85 */
86 struct SamplerNotifyUpdateCTX *next;
87
88 /**
89 * @brief Previous element in DLL.
90 */
91 struct SamplerNotifyUpdateCTX *prev;
92};
93
94
95/**
96 * Type of function used to differentiate between modified and not modified
97 * Sampler.
98 */
99typedef void
100(*RPS_get_peers_type) (void *cls);
101
102/**
103 * Get one random peer out of the sampled peers.
104 *
105 * We might want to reinitialise this sampler after giving the
106 * corrsponding peer to the client.
107 * Only used internally
108 */
109static void
110sampler_get_rand_peer (void *cls);
111
112
113/**
114 * Closure to _get_n_rand_peers_ready_cb()
115 */
116struct RPS_SamplerRequestHandle
117{
118 /**
119 * DLL
120 */
121 struct RPS_SamplerRequestHandle *next;
122 struct RPS_SamplerRequestHandle *prev;
123
124 /**
125 * Number of peers we are waiting for.
126 */
127 uint32_t num_peers;
128
129 /**
130 * Number of peers we currently have.
131 */
132 uint32_t cur_num_peers;
133
134 /**
135 * Pointer to the array holding the ids.
136 */
137 struct GNUNET_PeerIdentity *ids;
138
139 /**
140 * Head and tail for the DLL to store the tasks for single requests
141 */
142 struct GetPeerCls *gpc_head;
143 struct GetPeerCls *gpc_tail;
144
145 /**
146 * Sampler.
147 */
148 struct RPS_Sampler *sampler;
149
150 /**
151 * Callback to be called when all ids are available.
152 */
153 RPS_sampler_n_rand_peers_ready_cb callback;
154
155 /**
156 * Closure given to the callback
157 */
158 void *cls;
159};
160
161///**
162// * Global sampler variable.
163// */
164// struct RPS_Sampler *sampler;
165
166
167/**
168 * The minimal size for the extended sampler elements.
169 */
170static size_t min_size;
171
172/**
173 * The maximal size the extended sampler elements should grow to.
174 */
175static size_t max_size;
176
177/**
178 * The size the extended sampler elements currently have.
179 */
180// static size_t extra_size;
181
182/**
183 * Inedex to the sampler element that is the next to be returned
184 */
185static uint32_t client_get_index;
186
187
188/**
189 * Initialise a tuple of sampler elements.
190 *
191 * @param init_size the size the sampler is initialised with
192 * @param max_round_interval maximum time a round takes
193 * @return a handle to a sampler that consists of sampler elements.
194 */
195struct RPS_Sampler *
196RPS_sampler_init (size_t init_size,
197 struct GNUNET_TIME_Relative max_round_interval)
198{
199 struct RPS_Sampler *sampler;
200
201 /* Initialise context around extended sampler */
202 min_size = 10; // TODO make input to _samplers_init()
203 max_size = 1000; // TODO make input to _samplers_init()
204
205 sampler = GNUNET_new (struct RPS_Sampler);
206
207 sampler->max_round_interval = max_round_interval;
208 sampler->get_peers = sampler_get_rand_peer;
209 // sampler->sampler_elements = GNUNET_new_array(init_size, struct GNUNET_PeerIdentity);
210 // GNUNET_array_grow (sampler->sampler_elements, sampler->sampler_size, min_size);
211 RPS_sampler_resize (sampler, init_size);
212
213 client_get_index = 0;
214
215 // GNUNET_assert (init_size == sampler->sampler_size);
216 return sampler;
217}
218
219
220/**
221 * Get one random peer out of the sampled peers.
222 *
223 * We might want to reinitialise this sampler after giving the
224 * corrsponding peer to the client.
225 * Only used internally
226 */
227static void
228sampler_get_rand_peer (void *cls)
229{
230 struct GetPeerCls *gpc = cls;
231 uint32_t r_index;
232 struct RPS_Sampler *sampler;
233
234 gpc->get_peer_task = NULL;
235 gpc->notify_ctx = NULL;
236 sampler = gpc->req_handle->sampler;
237
238 /**;
239 * Choose the r_index of the peer we want to return
240 * at random from the interval of the gossip list
241 */
242 r_index = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
243 sampler->sampler_size);
244
245 if (EMPTY == sampler->sampler_elements[r_index]->is_empty)
246 {
247 // LOG (GNUNET_ERROR_TYPE_DEBUG,
248 // "Not returning randomly selected, empty PeerID. - Rescheduling.\n");
249
250 gpc->notify_ctx =
251 sampler_notify_on_update (sampler,
252 &sampler_get_rand_peer,
253 gpc);
254 return;
255 }
256
257 GNUNET_CONTAINER_DLL_remove (gpc->req_handle->gpc_head,
258 gpc->req_handle->gpc_tail,
259 gpc);
260 *gpc->id = sampler->sampler_elements[r_index]->peer_id;
261 gpc->cont (gpc->cont_cls, gpc->id, 0,
262 sampler->sampler_elements[r_index]->num_peers);
263
264 GNUNET_free (gpc);
265}
266
267
268/* end of gnunet-service-rps.c */