aboutsummaryrefslogtreecommitdiff
path: root/src/datacache/datacache.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/datacache/datacache.c')
-rw-r--r--src/datacache/datacache.c333
1 files changed, 167 insertions, 166 deletions
diff --git a/src/datacache/datacache.c b/src/datacache/datacache.c
index 52c755a49..1ae228b86 100644
--- a/src/datacache/datacache.c
+++ b/src/datacache/datacache.c
@@ -29,15 +29,16 @@
29#include "gnunet_datacache_plugin.h" 29#include "gnunet_datacache_plugin.h"
30 30
31 31
32#define LOG(kind, ...) GNUNET_log_from(kind, "datacache", __VA_ARGS__) 32#define LOG(kind, ...) GNUNET_log_from (kind, "datacache", __VA_ARGS__)
33 33
34#define LOG_STRERROR_FILE(kind, op, fn) \ 34#define LOG_STRERROR_FILE(kind, op, fn) \
35 GNUNET_log_from_strerror_file(kind, "datacache", op, fn) 35 GNUNET_log_from_strerror_file (kind, "datacache", op, fn)
36 36
37/** 37/**
38 * Internal state of the datacache library. 38 * Internal state of the datacache library.
39 */ 39 */
40struct GNUNET_DATACACHE_Handle { 40struct GNUNET_DATACACHE_Handle
41{
41 /** 42 /**
42 * Bloomfilter to quickly tell if we don't have the content. 43 * Bloomfilter to quickly tell if we don't have the content.
43 */ 44 */
@@ -100,24 +101,24 @@ struct GNUNET_DATACACHE_Handle {
100 * @param size number of bytes that were made available 101 * @param size number of bytes that were made available
101 */ 102 */
102static void 103static void
103env_delete_notify(void *cls, const struct GNUNET_HashCode *key, size_t size) 104env_delete_notify (void *cls, const struct GNUNET_HashCode *key, size_t size)
104{ 105{
105 struct GNUNET_DATACACHE_Handle *h = cls; 106 struct GNUNET_DATACACHE_Handle *h = cls;
106 107
107 LOG(GNUNET_ERROR_TYPE_DEBUG, 108 LOG (GNUNET_ERROR_TYPE_DEBUG,
108 "Content under key `%s' discarded\n", 109 "Content under key `%s' discarded\n",
109 GNUNET_h2s(key)); 110 GNUNET_h2s (key));
110 GNUNET_assert(h->utilization >= size); 111 GNUNET_assert (h->utilization >= size);
111 h->utilization -= size; 112 h->utilization -= size;
112 GNUNET_CONTAINER_bloomfilter_remove(h->filter, key); 113 GNUNET_CONTAINER_bloomfilter_remove (h->filter, key);
113 GNUNET_STATISTICS_update(h->stats, 114 GNUNET_STATISTICS_update (h->stats,
114 gettext_noop("# bytes stored"), 115 gettext_noop ("# bytes stored"),
115 -(long long)size, 116 -(long long) size,
116 GNUNET_NO); 117 GNUNET_NO);
117 GNUNET_STATISTICS_update(h->stats, 118 GNUNET_STATISTICS_update (h->stats,
118 gettext_noop("# items stored"), 119 gettext_noop ("# items stored"),
119 -1, 120 -1,
120 GNUNET_NO); 121 GNUNET_NO);
121} 122}
122 123
123 124
@@ -129,8 +130,8 @@ env_delete_notify(void *cls, const struct GNUNET_HashCode *key, size_t size)
129 * @return handle to use to access the service 130 * @return handle to use to access the service
130 */ 131 */
131struct GNUNET_DATACACHE_Handle * 132struct GNUNET_DATACACHE_Handle *
132GNUNET_DATACACHE_create(const struct GNUNET_CONFIGURATION_Handle *cfg, 133GNUNET_DATACACHE_create (const struct GNUNET_CONFIGURATION_Handle *cfg,
133 const char *section) 134 const char *section)
134{ 135{
135 unsigned int bf_size; 136 unsigned int bf_size;
136 unsigned long long quota; 137 unsigned long long quota;
@@ -139,65 +140,65 @@ GNUNET_DATACACHE_create(const struct GNUNET_CONFIGURATION_Handle *cfg,
139 char *name; 140 char *name;
140 141
141 if (GNUNET_OK != 142 if (GNUNET_OK !=
142 GNUNET_CONFIGURATION_get_value_size(cfg, section, "QUOTA", &quota)) 143 GNUNET_CONFIGURATION_get_value_size (cfg, section, "QUOTA", &quota))
143 { 144 {
144 GNUNET_log_config_missing(GNUNET_ERROR_TYPE_ERROR, section, "QUOTA"); 145 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, section, "QUOTA");
145 return NULL; 146 return NULL;
146 } 147 }
147 if (GNUNET_OK != 148 if (GNUNET_OK !=
148 GNUNET_CONFIGURATION_get_value_string(cfg, section, "DATABASE", &name)) 149 GNUNET_CONFIGURATION_get_value_string (cfg, section, "DATABASE", &name))
149 { 150 {
150 GNUNET_log_config_missing(GNUNET_ERROR_TYPE_ERROR, section, "DATABASE"); 151 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, section, "DATABASE");
151 return NULL; 152 return NULL;
152 } 153 }
153 bf_size = quota / 32; /* 8 bit per entry, 1 bit per 32 kb in DB */ 154 bf_size = quota / 32; /* 8 bit per entry, 1 bit per 32 kb in DB */
154 155
155 ret = GNUNET_new(struct GNUNET_DATACACHE_Handle); 156 ret = GNUNET_new (struct GNUNET_DATACACHE_Handle);
156 157
157 if (GNUNET_YES != 158 if (GNUNET_YES !=
158 GNUNET_CONFIGURATION_get_value_yesno(cfg, section, "DISABLE_BF")) 159 GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "DISABLE_BF"))
160 {
161 if (GNUNET_YES !=
162 GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "DISABLE_BF_RC"))
163 {
164 ret->bloom_name = GNUNET_DISK_mktemp ("gnunet-datacachebloom");
165 }
166 if (NULL != ret->bloom_name)
167 {
168 ret->filter = GNUNET_CONTAINER_bloomfilter_load (
169 ret->bloom_name,
170 quota / 1024, /* 8 bit per entry in DB, expect 1k entries */
171 5);
172 }
173 if (NULL == ret->filter)
159 { 174 {
160 if (GNUNET_YES != 175 ret->filter =
161 GNUNET_CONFIGURATION_get_value_yesno(cfg, section, "DISABLE_BF_RC")) 176 GNUNET_CONTAINER_bloomfilter_init (NULL,
162 { 177 bf_size,
163 ret->bloom_name = GNUNET_DISK_mktemp("gnunet-datacachebloom"); 178 5); /* approx. 3% false positives at max use */
164 }
165 if (NULL != ret->bloom_name)
166 {
167 ret->filter = GNUNET_CONTAINER_bloomfilter_load(
168 ret->bloom_name,
169 quota / 1024, /* 8 bit per entry in DB, expect 1k entries */
170 5);
171 }
172 if (NULL == ret->filter)
173 {
174 ret->filter =
175 GNUNET_CONTAINER_bloomfilter_init(NULL,
176 bf_size,
177 5); /* approx. 3% false positives at max use */
178 }
179 } 179 }
180 ret->stats = GNUNET_STATISTICS_create("datacache", cfg); 180 }
181 ret->section = GNUNET_strdup(section); 181 ret->stats = GNUNET_STATISTICS_create ("datacache", cfg);
182 ret->section = GNUNET_strdup (section);
182 ret->env.cfg = cfg; 183 ret->env.cfg = cfg;
183 ret->env.delete_notify = &env_delete_notify; 184 ret->env.delete_notify = &env_delete_notify;
184 ret->env.section = ret->section; 185 ret->env.section = ret->section;
185 ret->env.cls = ret; 186 ret->env.cls = ret;
186 ret->env.delete_notify = &env_delete_notify; 187 ret->env.delete_notify = &env_delete_notify;
187 ret->env.quota = quota; 188 ret->env.quota = quota;
188 LOG(GNUNET_ERROR_TYPE_INFO, _("Loading `%s' datacache plugin\n"), name); 189 LOG (GNUNET_ERROR_TYPE_INFO, _ ("Loading `%s' datacache plugin\n"), name);
189 GNUNET_asprintf(&libname, "libgnunet_plugin_datacache_%s", name); 190 GNUNET_asprintf (&libname, "libgnunet_plugin_datacache_%s", name);
190 ret->short_name = name; 191 ret->short_name = name;
191 ret->lib_name = libname; 192 ret->lib_name = libname;
192 ret->api = GNUNET_PLUGIN_load(libname, &ret->env); 193 ret->api = GNUNET_PLUGIN_load (libname, &ret->env);
193 if (ret->api == NULL) 194 if (ret->api == NULL)
194 { 195 {
195 LOG(GNUNET_ERROR_TYPE_ERROR, 196 LOG (GNUNET_ERROR_TYPE_ERROR,
196 _("Failed to load datacache plugin for `%s'\n"), 197 _ ("Failed to load datacache plugin for `%s'\n"),
197 name); 198 name);
198 GNUNET_DATACACHE_destroy(ret); 199 GNUNET_DATACACHE_destroy (ret);
199 return NULL; 200 return NULL;
200 } 201 }
201 return ret; 202 return ret;
202} 203}
203 204
@@ -208,26 +209,26 @@ GNUNET_DATACACHE_create(const struct GNUNET_CONFIGURATION_Handle *cfg,
208 * @param h handle to the datastore 209 * @param h handle to the datastore
209 */ 210 */
210void 211void
211GNUNET_DATACACHE_destroy(struct GNUNET_DATACACHE_Handle *h) 212GNUNET_DATACACHE_destroy (struct GNUNET_DATACACHE_Handle *h)
212{ 213{
213 if (NULL != h->filter) 214 if (NULL != h->filter)
214 GNUNET_CONTAINER_bloomfilter_free(h->filter); 215 GNUNET_CONTAINER_bloomfilter_free (h->filter);
215 if (NULL != h->api) 216 if (NULL != h->api)
216 GNUNET_break(NULL == GNUNET_PLUGIN_unload(h->lib_name, h->api)); 217 GNUNET_break (NULL == GNUNET_PLUGIN_unload (h->lib_name, h->api));
217 GNUNET_free(h->lib_name); 218 GNUNET_free (h->lib_name);
218 GNUNET_free(h->short_name); 219 GNUNET_free (h->short_name);
219 GNUNET_free(h->section); 220 GNUNET_free (h->section);
220 if (NULL != h->bloom_name) 221 if (NULL != h->bloom_name)
221 { 222 {
222 if (0 != unlink(h->bloom_name)) 223 if (0 != unlink (h->bloom_name))
223 GNUNET_log_from_strerror_file(GNUNET_ERROR_TYPE_WARNING, 224 GNUNET_log_from_strerror_file (GNUNET_ERROR_TYPE_WARNING,
224 "datacache", 225 "datacache",
225 "unlink", 226 "unlink",
226 h->bloom_name); 227 h->bloom_name);
227 GNUNET_free(h->bloom_name); 228 GNUNET_free (h->bloom_name);
228 } 229 }
229 GNUNET_STATISTICS_destroy(h->stats, GNUNET_NO); 230 GNUNET_STATISTICS_destroy (h->stats, GNUNET_NO);
230 GNUNET_free(h); 231 GNUNET_free (h);
231} 232}
232 233
233 234
@@ -246,52 +247,52 @@ GNUNET_DATACACHE_destroy(struct GNUNET_DATACACHE_Handle *h)
246 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error, #GNUNET_NO if duplicate 247 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error, #GNUNET_NO if duplicate
247 */ 248 */
248int 249int
249GNUNET_DATACACHE_put(struct GNUNET_DATACACHE_Handle *h, 250GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h,
250 const struct GNUNET_HashCode *key, 251 const struct GNUNET_HashCode *key,
251 uint32_t xor_distance, 252 uint32_t xor_distance,
252 size_t data_size, 253 size_t data_size,
253 const char *data, 254 const char *data,
254 enum GNUNET_BLOCK_Type type, 255 enum GNUNET_BLOCK_Type type,
255 struct GNUNET_TIME_Absolute discard_time, 256 struct GNUNET_TIME_Absolute discard_time,
256 unsigned int path_info_len, 257 unsigned int path_info_len,
257 const struct GNUNET_PeerIdentity *path_info) 258 const struct GNUNET_PeerIdentity *path_info)
258{ 259{
259 ssize_t used; 260 ssize_t used;
260 261
261 used = h->api->put(h->api->cls, 262 used = h->api->put (h->api->cls,
262 key, 263 key,
263 xor_distance, 264 xor_distance,
264 data_size, 265 data_size,
265 data, 266 data,
266 type, 267 type,
267 discard_time, 268 discard_time,
268 path_info_len, 269 path_info_len,
269 path_info); 270 path_info);
270 if (-1 == used) 271 if (-1 == used)
271 { 272 {
272 GNUNET_break(0); 273 GNUNET_break (0);
273 return GNUNET_SYSERR; 274 return GNUNET_SYSERR;
274 } 275 }
275 if (0 == used) 276 if (0 == used)
276 { 277 {
277 /* duplicate */ 278 /* duplicate */
278 return GNUNET_NO; 279 return GNUNET_NO;
279 } 280 }
280 LOG(GNUNET_ERROR_TYPE_DEBUG, 281 LOG (GNUNET_ERROR_TYPE_DEBUG,
281 "Stored data under key `%s' in cache\n", 282 "Stored data under key `%s' in cache\n",
282 GNUNET_h2s(key)); 283 GNUNET_h2s (key));
283 if (NULL != h->filter) 284 if (NULL != h->filter)
284 GNUNET_CONTAINER_bloomfilter_add(h->filter, key); 285 GNUNET_CONTAINER_bloomfilter_add (h->filter, key);
285 GNUNET_STATISTICS_update(h->stats, 286 GNUNET_STATISTICS_update (h->stats,
286 gettext_noop("# bytes stored"), 287 gettext_noop ("# bytes stored"),
287 used, 288 used,
288 GNUNET_NO); 289 GNUNET_NO);
289 GNUNET_STATISTICS_update(h->stats, 290 GNUNET_STATISTICS_update (h->stats,
290 gettext_noop("# items stored"), 291 gettext_noop ("# items stored"),
291 1, 292 1,
292 GNUNET_NO); 293 GNUNET_NO);
293 while (h->utilization + used > h->env.quota) 294 while (h->utilization + used > h->env.quota)
294 GNUNET_assert(GNUNET_OK == h->api->del(h->api->cls)); 295 GNUNET_assert (GNUNET_OK == h->api->del (h->api->cls));
295 h->utilization += used; 296 h->utilization += used;
296 return GNUNET_OK; 297 return GNUNET_OK;
297} 298}
@@ -309,33 +310,33 @@ GNUNET_DATACACHE_put(struct GNUNET_DATACACHE_Handle *h,
309 * @return the number of results found 310 * @return the number of results found
310 */ 311 */
311unsigned int 312unsigned int
312GNUNET_DATACACHE_get(struct GNUNET_DATACACHE_Handle *h, 313GNUNET_DATACACHE_get (struct GNUNET_DATACACHE_Handle *h,
313 const struct GNUNET_HashCode *key, 314 const struct GNUNET_HashCode *key,
314 enum GNUNET_BLOCK_Type type, 315 enum GNUNET_BLOCK_Type type,
315 GNUNET_DATACACHE_Iterator iter, 316 GNUNET_DATACACHE_Iterator iter,
316 void *iter_cls) 317 void *iter_cls)
317{ 318{
318 GNUNET_STATISTICS_update(h->stats, 319 GNUNET_STATISTICS_update (h->stats,
319 gettext_noop("# requests received"), 320 gettext_noop ("# requests received"),
320 1, 321 1,
321 GNUNET_NO); 322 GNUNET_NO);
322 LOG(GNUNET_ERROR_TYPE_DEBUG, 323 LOG (GNUNET_ERROR_TYPE_DEBUG,
323 "Processing request for key `%s'\n", 324 "Processing request for key `%s'\n",
324 GNUNET_h2s(key)); 325 GNUNET_h2s (key));
325 if ((NULL != h->filter) && 326 if ((NULL != h->filter) &&
326 (GNUNET_OK != GNUNET_CONTAINER_bloomfilter_test(h->filter, key))) 327 (GNUNET_OK != GNUNET_CONTAINER_bloomfilter_test (h->filter, key)))
327 { 328 {
328 GNUNET_STATISTICS_update(h->stats, 329 GNUNET_STATISTICS_update (h->stats,
329 gettext_noop( 330 gettext_noop (
330 "# requests filtered by bloom filter"), 331 "# requests filtered by bloom filter"),
331 1, 332 1,
332 GNUNET_NO); 333 GNUNET_NO);
333 LOG(GNUNET_ERROR_TYPE_DEBUG, 334 LOG (GNUNET_ERROR_TYPE_DEBUG,
334 "Bloomfilter filters request for key `%s'\n", 335 "Bloomfilter filters request for key `%s'\n",
335 GNUNET_h2s(key)); 336 GNUNET_h2s (key));
336 return 0; /* can not be present */ 337 return 0; /* can not be present */
337 } 338 }
338 return h->api->get(h->api->cls, key, type, iter, iter_cls); 339 return h->api->get (h->api->cls, key, type, iter, iter_cls);
339} 340}
340 341
341 342
@@ -348,17 +349,17 @@ GNUNET_DATACACHE_get(struct GNUNET_DATACACHE_Handle *h,
348 * @return the number of results found (zero or 1) 349 * @return the number of results found (zero or 1)
349 */ 350 */
350unsigned int 351unsigned int
351GNUNET_DATACACHE_get_random(struct GNUNET_DATACACHE_Handle *h, 352GNUNET_DATACACHE_get_random (struct GNUNET_DATACACHE_Handle *h,
352 GNUNET_DATACACHE_Iterator iter, 353 GNUNET_DATACACHE_Iterator iter,
353 void *iter_cls) 354 void *iter_cls)
354{ 355{
355 GNUNET_STATISTICS_update(h->stats, 356 GNUNET_STATISTICS_update (h->stats,
356 gettext_noop( 357 gettext_noop (
357 "# requests for random value received"), 358 "# requests for random value received"),
358 1, 359 1,
359 GNUNET_NO); 360 GNUNET_NO);
360 LOG(GNUNET_ERROR_TYPE_DEBUG, "Processing request for random value\n"); 361 LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing request for random value\n");
361 return h->api->get_random(h->api->cls, iter, iter_cls); 362 return h->api->get_random (h->api->cls, iter, iter_cls);
362} 363}
363 364
364 365
@@ -376,21 +377,21 @@ GNUNET_DATACACHE_get_random(struct GNUNET_DATACACHE_Handle *h,
376 * @return the number of results found 377 * @return the number of results found
377 */ 378 */
378unsigned int 379unsigned int
379GNUNET_DATACACHE_get_closest(struct GNUNET_DATACACHE_Handle *h, 380GNUNET_DATACACHE_get_closest (struct GNUNET_DATACACHE_Handle *h,
380 const struct GNUNET_HashCode *key, 381 const struct GNUNET_HashCode *key,
381 unsigned int num_results, 382 unsigned int num_results,
382 GNUNET_DATACACHE_Iterator iter, 383 GNUNET_DATACACHE_Iterator iter,
383 void *iter_cls) 384 void *iter_cls)
384{ 385{
385 GNUNET_STATISTICS_update(h->stats, 386 GNUNET_STATISTICS_update (h->stats,
386 gettext_noop( 387 gettext_noop (
387 "# proximity search requests received"), 388 "# proximity search requests received"),
388 1, 389 1,
389 GNUNET_NO); 390 GNUNET_NO);
390 LOG(GNUNET_ERROR_TYPE_DEBUG, 391 LOG (GNUNET_ERROR_TYPE_DEBUG,
391 "Processing proximity search at `%s'\n", 392 "Processing proximity search at `%s'\n",
392 GNUNET_h2s(key)); 393 GNUNET_h2s (key));
393 return h->api->get_closest(h->api->cls, key, num_results, iter, iter_cls); 394 return h->api->get_closest (h->api->cls, key, num_results, iter, iter_cls);
394} 395}
395 396
396 397