115112faf7e08d0a61ee7ffc8368085914141391
[oweals/gnunet.git] / src / datastore / perf_datastore_api_iterators.c
1 /*
2      This file is part of GNUnet.
3      (C) 2004, 2005, 2006, 2007 Christian Grothoff (and other contributing authors)
4
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.
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      General Public License for more details.
14
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.
19 */
20 /*
21  * @file applications/sqstore_sqlite/sqlitetest3.c
22  * @brief Profile sqstore iterators.
23  * @author Christian Grothoff
24  */
25
26 #include "platform.h"
27 #include "gnunet_util.h"
28 #include "gnunet_protocols.h"
29 #include "gnunet_sqstore_service.h"
30 #include "core.h"
31
32 /**
33  * Target datastore size (in bytes).  Realistic sizes are
34  * more like 16 GB (not the default of 16 MB); however,
35  * those take too long to run them in the usual "make check"
36  * sequence.  Hence the value used for shipping is tiny.
37  */
38 #define MAX_SIZE 1024LL * 1024 * 128
39
40 #define ITERATIONS 10
41
42 /**
43  * Number of put operations equivalent to 1/10th of MAX_SIZE
44  */
45 #define PUT_10 (MAX_SIZE / 32 / 1024 / ITERATIONS)
46
47 static unsigned long long stored_bytes;
48
49 static unsigned long long stored_entries;
50
51 static unsigned long long stored_ops;
52
53 static GNUNET_CronTime start_time;
54
55 static int
56 putValue (GNUNET_SQstore_ServiceAPI * api, int i, int k)
57 {
58   GNUNET_DatastoreValue *value;
59   size_t size;
60   static GNUNET_HashCode key;
61   static int ic;
62
63   /* most content is 32k */
64   size = sizeof (GNUNET_DatastoreValue) + 32 * 1024;
65
66   if (GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, 16) == 0)  /* but some of it is less! */
67     size =
68       sizeof (GNUNET_DatastoreValue) +
69       GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, 32 * 1024);
70   size = size - (size & 7);     /* always multiple of 8 */
71
72   /* generate random key */
73   key.bits[0] = (unsigned int) GNUNET_get_time ();
74   GNUNET_hash (&key, sizeof (GNUNET_HashCode), &key);
75   value = GNUNET_malloc (size);
76   value->size = htonl (size);
77   value->type = htonl (i);
78   value->priority =
79     htonl (GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, 100));
80   value->anonymity_level = htonl (i);
81   value->expiration_time =
82     GNUNET_htonll (GNUNET_get_time () + 60 * GNUNET_CRON_HOURS +
83                    GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, 1000));
84   memset (&value[1], i, size - sizeof (GNUNET_DatastoreValue));
85   if (i > 255)
86     memset (&value[1], i - 255, (size - sizeof (GNUNET_DatastoreValue)) / 2);
87   ((char *) &value[1])[0] = k;
88   if (GNUNET_OK != api->put (&key, value))
89     {
90       GNUNET_free (value);
91       fprintf (stderr, "E");
92       return GNUNET_SYSERR;
93     }
94   ic++;
95   stored_bytes += ntohl (value->size);
96   stored_ops++;
97   stored_entries++;
98   GNUNET_free (value);
99   return GNUNET_OK;
100 }
101
102 static int
103 iterateDummy (const GNUNET_HashCode * key, const GNUNET_DatastoreValue * val,
104               void *cls, unsigned long long uid)
105 {
106   if (GNUNET_shutdown_test () == GNUNET_YES)
107     return GNUNET_SYSERR;
108   return GNUNET_OK;
109 }
110
111 static int
112 test (GNUNET_SQstore_ServiceAPI * api)
113 {
114   int i;
115   int j;
116   int ret;
117   GNUNET_CronTime start;
118   GNUNET_CronTime end;
119
120   for (i = 0; i < ITERATIONS; i++)
121     {
122       /* insert data equivalent to 1/10th of MAX_SIZE */
123       start = GNUNET_get_time ();
124       for (j = 0; j < PUT_10; j++)
125         {
126           if (GNUNET_OK != putValue (api, j, i))
127             break;
128           if (GNUNET_shutdown_test () == GNUNET_YES)
129             break;
130         }
131       end = GNUNET_get_time ();
132       printf ("%3u insertion              took %20llums\n", i, end - start);
133       if (GNUNET_shutdown_test () == GNUNET_YES)
134         break;
135       start = GNUNET_get_time ();
136       ret = api->iterateLowPriority (0, &iterateDummy, api);
137       end = GNUNET_get_time ();
138       printf ("%3u low priority iteration took %20llums (%d)\n", i,
139               end - start, ret);
140       if (GNUNET_shutdown_test () == GNUNET_YES)
141         break;
142       start = GNUNET_get_time ();
143       ret = api->iterateExpirationTime (0, &iterateDummy, api);
144       end = GNUNET_get_time ();
145       printf ("%3u expiration t iteration took %20llums (%d)\n", i,
146               end - start, ret);
147       if (GNUNET_shutdown_test () == GNUNET_YES)
148         break;
149       start = GNUNET_get_time ();
150       ret = api->iterateNonAnonymous (0, &iterateDummy, api);
151       end = GNUNET_get_time ();
152       printf ("%3u non anonymou iteration took %20llums (%d)\n", i,
153               end - start, ret);
154       if (GNUNET_shutdown_test () == GNUNET_YES)
155         break;
156       start = GNUNET_get_time ();
157       ret = api->iterateMigrationOrder (&iterateDummy, api);
158       end = GNUNET_get_time ();
159       printf ("%3u migration or iteration took %20llums (%d)\n", i,
160               end - start, ret);
161       if (GNUNET_shutdown_test () == GNUNET_YES)
162         break;
163       start = GNUNET_get_time ();
164       ret = api->iterateAllNow (&iterateDummy, api);
165       end = GNUNET_get_time ();
166       printf ("%3u all now      iteration took %20llums (%d)\n", i,
167               end - start, ret);
168       if (GNUNET_shutdown_test () == GNUNET_YES)
169         break;
170     }
171   api->drop ();
172   return GNUNET_OK;
173 }
174
175 int
176 main (int argc, char *argv[])
177 {
178   GNUNET_SQstore_ServiceAPI *api;
179   int ok;
180   struct GNUNET_GC_Configuration *cfg;
181   struct GNUNET_CronManager *cron;
182
183   cfg = GNUNET_GC_create ();
184   if (-1 == GNUNET_GC_parse_configuration (cfg, "check.conf"))
185     {
186       GNUNET_GC_free (cfg);
187       return -1;
188     }
189   cron = GNUNET_cron_create (NULL);
190   GNUNET_CORE_init (NULL, cfg, cron, NULL);
191   api = GNUNET_CORE_request_service ("sqstore");
192   if (api != NULL)
193     {
194       start_time = GNUNET_get_time ();
195       ok = test (api);
196       GNUNET_CORE_release_service (api);
197     }
198   else
199     ok = GNUNET_SYSERR;
200   GNUNET_CORE_done ();
201   GNUNET_cron_destroy (cron);
202   GNUNET_GC_free (cfg);
203   if (ok == GNUNET_SYSERR)
204     return 1;
205   return 0;
206 }
207
208 /* end of sqlitetest3.c */