GNUnet  0.20.0
gnunet-service-rps_sampler.c
Go to the documentation of this file.
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 
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
29 #include "rps.h"
30 
31 #include "rps-sampler_common.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 
63 typedef void
64 (*SamplerNotifyUpdateCB) (void *cls);
65 
72 {
77 
81  void *cls;
82 
87 
92 };
93 
94 
99 typedef void
100 (*RPS_get_peers_type) (void *cls);
101 
109 static void
110 sampler_get_rand_peer (void *cls);
111 
112 
117 {
123 
127  uint32_t num_peers;
128 
132  uint32_t cur_num_peers;
133 
138 
144 
149 
154 
158  void *cls;
159 };
160 
162 // * Global sampler variable.
163 // */
164 // struct RPS_Sampler *sampler;
165 
166 
170 static size_t min_size;
171 
175 static size_t max_size;
176 
180 // static size_t extra_size;
181 
185 static uint32_t client_get_index;
186 
187 
195 struct RPS_Sampler *
196 RPS_sampler_init (size_t init_size,
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 
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 
227 static void
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 
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,
253  gpc);
254  return;
255  }
256 
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 */
void(* RPS_get_peers_type)(void *cls)
Type of function used to differentiate between modified and not modified Sampler.
void(* SamplerNotifyUpdateCB)(void *cls)
Callback called each time a new peer was put into the sampler.
static void sampler_get_rand_peer(void *cls)
Get one random peer out of the sampled peers.
static uint32_t client_get_index
The size the extended sampler elements currently have.
struct RPS_Sampler * RPS_sampler_init(size_t init_size, struct GNUNET_TIME_Relative max_round_interval)
Initialise a tuple of sampler elements.
static size_t max_size
The maximal size the extended sampler elements should grow to.
static size_t min_size
‍**
sampler implementation
void RPS_sampler_resize(struct RPS_Sampler *sampler, unsigned int new_size)
Grow or shrink the size of the sampler.
sampler element implementation
API to create, modify and access statistics.
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Generate a random unsigned 64-bit value.
@ GNUNET_CRYPTO_QUALITY_STRONG
High-quality operations are desired.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
struct SamplerNotifyUpdateCTX * sampler_notify_on_update(struct RPS_Sampler *sampler, SamplerNotifyUpdateCB notify_cb, void *cls)
Add a callback that will be called when the next peer is inserted into the sampler.
Code common to client and service sampler.
void(* RPS_sampler_n_rand_peers_ready_cb)(const struct GNUNET_PeerIdentity *ids, uint32_t num_peers, void *cls)
Callback that is called from _get_n_rand_peers() when the PeerIDs are ready.
Some utils facilitating the view into the internals for the sampler needed for evaluation.
example IPC messages between RPS API and GNS service
The identity of the host (wraps the signing key of the peer).
Time for relative time used by GNUnet, in microseconds.
Closure for sampler_mod_get_rand_peer() and sampler_get_rand_peer.
struct SamplerNotifyUpdateCTX * notify_ctx
Context to the given callback.
struct GNUNET_PeerIdentity * id
The address of the id to be stored at.
RPS_sampler_rand_peer_ready_cont cont
The callback.
struct RPS_SamplerRequestHandle * req_handle
The RPS_SamplerRequestHandle this single request belongs to.
struct GNUNET_SCHEDULER_Task * get_peer_task
The task for this function.
void * cont_cls
The closure to the callback cont.
uint32_t num_peers
How many times a PeerID was put in this sampler.
struct GNUNET_PeerIdentity peer_id
The PeerID this sampler currently samples.
enum RPS_SamplerEmpty is_empty
Flag that indicates that we are not holding a valid PeerID right now.
Closure to _get_n_rand_peers_ready_cb()
struct RPS_Sampler * sampler
Sampler.
struct RPS_SamplerRequestHandle * prev
RPS_sampler_n_rand_peers_ready_cb callback
Callback to be called when all ids are available.
uint32_t num_peers
Number of peers we are waiting for.
struct GNUNET_PeerIdentity * ids
Pointer to the array holding the ids.
struct GetPeerCls * gpc_head
Head and tail for the DLL to store the tasks for single requests.
struct RPS_SamplerRequestHandle * next
DLL.
void * cls
Closure given to the callback.
uint32_t cur_num_peers
Number of peers we currently have.
Sampler with its own array of SamplerElements.
RPS_get_peers_type get_peers
Stores the function to return peers.
struct RPS_SamplerElement ** sampler_elements
All sampler elements in one array.
struct GNUNET_TIME_Relative max_round_interval
Maximum time a round takes.
unsigned int sampler_size
Number of sampler elements we hold.
struct SamplerNotifyUpdateCTX * prev
Previous element in DLL.
struct SamplerNotifyUpdateCTX * next
Next element in DLL.
SamplerNotifyUpdateCB notify_cb
The Callback to call on updates.
void * cls
The according closure.