diff options
Diffstat (limited to 'src/datacache/datacache.c')
-rw-r--r-- | src/datacache/datacache.c | 143 |
1 files changed, 103 insertions, 40 deletions
diff --git a/src/datacache/datacache.c b/src/datacache/datacache.c index 0b2cb6514..426841bc8 100644 --- a/src/datacache/datacache.c +++ b/src/datacache/datacache.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010 Christian Grothoff (and other contributing authors) | 3 | Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2015 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 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 | 6 | it under the terms of the GNU General Public License as published |
@@ -17,7 +17,6 @@ | |||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
18 | Boston, MA 02111-1307, USA. | 18 | Boston, MA 02111-1307, USA. |
19 | */ | 19 | */ |
20 | |||
21 | /** | 20 | /** |
22 | * @file datacache/datacache.c | 21 | * @file datacache/datacache.c |
23 | * @brief datacache API implementation | 22 | * @brief datacache API implementation |
@@ -103,18 +102,26 @@ struct GNUNET_DATACACHE_Handle | |||
103 | * @param size number of bytes that were made available | 102 | * @param size number of bytes that were made available |
104 | */ | 103 | */ |
105 | static void | 104 | static void |
106 | env_delete_notify (void *cls, const struct GNUNET_HashCode * key, size_t size) | 105 | env_delete_notify (void *cls, |
106 | const struct GNUNET_HashCode *key, | ||
107 | size_t size) | ||
107 | { | 108 | { |
108 | struct GNUNET_DATACACHE_Handle *h = cls; | 109 | struct GNUNET_DATACACHE_Handle *h = cls; |
109 | 110 | ||
110 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Content under key `%s' discarded\n", | 111 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
112 | "Content under key `%s' discarded\n", | ||
111 | GNUNET_h2s (key)); | 113 | GNUNET_h2s (key)); |
112 | GNUNET_assert (h->utilization >= size); | 114 | GNUNET_assert (h->utilization >= size); |
113 | h->utilization -= size; | 115 | h->utilization -= size; |
114 | GNUNET_CONTAINER_bloomfilter_remove (h->filter, key); | 116 | GNUNET_CONTAINER_bloomfilter_remove (h->filter, |
115 | GNUNET_STATISTICS_update (h->stats, gettext_noop ("# bytes stored"), - (long long) size, | 117 | key); |
118 | GNUNET_STATISTICS_update (h->stats, | ||
119 | gettext_noop ("# bytes stored"), | ||
120 | - (long long) size, | ||
116 | GNUNET_NO); | 121 | GNUNET_NO); |
117 | GNUNET_STATISTICS_update (h->stats, gettext_noop ("# items stored"), -1, | 122 | GNUNET_STATISTICS_update (h->stats, |
123 | gettext_noop ("# items stored"), | ||
124 | -1, | ||
118 | GNUNET_NO); | 125 | GNUNET_NO); |
119 | } | 126 | } |
120 | 127 | ||
@@ -137,18 +144,25 @@ GNUNET_DATACACHE_create (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
137 | char *name; | 144 | char *name; |
138 | 145 | ||
139 | if (GNUNET_OK != | 146 | if (GNUNET_OK != |
140 | GNUNET_CONFIGURATION_get_value_size (cfg, section, "QUOTA", "a)) | 147 | GNUNET_CONFIGURATION_get_value_size (cfg, |
148 | section, | ||
149 | "QUOTA", | ||
150 | "a)) | ||
141 | { | 151 | { |
142 | LOG (GNUNET_ERROR_TYPE_ERROR, | 152 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, |
143 | _("No `%s' specified for `%s' in configuration!\n"), "QUOTA", section); | 153 | section, |
154 | "QUOTA"); | ||
144 | return NULL; | 155 | return NULL; |
145 | } | 156 | } |
146 | if (GNUNET_OK != | 157 | if (GNUNET_OK != |
147 | GNUNET_CONFIGURATION_get_value_string (cfg, section, "DATABASE", &name)) | 158 | GNUNET_CONFIGURATION_get_value_string (cfg, |
159 | section, | ||
160 | "DATABASE", | ||
161 | &name)) | ||
148 | { | 162 | { |
149 | LOG (GNUNET_ERROR_TYPE_ERROR, | 163 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, |
150 | _("No `%s' specified for `%s' in configuration!\n"), "DATABASE", | 164 | section, |
151 | section); | 165 | "DATABASE"); |
152 | return NULL; | 166 | return NULL; |
153 | } | 167 | } |
154 | bf_size = quota / 32; /* 8 bit per entry, 1 bit per 32 kb in DB */ | 168 | bf_size = quota / 32; /* 8 bit per entry, 1 bit per 32 kb in DB */ |
@@ -165,12 +179,15 @@ GNUNET_DATACACHE_create (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
165 | } | 179 | } |
166 | if (NULL != ret->bloom_name) | 180 | if (NULL != ret->bloom_name) |
167 | { | 181 | { |
168 | ret->filter = GNUNET_CONTAINER_bloomfilter_load (ret->bloom_name, quota / 1024, /* 8 bit per entry in DB, expect 1k entries */ | 182 | ret->filter = GNUNET_CONTAINER_bloomfilter_load (ret->bloom_name, |
183 | quota / 1024, /* 8 bit per entry in DB, expect 1k entries */ | ||
169 | 5); | 184 | 5); |
170 | } | 185 | } |
171 | if (NULL == ret->filter) | 186 | if (NULL == ret->filter) |
172 | { | 187 | { |
173 | ret->filter = GNUNET_CONTAINER_bloomfilter_init (NULL, bf_size, 5); /* approx. 3% false positives at max use */ | 188 | ret->filter = GNUNET_CONTAINER_bloomfilter_init (NULL, |
189 | bf_size, | ||
190 | 5); /* approx. 3% false positives at max use */ | ||
174 | } | 191 | } |
175 | } | 192 | } |
176 | ret->stats = GNUNET_STATISTICS_create ("datacache", cfg); | 193 | ret->stats = GNUNET_STATISTICS_create ("datacache", cfg); |
@@ -181,15 +198,20 @@ GNUNET_DATACACHE_create (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
181 | ret->env.cls = ret; | 198 | ret->env.cls = ret; |
182 | ret->env.delete_notify = &env_delete_notify; | 199 | ret->env.delete_notify = &env_delete_notify; |
183 | ret->env.quota = quota; | 200 | ret->env.quota = quota; |
184 | LOG (GNUNET_ERROR_TYPE_INFO, _("Loading `%s' datacache plugin\n"), name); | 201 | LOG (GNUNET_ERROR_TYPE_INFO, |
185 | GNUNET_asprintf (&libname, "libgnunet_plugin_datacache_%s", name); | 202 | _("Loading `%s' datacache plugin\n"), |
203 | name); | ||
204 | GNUNET_asprintf (&libname, | ||
205 | "libgnunet_plugin_datacache_%s", | ||
206 | name); | ||
186 | ret->short_name = name; | 207 | ret->short_name = name; |
187 | ret->lib_name = libname; | 208 | ret->lib_name = libname; |
188 | ret->api = GNUNET_PLUGIN_load (libname, &ret->env); | 209 | ret->api = GNUNET_PLUGIN_load (libname, &ret->env); |
189 | if (ret->api == NULL) | 210 | if (ret->api == NULL) |
190 | { | 211 | { |
191 | LOG (GNUNET_ERROR_TYPE_ERROR, | 212 | LOG (GNUNET_ERROR_TYPE_ERROR, |
192 | _("Failed to load datacache plugin for `%s'\n"), name); | 213 | _("Failed to load datacache plugin for `%s'\n"), |
214 | name); | ||
193 | GNUNET_DATACACHE_destroy (ret); | 215 | GNUNET_DATACACHE_destroy (ret); |
194 | return NULL; | 216 | return NULL; |
195 | } | 217 | } |
@@ -207,16 +229,18 @@ GNUNET_DATACACHE_destroy (struct GNUNET_DATACACHE_Handle *h) | |||
207 | { | 229 | { |
208 | if (NULL != h->filter) | 230 | if (NULL != h->filter) |
209 | GNUNET_CONTAINER_bloomfilter_free (h->filter); | 231 | GNUNET_CONTAINER_bloomfilter_free (h->filter); |
210 | if (h->api != NULL) | 232 | if (NULL != h->api) |
211 | GNUNET_break (NULL == GNUNET_PLUGIN_unload (h->lib_name, h->api)); | 233 | GNUNET_break (NULL == GNUNET_PLUGIN_unload (h->lib_name, h->api)); |
212 | GNUNET_free (h->lib_name); | 234 | GNUNET_free (h->lib_name); |
213 | GNUNET_free (h->short_name); | 235 | GNUNET_free (h->short_name); |
214 | GNUNET_free (h->section); | 236 | GNUNET_free (h->section); |
215 | if (h->bloom_name != NULL) | 237 | if (NULL != h->bloom_name) |
216 | { | 238 | { |
217 | if (0 != UNLINK (h->bloom_name)) | 239 | if (0 != UNLINK (h->bloom_name)) |
218 | GNUNET_log_from_strerror_file (GNUNET_ERROR_TYPE_WARNING, "datacache", | 240 | GNUNET_log_from_strerror_file (GNUNET_ERROR_TYPE_WARNING, |
219 | "unlink", h->bloom_name); | 241 | "datacache", |
242 | "unlink", | ||
243 | h->bloom_name); | ||
220 | GNUNET_free (h->bloom_name); | 244 | GNUNET_free (h->bloom_name); |
221 | } | 245 | } |
222 | GNUNET_STATISTICS_destroy (h->stats, GNUNET_NO); | 246 | GNUNET_STATISTICS_destroy (h->stats, GNUNET_NO); |
@@ -229,7 +253,7 @@ GNUNET_DATACACHE_destroy (struct GNUNET_DATACACHE_Handle *h) | |||
229 | * | 253 | * |
230 | * @param h handle to the datacache | 254 | * @param h handle to the datacache |
231 | * @param key key to store data under | 255 | * @param key key to store data under |
232 | * @param size number of bytes in data | 256 | * @param data_size number of bytes in @a data |
233 | * @param data data to store | 257 | * @param data data to store |
234 | * @param type type of the value | 258 | * @param type type of the value |
235 | * @param discard_time when to discard the value in any case | 259 | * @param discard_time when to discard the value in any case |
@@ -239,8 +263,10 @@ GNUNET_DATACACHE_destroy (struct GNUNET_DATACACHE_Handle *h) | |||
239 | */ | 263 | */ |
240 | int | 264 | int |
241 | GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h, | 265 | GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h, |
242 | const struct GNUNET_HashCode * key, size_t size, | 266 | const struct GNUNET_HashCode *key, |
243 | const char *data, enum GNUNET_BLOCK_Type type, | 267 | size_t data_size, |
268 | const char *data, | ||
269 | enum GNUNET_BLOCK_Type type, | ||
244 | struct GNUNET_TIME_Absolute discard_time, | 270 | struct GNUNET_TIME_Absolute discard_time, |
245 | unsigned int path_info_len, | 271 | unsigned int path_info_len, |
246 | const struct GNUNET_PeerIdentity *path_info) | 272 | const struct GNUNET_PeerIdentity *path_info) |
@@ -248,7 +274,7 @@ GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h, | |||
248 | ssize_t used; | 274 | ssize_t used; |
249 | 275 | ||
250 | used = h->api->put (h->api->cls, key, | 276 | used = h->api->put (h->api->cls, key, |
251 | size, data, | 277 | data_size, data, |
252 | type, discard_time, | 278 | type, discard_time, |
253 | path_info_len, path_info); | 279 | path_info_len, path_info); |
254 | if (-1 == used) | 280 | if (-1 == used) |
@@ -261,11 +287,16 @@ GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h, | |||
261 | /* duplicate */ | 287 | /* duplicate */ |
262 | return GNUNET_NO; | 288 | return GNUNET_NO; |
263 | } | 289 | } |
264 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Stored data under key `%s' in cache\n", | 290 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
291 | "Stored data under key `%s' in cache\n", | ||
265 | GNUNET_h2s (key)); | 292 | GNUNET_h2s (key)); |
266 | GNUNET_STATISTICS_update (h->stats, gettext_noop ("# bytes stored"), size, | 293 | GNUNET_STATISTICS_update (h->stats, |
294 | gettext_noop ("# bytes stored"), | ||
295 | data_size, | ||
267 | GNUNET_NO); | 296 | GNUNET_NO); |
268 | GNUNET_STATISTICS_update (h->stats, gettext_noop ("# items stored"), 1, | 297 | GNUNET_STATISTICS_update (h->stats, |
298 | gettext_noop ("# items stored"), | ||
299 | 1, | ||
269 | GNUNET_NO); | 300 | GNUNET_NO); |
270 | if (NULL != h->filter) | 301 | if (NULL != h->filter) |
271 | GNUNET_CONTAINER_bloomfilter_add (h->filter, key); | 302 | GNUNET_CONTAINER_bloomfilter_add (h->filter, key); |
@@ -284,32 +315,64 @@ GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h, | |||
284 | * @param key what to look up | 315 | * @param key what to look up |
285 | * @param type entries of which type are relevant? | 316 | * @param type entries of which type are relevant? |
286 | * @param iter maybe NULL (to just count) | 317 | * @param iter maybe NULL (to just count) |
287 | * @param iter_cls closure for iter | 318 | * @param iter_cls closure for @a iter |
288 | * @return the number of results found | 319 | * @return the number of results found |
289 | */ | 320 | */ |
290 | unsigned int | 321 | unsigned int |
291 | GNUNET_DATACACHE_get (struct GNUNET_DATACACHE_Handle *h, | 322 | GNUNET_DATACACHE_get (struct GNUNET_DATACACHE_Handle *h, |
292 | const struct GNUNET_HashCode * key, enum GNUNET_BLOCK_Type type, | 323 | const struct GNUNET_HashCode *key, |
293 | GNUNET_DATACACHE_Iterator iter, void *iter_cls) | 324 | enum GNUNET_BLOCK_Type type, |
325 | GNUNET_DATACACHE_Iterator iter, | ||
326 | void *iter_cls) | ||
294 | { | 327 | { |
295 | GNUNET_STATISTICS_update (h->stats, gettext_noop ("# requests received"), 1, | 328 | GNUNET_STATISTICS_update (h->stats, |
329 | gettext_noop ("# requests received"), | ||
330 | 1, | ||
296 | GNUNET_NO); | 331 | GNUNET_NO); |
297 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing request for key `%s'\n", | 332 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
333 | "Processing request for key `%s'\n", | ||
298 | GNUNET_h2s (key)); | 334 | GNUNET_h2s (key)); |
299 | if ( (NULL != h->filter) && | 335 | if ( (NULL != h->filter) && |
300 | (GNUNET_OK != GNUNET_CONTAINER_bloomfilter_test (h->filter, key)) ) | 336 | (GNUNET_OK != GNUNET_CONTAINER_bloomfilter_test (h->filter, key)) ) |
301 | { | 337 | { |
302 | GNUNET_STATISTICS_update (h->stats, | 338 | GNUNET_STATISTICS_update (h->stats, |
303 | gettext_noop | 339 | gettext_noop ("# requests filtered by bloom filter"), |
304 | ("# requests filtered by bloom filter"), 1, | 340 | 1, |
305 | GNUNET_NO); | 341 | GNUNET_NO); |
306 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Bloomfilter filters request for key `%s'\n", | 342 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
343 | "Bloomfilter filters request for key `%s'\n", | ||
307 | GNUNET_h2s (key)); | 344 | GNUNET_h2s (key)); |
308 | return 0; /* can not be present */ | 345 | return 0; /* can not be present */ |
309 | } | 346 | } |
310 | return h->api->get (h->api->cls, key, type, iter, iter_cls); | 347 | return h->api->get (h->api->cls, |
348 | key, type, | ||
349 | iter, iter_cls); | ||
311 | } | 350 | } |
312 | 351 | ||
313 | 352 | ||
353 | /** | ||
354 | * Obtain a random element from the datacache. | ||
355 | * | ||
356 | * @param h handle to the datacache | ||
357 | * @param iter maybe NULL (to just count) | ||
358 | * @param iter_cls closure for @a iter | ||
359 | * @return the number of results found (zero or 1) | ||
360 | */ | ||
361 | unsigned int | ||
362 | GNUNET_DATACACHE_get_random (struct GNUNET_DATACACHE_Handle *h, | ||
363 | GNUNET_DATACACHE_Iterator iter, | ||
364 | void *iter_cls) | ||
365 | { | ||
366 | GNUNET_STATISTICS_update (h->stats, | ||
367 | gettext_noop ("# requests for random value received"), | ||
368 | 1, | ||
369 | GNUNET_NO); | ||
370 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
371 | "Processing request for random value\n"); | ||
372 | return h->api->get_random (h->api->cls, | ||
373 | iter, | ||
374 | iter_cls); | ||
375 | } | ||
376 | |||
314 | 377 | ||
315 | /* end of datacache_api.c */ | 378 | /* end of datacache.c */ |