aboutsummaryrefslogtreecommitdiff
path: root/src/set/gnunet-set-profiler.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/set/gnunet-set-profiler.c')
-rw-r--r--src/set/gnunet-set-profiler.c508
1 files changed, 0 insertions, 508 deletions
diff --git a/src/set/gnunet-set-profiler.c b/src/set/gnunet-set-profiler.c
deleted file mode 100644
index 3014861a6..000000000
--- a/src/set/gnunet-set-profiler.c
+++ /dev/null
@@ -1,508 +0,0 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2013 GNUnet e.V.
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 set/gnunet-set-profiler.c
23 * @brief profiling tool for set
24 * @author Florian Dold
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_statistics_service.h"
29#include "gnunet_set_service.h"
30#include "gnunet_testbed_service.h"
31
32
33static int ret;
34
35static unsigned int num_a = 5;
36static unsigned int num_b = 5;
37static unsigned int num_c = 20;
38
39static char *op_str = "union";
40
41const static struct GNUNET_CONFIGURATION_Handle *config;
42
43struct SetInfo
44{
45 char *id;
46 struct GNUNET_SET_Handle *set;
47 struct GNUNET_SET_OperationHandle *oh;
48 struct GNUNET_CONTAINER_MultiHashMap *sent;
49 struct GNUNET_CONTAINER_MultiHashMap *received;
50 int done;
51} info1, info2;
52
53static struct GNUNET_CONTAINER_MultiHashMap *common_sent;
54
55static struct GNUNET_HashCode app_id;
56
57static struct GNUNET_PeerIdentity local_peer;
58
59static struct GNUNET_SET_ListenHandle *set_listener;
60
61static int byzantine;
62static unsigned int force_delta;
63static unsigned int force_full;
64static unsigned int element_size = 32;
65
66/**
67 * Handle to the statistics service.
68 */
69static struct GNUNET_STATISTICS_Handle *statistics;
70
71/**
72 * The profiler will write statistics
73 * for all peers to the file with this name.
74 */
75static char *statistics_filename;
76
77/**
78 * The profiler will write statistics
79 * for all peers to this file.
80 */
81static FILE *statistics_file;
82
83
84static int
85map_remove_iterator (void *cls,
86 const struct GNUNET_HashCode *key,
87 void *value)
88{
89 struct GNUNET_CONTAINER_MultiHashMap *m = cls;
90 int ret;
91
92 GNUNET_assert (NULL != key);
93
94 ret = GNUNET_CONTAINER_multihashmap_remove_all (m, key);
95 if (GNUNET_OK != ret)
96 printf ("spurious element\n");
97 return GNUNET_YES;
98}
99
100
101/**
102 * Callback function to process statistic values.
103 *
104 * @param cls closure
105 * @param subsystem name of subsystem that created the statistic
106 * @param name the name of the datum
107 * @param value the current value
108 * @param is_persistent #GNUNET_YES if the value is persistent, #GNUNET_NO if not
109 * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration
110 */
111static int
112statistics_result (void *cls,
113 const char *subsystem,
114 const char *name,
115 uint64_t value,
116 int is_persistent)
117{
118 if (NULL != statistics_file)
119 {
120 fprintf (statistics_file, "%s\t%s\t%lu\n", subsystem, name, (unsigned
121 long) value);
122 }
123 return GNUNET_OK;
124}
125
126
127static void
128statistics_done (void *cls,
129 int success)
130{
131 GNUNET_assert (GNUNET_YES == success);
132 if (NULL != statistics_file)
133 fclose (statistics_file);
134 GNUNET_SCHEDULER_shutdown ();
135}
136
137
138static void
139check_all_done (void)
140{
141 if ((info1.done == GNUNET_NO) || (info2.done == GNUNET_NO))
142 return;
143
144 GNUNET_CONTAINER_multihashmap_iterate (info1.received, map_remove_iterator,
145 info2.sent);
146 GNUNET_CONTAINER_multihashmap_iterate (info2.received, map_remove_iterator,
147 info1.sent);
148
149 printf ("set a: %d missing elements\n", GNUNET_CONTAINER_multihashmap_size (
150 info1.sent));
151 printf ("set b: %d missing elements\n", GNUNET_CONTAINER_multihashmap_size (
152 info2.sent));
153
154 if (NULL == statistics_filename)
155 {
156 GNUNET_SCHEDULER_shutdown ();
157 return;
158 }
159
160 statistics_file = fopen (statistics_filename, "w");
161 GNUNET_STATISTICS_get (statistics, NULL, NULL,
162 &statistics_done,
163 &statistics_result, NULL);
164}
165
166
167static void
168set_result_cb (void *cls,
169 const struct GNUNET_SET_Element *element,
170 uint64_t current_size,
171 enum GNUNET_SET_Status status)
172{
173 struct SetInfo *info = cls;
174 struct GNUNET_HashCode hash;
175
176 GNUNET_assert (GNUNET_NO == info->done);
177 switch (status)
178 {
179 case GNUNET_SET_STATUS_DONE:
180 case GNUNET_SET_STATUS_HALF_DONE:
181 info->done = GNUNET_YES;
182 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "set %s done\n", info->id);
183 check_all_done ();
184 info->oh = NULL;
185 return;
186
187 case GNUNET_SET_STATUS_FAILURE:
188 info->oh = NULL;
189 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "failure\n");
190 GNUNET_SCHEDULER_shutdown ();
191 return;
192
193 case GNUNET_SET_STATUS_ADD_LOCAL:
194 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "set %s: local element\n", info->id);
195 break;
196
197 case GNUNET_SET_STATUS_ADD_REMOTE:
198 GNUNET_CRYPTO_hash (element->data, element->size, &hash);
199 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "set %s: remote element %s\n", info->id,
200 GNUNET_h2s (&hash));
201 // XXX: record and check
202 return;
203
204 default:
205 GNUNET_assert (0);
206 }
207
208 if (element->size != element_size)
209 {
210 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
211 "wrong element size: %u, expected %u\n",
212 element->size,
213 (unsigned int) sizeof(struct GNUNET_HashCode));
214 GNUNET_assert (0);
215 }
216
217 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "set %s: got element (%s)\n",
218 info->id, GNUNET_h2s (element->data));
219 GNUNET_assert (NULL != element->data);
220 struct GNUNET_HashCode data_hash;
221 GNUNET_CRYPTO_hash (element->data, element_size, &data_hash);
222 GNUNET_CONTAINER_multihashmap_put (info->received,
223 &data_hash, NULL,
224 GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE);
225}
226
227
228static void
229set_listen_cb (void *cls,
230 const struct GNUNET_PeerIdentity *other_peer,
231 const struct GNUNET_MessageHeader *context_msg,
232 struct GNUNET_SET_Request *request)
233{
234 /* max. 2 options plus terminator */
235 struct GNUNET_SET_Option opts[3] = { { 0 } };
236 unsigned int n_opts = 0;
237
238 if (NULL == request)
239 {
240 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
241 "listener failed\n");
242 return;
243 }
244 GNUNET_assert (NULL == info2.oh);
245 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
246 "set listen cb called\n");
247 if (byzantine)
248 {
249 opts[n_opts++] = (struct GNUNET_SET_Option) { .type =
250 GNUNET_SET_OPTION_BYZANTINE };
251 }
252 GNUNET_assert (! (force_full && force_delta));
253 if (force_full)
254 {
255 opts[n_opts++] = (struct GNUNET_SET_Option) { .type =
256 GNUNET_SET_OPTION_FORCE_FULL };
257 }
258 if (force_delta)
259 {
260 opts[n_opts++] = (struct GNUNET_SET_Option) { .type =
261 GNUNET_SET_OPTION_FORCE_DELTA };
262 }
263
264 opts[n_opts].type = 0;
265 info2.oh = GNUNET_SET_accept (request, GNUNET_SET_RESULT_SYMMETRIC,
266 opts,
267 set_result_cb, &info2);
268 GNUNET_SET_commit (info2.oh, info2.set);
269}
270
271
272static int
273set_insert_iterator (void *cls,
274 const struct GNUNET_HashCode *key,
275 void *value)
276{
277 struct GNUNET_SET_Handle *set = cls;
278 struct GNUNET_SET_Element el;
279
280 el.element_type = 0;
281 el.data = value;
282 el.size = element_size;
283 GNUNET_SET_add_element (set, &el, NULL, NULL);
284 return GNUNET_YES;
285}
286
287
288static void
289handle_shutdown (void *cls)
290{
291 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
292 "Shutting down set profiler\n");
293 if (NULL != set_listener)
294 {
295 GNUNET_SET_listen_cancel (set_listener);
296 set_listener = NULL;
297 }
298 if (NULL != info1.oh)
299 {
300 GNUNET_SET_operation_cancel (info1.oh);
301 info1.oh = NULL;
302 }
303 if (NULL != info2.oh)
304 {
305 GNUNET_SET_operation_cancel (info2.oh);
306 info2.oh = NULL;
307 }
308 if (NULL != info1.set)
309 {
310 GNUNET_SET_destroy (info1.set);
311 info1.set = NULL;
312 }
313 if (NULL != info2.set)
314 {
315 GNUNET_SET_destroy (info2.set);
316 info2.set = NULL;
317 }
318 GNUNET_STATISTICS_destroy (statistics, GNUNET_NO);
319}
320
321
322static void
323run (void *cls,
324 const struct GNUNET_CONFIGURATION_Handle *cfg,
325 struct GNUNET_TESTING_Peer *peer)
326{
327 unsigned int i;
328 struct GNUNET_HashCode hash;
329 /* max. 2 options plus terminator */
330 struct GNUNET_SET_Option opts[3] = { { 0 } };
331 unsigned int n_opts = 0;
332
333 config = cfg;
334
335 GNUNET_assert (element_size > 0);
336
337 if (GNUNET_OK != GNUNET_CRYPTO_get_peer_identity (cfg, &local_peer))
338 {
339 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "could not retrieve host identity\n");
340 ret = 0;
341 return;
342 }
343
344 statistics = GNUNET_STATISTICS_create ("set-profiler", cfg);
345
346 GNUNET_SCHEDULER_add_shutdown (&handle_shutdown, NULL);
347
348 info1.id = "a";
349 info2.id = "b";
350
351 info1.sent = GNUNET_CONTAINER_multihashmap_create (num_a + 1, GNUNET_NO);
352 info2.sent = GNUNET_CONTAINER_multihashmap_create (num_b + 1, GNUNET_NO);
353 common_sent = GNUNET_CONTAINER_multihashmap_create (num_c + 1, GNUNET_NO);
354
355 info1.received = GNUNET_CONTAINER_multihashmap_create (num_a + 1, GNUNET_NO);
356 info2.received = GNUNET_CONTAINER_multihashmap_create (num_b + 1, GNUNET_NO);
357
358 for (i = 0; i < num_a; i++)
359 {
360 char *data = GNUNET_malloc (element_size);
361 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, data, element_size);
362 GNUNET_CRYPTO_hash (data, element_size, &hash);
363 GNUNET_CONTAINER_multihashmap_put (info1.sent, &hash, data,
364 GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE);
365 }
366
367 for (i = 0; i < num_b; i++)
368 {
369 char *data = GNUNET_malloc (element_size);
370 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, data, element_size);
371 GNUNET_CRYPTO_hash (data, element_size, &hash);
372 GNUNET_CONTAINER_multihashmap_put (info2.sent, &hash, data,
373 GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE);
374 }
375
376 for (i = 0; i < num_c; i++)
377 {
378 char *data = GNUNET_malloc (element_size);
379 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, data, element_size);
380 GNUNET_CRYPTO_hash (data, element_size, &hash);
381 GNUNET_CONTAINER_multihashmap_put (common_sent, &hash, data,
382 GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE);
383 }
384
385 GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_STRONG, &app_id);
386
387 /* FIXME: also implement intersection etc. */
388 info1.set = GNUNET_SET_create (config, GNUNET_SET_OPERATION_UNION);
389 info2.set = GNUNET_SET_create (config, GNUNET_SET_OPERATION_UNION);
390
391 GNUNET_CONTAINER_multihashmap_iterate (info1.sent, set_insert_iterator,
392 info1.set);
393 GNUNET_CONTAINER_multihashmap_iterate (info2.sent, set_insert_iterator,
394 info2.set);
395 GNUNET_CONTAINER_multihashmap_iterate (common_sent, set_insert_iterator,
396 info1.set);
397 GNUNET_CONTAINER_multihashmap_iterate (common_sent, set_insert_iterator,
398 info2.set);
399
400 set_listener = GNUNET_SET_listen (config, GNUNET_SET_OPERATION_UNION,
401 &app_id, set_listen_cb, NULL);
402
403
404 if (byzantine)
405 {
406 opts[n_opts++] = (struct GNUNET_SET_Option) { .type =
407 GNUNET_SET_OPTION_BYZANTINE };
408 }
409 GNUNET_assert (! (force_full && force_delta));
410 if (force_full)
411 {
412 opts[n_opts++] = (struct GNUNET_SET_Option) { .type =
413 GNUNET_SET_OPTION_FORCE_FULL };
414 }
415 if (force_delta)
416 {
417 opts[n_opts++] = (struct GNUNET_SET_Option) { .type =
418 GNUNET_SET_OPTION_FORCE_DELTA };
419 }
420
421 opts[n_opts].type = 0;
422
423 info1.oh = GNUNET_SET_prepare (&local_peer, &app_id, NULL,
424 GNUNET_SET_RESULT_SYMMETRIC,
425 opts,
426 set_result_cb, &info1);
427 GNUNET_SET_commit (info1.oh, info1.set);
428 GNUNET_SET_destroy (info1.set);
429 info1.set = NULL;
430}
431
432
433static void
434pre_run (void *cls, char *const *args, const char *cfgfile,
435 const struct GNUNET_CONFIGURATION_Handle *cfg)
436{
437 if (0 != GNUNET_TESTING_peer_run ("set-profiler",
438 cfgfile,
439 &run, NULL))
440 ret = 2;
441}
442
443
444int
445main (int argc, char **argv)
446{
447 struct GNUNET_GETOPT_CommandLineOption options[] = {
448 GNUNET_GETOPT_option_uint ('A',
449 "num-first",
450 NULL,
451 gettext_noop ("number of values"),
452 &num_a),
453
454 GNUNET_GETOPT_option_uint ('B',
455 "num-second",
456 NULL,
457 gettext_noop ("number of values"),
458 &num_b),
459
460 GNUNET_GETOPT_option_flag ('b',
461 "byzantine",
462 gettext_noop ("use byzantine mode"),
463 &byzantine),
464
465 GNUNET_GETOPT_option_uint ('f',
466 "force-full",
467 NULL,
468 gettext_noop ("force sending full set"),
469 &force_full),
470
471 GNUNET_GETOPT_option_uint ('d',
472 "force-delta",
473 NULL,
474 gettext_noop ("number delta operation"),
475 &force_delta),
476
477 GNUNET_GETOPT_option_uint ('C',
478 "num-common",
479 NULL,
480 gettext_noop ("number of values"),
481 &num_c),
482
483 GNUNET_GETOPT_option_string ('x',
484 "operation",
485 NULL,
486 gettext_noop ("operation to execute"),
487 &op_str),
488
489 GNUNET_GETOPT_option_uint ('w',
490 "element-size",
491 NULL,
492 gettext_noop ("element size"),
493 &element_size),
494
495 GNUNET_GETOPT_option_filename ('s',
496 "statistics",
497 "FILENAME",
498 gettext_noop ("write statistics to file"),
499 &statistics_filename),
500
501 GNUNET_GETOPT_OPTION_END
502 };
503
504 GNUNET_PROGRAM_run2 (argc, argv, "gnunet-set-profiler",
505 "help",
506 options, &pre_run, NULL, GNUNET_YES);
507 return ret;
508}