2 This file is part of GNUnet.
3 (C) 2004, 2005, 2006, 2007, 2009 Christian Grothoff (and other contributing authors)
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
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 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
21 * @file perf_datastore_api_iterators.c
22 * @brief Profile database plugin directly, focusing on iterators.
23 * @author Christian Grothoff
27 #include "gnunet_util_lib.h"
28 #include "gnunet_protocols.h"
29 #include "plugin_datastore.h"
32 * Target datastore size (in bytes). Realistic sizes are
33 * more like 16 GB (not the default of 16 MB); however,
34 * those take too long to run them in the usual "make check"
35 * sequence. Hence the value used for shipping is tiny.
37 #define MAX_SIZE 1024LL * 1024 * 128
42 * Number of put operations equivalent to 1/10th of MAX_SIZE
44 #define PUT_10 (MAX_SIZE / 32 / 1024 / ITERATIONS)
46 static unsigned long long stored_bytes;
48 static unsigned long long stored_entries;
50 static unsigned long long stored_ops;
52 static struct GNUNET_CONFIGURATION_Handle *cfg;
54 static struct GNUNET_SCHEDULER_Handle *sched;
60 putValue (struct GNUNET_DATASTORE_PluginFunctions * api, int i, int k)
64 static GNUNET_HashCode key;
68 /* most content is 32k */
71 if (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 16) == 0) /* but some of it is less! */
72 size = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 32 * 1024);
73 size = size - (size & 7); /* always multiple of 8 */
75 /* generate random key */
76 key.bits[0] = (unsigned int) GNUNET_TIME_absolute_get ().value;
77 GNUNET_CRYPTO_hash (&key, sizeof (GNUNET_HashCode), &key);
78 memset (value, i, size);
80 memset (value, i - 255, size / 2);
83 if (GNUNET_OK != api->put (api->cls,
88 GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 100),
90 GNUNET_TIME_relative_to_absolute
91 (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,
93 GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 1000))),
96 fprintf (stderr, "E: `%s'", msg);
97 GNUNET_free_non_null (msg);
101 stored_bytes += size;
110 iterateDummy (void *cls,
112 const GNUNET_HashCode * key,
118 struct GNUNET_TIME_Absolute
126 test (struct GNUNET_DATASTORE_PluginFunctions * api)
130 struct GNUNET_TIME_Absolute start;
131 struct GNUNET_TIME_Absolute end;
133 /* FIXME: CPS the loop! */
134 for (i = 0; i < ITERATIONS; i++)
136 /* insert data equivalent to 1/10th of MAX_SIZE */
137 start = GNUNET_TIME_absolute_get ();
138 for (j = 0; j < PUT_10; j++)
140 if (GNUNET_OK != putValue (api, j, i))
143 end = GNUNET_TIME_absolute_get ();
144 printf ("%3u insertion took %20llums\n", i, end.value - start.value);
146 api->iter_low_priority (api->cls, 0, &iterateDummy, api);
147 end = GNUNET_TIME_absolute_get ();
148 printf ("%3u low priority iteration took %20llums\n", i,
149 end.value - start.value);
151 api->iter_ascending_expiration (api->cls, 0, &iterateDummy, api);
152 end = GNUNET_TIME_absolute_get ();
153 printf ("%3u expiration t iteration took %20llums\n", i,
154 end.value - start.value);
156 api->iter_zero_anonymity (api->cls, 0, &iterateDummy, api);
157 end = GNUNET_TIME_absolute_get ();
158 printf ("%3u non anonymou iteration took %20llums\n", i,
159 end.value - start.value);
161 api->iter_migration_order (api->cls, 0, &iterateDummy, api);
162 end = GNUNET_TIME_absolute_get ();
163 printf ("%3u migration or iteration took %20llums\n", i,
164 end.value - start.value);
166 api->iter_all_now (api->cls, 0, &iterateDummy, api);
167 end = GNUNET_TIME_absolute_get ();
168 printf ("%3u all now iteration took %20llums\n", i,
169 end.value - start.value);
171 api->drop (api->cls);
177 * Load the datastore plugin.
179 static struct GNUNET_DATASTORE_PluginFunctions *
182 static struct GNUNET_DATASTORE_PluginEnvironment env;
183 struct GNUNET_DATASTORE_PluginFunctions * ret;
188 GNUNET_CONFIGURATION_get_value_string (cfg,
189 "DATASTORE", "DATABASE", &name))
191 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
192 _("No `%s' specified for `%s' in configuration!\n"),
199 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
200 _("Loading `%s' datastore plugin\n"), name);
201 GNUNET_asprintf (&libname, "libgnunet_plugin_datastore_%s", name);
202 GNUNET_assert (NULL != (ret = GNUNET_PLUGIN_load (libname, &env)));
203 GNUNET_free (libname);
210 * Function called when the service shuts
211 * down. Unloads our datastore plugin.
213 * @param api api to unload
216 unload_plugin (struct GNUNET_DATASTORE_PluginFunctions * api)
222 GNUNET_CONFIGURATION_get_value_string (cfg,
223 "DATASTORE", "DATABASE", &name))
225 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
226 _("No `%s' specified for `%s' in configuration!\n"),
231 GNUNET_asprintf (&libname, "libgnunet_plugin_datastore_%s", name);
232 GNUNET_break (NULL == GNUNET_PLUGIN_unload (libname, api));
233 GNUNET_free (libname);
240 * Last task run during shutdown. Disconnects us from
241 * the transport and core.
244 cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
246 struct GNUNET_DATASTORE_PluginFunctions *api = cls;
255 struct GNUNET_SCHEDULER_Handle *s,
257 const char *cfgfile, struct GNUNET_CONFIGURATION_Handle *c)
259 struct GNUNET_DATASTORE_PluginFunctions *api;
263 api = load_plugin ();
265 GNUNET_SCHEDULER_add_delayed (sched,
267 GNUNET_SCHEDULER_PRIORITY_IDLE,
268 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
269 GNUNET_TIME_UNIT_FOREVER_REL,
270 &cleaning_task, api);
277 char *const argv[] = { "perf-datastore-api-iterators",
279 "test_datastore_api_data.conf",
285 struct GNUNET_GETOPT_CommandLineOption options[] = {
286 GNUNET_GETOPT_OPTION_END
288 GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
289 argv, "perf-datastore-api-iterators", "nohelp",
290 options, &run, NULL);
292 fprintf (stderr, "Missed some testcases: %u\n", ok);
298 main (int argc, char *argv[])
302 GNUNET_log_setup ("perf-datastore-api-iterators",
315 /* end of perf_datastore_api_iterators.c */