aboutsummaryrefslogtreecommitdiff
path: root/src/datacache
diff options
context:
space:
mode:
Diffstat (limited to 'src/datacache')
-rw-r--r--src/datacache/datacache.c86
-rw-r--r--src/datacache/plugin_datacache_heap.c70
-rw-r--r--src/datacache/plugin_datacache_postgres.c23
-rw-r--r--src/datacache/plugin_datacache_sqlite.c62
-rw-r--r--src/datacache/plugin_datacache_template.c2
5 files changed, 175 insertions, 68 deletions
diff --git a/src/datacache/datacache.c b/src/datacache/datacache.c
index 944a99aad..761ab801f 100644
--- a/src/datacache/datacache.c
+++ b/src/datacache/datacache.c
@@ -114,11 +114,11 @@ env_delete_notify (void *cls,
114 h->utilization -= size; 114 h->utilization -= size;
115 GNUNET_CONTAINER_bloomfilter_remove (h->filter, key); 115 GNUNET_CONTAINER_bloomfilter_remove (h->filter, key);
116 GNUNET_STATISTICS_update (h->stats, 116 GNUNET_STATISTICS_update (h->stats,
117 gettext_noop ("# bytes stored"), 117 "# bytes stored",
118 -(long long) size, 118 -(long long) size,
119 GNUNET_NO); 119 GNUNET_NO);
120 GNUNET_STATISTICS_update (h->stats, 120 GNUNET_STATISTICS_update (h->stats,
121 gettext_noop ("# items stored"), 121 "# items stored",
122 -1, 122 -1,
123 GNUNET_NO); 123 GNUNET_NO);
124} 124}
@@ -136,15 +136,25 @@ GNUNET_DATACACHE_create (const struct GNUNET_CONFIGURATION_Handle *cfg,
136 const struct GNUNET_OS_ProjectData *pd; 136 const struct GNUNET_OS_ProjectData *pd;
137 137
138 if (GNUNET_OK != 138 if (GNUNET_OK !=
139 GNUNET_CONFIGURATION_get_value_size (cfg, section, "QUOTA", &quota)) 139 GNUNET_CONFIGURATION_get_value_size (cfg,
140 section,
141 "QUOTA",
142 &quota))
140 { 143 {
141 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, section, "QUOTA"); 144 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
145 section,
146 "QUOTA");
142 return NULL; 147 return NULL;
143 } 148 }
144 if (GNUNET_OK != 149 if (GNUNET_OK !=
145 GNUNET_CONFIGURATION_get_value_string (cfg, section, "DATABASE", &name)) 150 GNUNET_CONFIGURATION_get_value_string (cfg,
151 section,
152 "DATABASE",
153 &name))
146 { 154 {
147 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, section, "DATABASE"); 155 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
156 section,
157 "DATABASE");
148 return NULL; 158 return NULL;
149 } 159 }
150 bf_size = quota / 32; /* 8 bit per entry, 1 bit per 32 kb in DB */ 160 bf_size = quota / 32; /* 8 bit per entry, 1 bit per 32 kb in DB */
@@ -152,10 +162,14 @@ GNUNET_DATACACHE_create (const struct GNUNET_CONFIGURATION_Handle *cfg,
152 ret = GNUNET_new (struct GNUNET_DATACACHE_Handle); 162 ret = GNUNET_new (struct GNUNET_DATACACHE_Handle);
153 163
154 if (GNUNET_YES != 164 if (GNUNET_YES !=
155 GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "DISABLE_BF")) 165 GNUNET_CONFIGURATION_get_value_yesno (cfg,
166 section,
167 "DISABLE_BF"))
156 { 168 {
157 if (GNUNET_YES != 169 if (GNUNET_YES !=
158 GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "DISABLE_BF_RC")) 170 GNUNET_CONFIGURATION_get_value_yesno (cfg,
171 section,
172 "DISABLE_BF_RC"))
159 { 173 {
160 ret->bloom_name = GNUNET_DISK_mktemp ("gnunet-datacachebloom"); 174 ret->bloom_name = GNUNET_DISK_mktemp ("gnunet-datacachebloom");
161 } 175 }
@@ -174,7 +188,8 @@ GNUNET_DATACACHE_create (const struct GNUNET_CONFIGURATION_Handle *cfg,
174 5); /* approx. 3% false positives at max use */ 188 5); /* approx. 3% false positives at max use */
175 } 189 }
176 } 190 }
177 ret->stats = GNUNET_STATISTICS_create ("datacache", cfg); 191 ret->stats = GNUNET_STATISTICS_create ("datacache",
192 cfg);
178 ret->section = GNUNET_strdup (section); 193 ret->section = GNUNET_strdup (section);
179 ret->env.cfg = cfg; 194 ret->env.cfg = cfg;
180 ret->env.delete_notify = &env_delete_notify; 195 ret->env.delete_notify = &env_delete_notify;
@@ -182,25 +197,31 @@ GNUNET_DATACACHE_create (const struct GNUNET_CONFIGURATION_Handle *cfg,
182 ret->env.cls = ret; 197 ret->env.cls = ret;
183 ret->env.delete_notify = &env_delete_notify; 198 ret->env.delete_notify = &env_delete_notify;
184 ret->env.quota = quota; 199 ret->env.quota = quota;
185 LOG (GNUNET_ERROR_TYPE_INFO, _ ("Loading `%s' datacache plugin\n"), name); 200 LOG (GNUNET_ERROR_TYPE_INFO,
186 GNUNET_asprintf (&libname, "libgnunet_plugin_datacache_%s", name); 201 "Loading `%s' datacache plugin\n",
202 name);
203 GNUNET_asprintf (&libname,
204 "libgnunet_plugin_datacache_%s",
205 name);
187 ret->short_name = name; 206 ret->short_name = name;
188 ret->lib_name = libname; 207 ret->lib_name = libname;
189 /* Load the plugin within GNUnet's default context */ 208 /* Load the plugin within GNUnet's default context */
190 pd = GNUNET_OS_project_data_get (); 209 pd = GNUNET_OS_project_data_get ();
191 GNUNET_OS_init (GNUNET_OS_project_data_default ()); 210 GNUNET_OS_init (GNUNET_OS_project_data_default ());
192 ret->api = GNUNET_PLUGIN_load (libname, &ret->env); 211 ret->api = GNUNET_PLUGIN_load (libname,
212 &ret->env);
193 GNUNET_OS_init (pd); 213 GNUNET_OS_init (pd);
194 if (NULL == ret->api) 214 if (NULL == ret->api)
195 { 215 {
196 /* Try to load the plugin within the application's context 216 /* Try to load the plugin within the application's context
197 This normally happens when the application is not GNUnet itself but a 217 This normally happens when the application is not GNUnet itself but a
198 third party; inside GNUnet this is effectively a double failure. */ 218 third party; inside GNUnet this is effectively a double failure. */
199 ret->api = GNUNET_PLUGIN_load (libname, &ret->env); 219 ret->api = GNUNET_PLUGIN_load (libname,
220 &ret->env);
200 if (NULL == ret->api) 221 if (NULL == ret->api)
201 { 222 {
202 LOG (GNUNET_ERROR_TYPE_ERROR, 223 LOG (GNUNET_ERROR_TYPE_ERROR,
203 _ ("Failed to load datacache plugin for `%s'\n"), 224 "Failed to load datacache plugin for `%s'\n",
204 name); 225 name);
205 GNUNET_DATACACHE_destroy (ret); 226 GNUNET_DATACACHE_destroy (ret);
206 return NULL; 227 return NULL;
@@ -216,7 +237,9 @@ GNUNET_DATACACHE_destroy (struct GNUNET_DATACACHE_Handle *h)
216 if (NULL != h->filter) 237 if (NULL != h->filter)
217 GNUNET_CONTAINER_bloomfilter_free (h->filter); 238 GNUNET_CONTAINER_bloomfilter_free (h->filter);
218 if (NULL != h->api) 239 if (NULL != h->api)
219 GNUNET_break (NULL == GNUNET_PLUGIN_unload (h->lib_name, h->api)); 240 GNUNET_break (NULL ==
241 GNUNET_PLUGIN_unload (h->lib_name,
242 h->api));
220 GNUNET_free (h->lib_name); 243 GNUNET_free (h->lib_name);
221 GNUNET_free (h->short_name); 244 GNUNET_free (h->short_name);
222 GNUNET_free (h->section); 245 GNUNET_free (h->section);
@@ -270,17 +293,19 @@ GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h,
270 "Stored data under key `%s' in cache\n", 293 "Stored data under key `%s' in cache\n",
271 GNUNET_h2s (key)); 294 GNUNET_h2s (key));
272 if (NULL != h->filter) 295 if (NULL != h->filter)
273 GNUNET_CONTAINER_bloomfilter_add (h->filter, key); 296 GNUNET_CONTAINER_bloomfilter_add (h->filter,
297 key);
274 GNUNET_STATISTICS_update (h->stats, 298 GNUNET_STATISTICS_update (h->stats,
275 gettext_noop ("# bytes stored"), 299 "# bytes stored",
276 used, 300 used,
277 GNUNET_NO); 301 GNUNET_NO);
278 GNUNET_STATISTICS_update (h->stats, 302 GNUNET_STATISTICS_update (h->stats,
279 gettext_noop ("# items stored"), 303 "# items stored",
280 1, 304 1,
281 GNUNET_NO); 305 GNUNET_NO);
282 while (h->utilization + used > h->env.quota) 306 while (h->utilization + used > h->env.quota)
283 GNUNET_assert (GNUNET_OK == h->api->del (h->api->cls)); 307 GNUNET_assert (GNUNET_OK ==
308 h->api->del (h->api->cls));
284 h->utilization += used; 309 h->utilization += used;
285 return GNUNET_OK; 310 return GNUNET_OK;
286} 311}
@@ -294,18 +319,18 @@ GNUNET_DATACACHE_get (struct GNUNET_DATACACHE_Handle *h,
294 void *iter_cls) 319 void *iter_cls)
295{ 320{
296 GNUNET_STATISTICS_update (h->stats, 321 GNUNET_STATISTICS_update (h->stats,
297 gettext_noop ("# requests received"), 322 "# requests received",
298 1, 323 1,
299 GNUNET_NO); 324 GNUNET_NO);
300 LOG (GNUNET_ERROR_TYPE_DEBUG, 325 LOG (GNUNET_ERROR_TYPE_DEBUG,
301 "Processing request for key `%s'\n", 326 "Processing request for key `%s'\n",
302 GNUNET_h2s (key)); 327 GNUNET_h2s (key));
303 if ((NULL != h->filter) && 328 if ((NULL != h->filter) &&
304 (GNUNET_OK != GNUNET_CONTAINER_bloomfilter_test (h->filter, key))) 329 (GNUNET_OK !=
330 GNUNET_CONTAINER_bloomfilter_test (h->filter, key)))
305 { 331 {
306 GNUNET_STATISTICS_update (h->stats, 332 GNUNET_STATISTICS_update (h->stats,
307 gettext_noop ( 333 "# requests filtered by bloom filter",
308 "# requests filtered by bloom filter"),
309 1, 334 1,
310 GNUNET_NO); 335 GNUNET_NO);
311 LOG (GNUNET_ERROR_TYPE_DEBUG, 336 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -313,26 +338,33 @@ GNUNET_DATACACHE_get (struct GNUNET_DATACACHE_Handle *h,
313 GNUNET_h2s (key)); 338 GNUNET_h2s (key));
314 return 0; /* can not be present */ 339 return 0; /* can not be present */
315 } 340 }
316 return h->api->get (h->api->cls, key, type, iter, iter_cls); 341 return h->api->get (h->api->cls,
342 key,
343 type,
344 iter, iter_cls);
317} 345}
318 346
319 347
320unsigned int 348unsigned int
321GNUNET_DATACACHE_get_closest (struct GNUNET_DATACACHE_Handle *h, 349GNUNET_DATACACHE_get_closest (struct GNUNET_DATACACHE_Handle *h,
322 const struct GNUNET_HashCode *key, 350 const struct GNUNET_HashCode *key,
351 enum GNUNET_BLOCK_Type type,
323 unsigned int num_results, 352 unsigned int num_results,
324 GNUNET_DATACACHE_Iterator iter, 353 GNUNET_DATACACHE_Iterator iter,
325 void *iter_cls) 354 void *iter_cls)
326{ 355{
327 GNUNET_STATISTICS_update (h->stats, 356 GNUNET_STATISTICS_update (h->stats,
328 gettext_noop ( 357 "# proximity search requests received",
329 "# proximity search requests received"),
330 1, 358 1,
331 GNUNET_NO); 359 GNUNET_NO);
332 LOG (GNUNET_ERROR_TYPE_DEBUG, 360 LOG (GNUNET_ERROR_TYPE_DEBUG,
333 "Processing proximity search at `%s'\n", 361 "Processing proximity search at `%s'\n",
334 GNUNET_h2s (key)); 362 GNUNET_h2s (key));
335 return h->api->get_closest (h->api->cls, key, num_results, iter, iter_cls); 363 return h->api->get_closest (h->api->cls,
364 key,
365 type,
366 num_results,
367 iter, iter_cls);
336} 368}
337 369
338 370
diff --git a/src/datacache/plugin_datacache_heap.c b/src/datacache/plugin_datacache_heap.c
index fbd3aea9a..5b50468a5 100644
--- a/src/datacache/plugin_datacache_heap.c
+++ b/src/datacache/plugin_datacache_heap.c
@@ -158,7 +158,7 @@ struct PutContext
158 * @param value an existing value 158 * @param value an existing value
159 * @return #GNUNET_YES if not found (to continue to iterate) 159 * @return #GNUNET_YES if not found (to continue to iterate)
160 */ 160 */
161static int 161static enum GNUNET_GenericReturnValue
162put_cb (void *cls, 162put_cb (void *cls,
163 const struct GNUNET_HashCode *key, 163 const struct GNUNET_HashCode *key,
164 void *value) 164 void *value)
@@ -224,15 +224,20 @@ heap_plugin_put (void *cls,
224{ 224{
225 struct Plugin *plugin = cls; 225 struct Plugin *plugin = cls;
226 struct Value *val; 226 struct Value *val;
227 struct PutContext put_ctx; 227 struct PutContext put_ctx = {
228 228 .data = data,
229 put_ctx.found = GNUNET_NO; 229 .size = size,
230 put_ctx.data = data; 230 .path_info = path_info,
231 put_ctx.size = size; 231 .path_info_len = path_info_len,
232 put_ctx.path_info = path_info; 232 .discard_time = discard_time,
233 put_ctx.path_info_len = path_info_len; 233 .type = type
234 put_ctx.discard_time = discard_time; 234 };
235 put_ctx.type = type; 235
236 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
237 "Storing %u bytes under key %s with path length %u\n",
238 (unsigned int) size,
239 GNUNET_h2s (key),
240 path_info_len);
236 GNUNET_CONTAINER_multihashmap_get_multiple (plugin->map, 241 GNUNET_CONTAINER_multihashmap_get_multiple (plugin->map,
237 key, 242 key,
238 &put_cb, 243 &put_cb,
@@ -313,12 +318,25 @@ get_cb (void *cls,
313 struct Value *val = value; 318 struct Value *val = value;
314 int ret; 319 int ret;
315 320
316 if ((get_ctx->type != val->type) && 321 if ( (get_ctx->type != val->type) &&
317 (GNUNET_BLOCK_TYPE_ANY != get_ctx->type)) 322 (GNUNET_BLOCK_TYPE_ANY != get_ctx->type) )
323 {
324 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
325 "Result for key %s does not match block type %d\n",
326 GNUNET_h2s (key),
327 get_ctx->type);
318 return GNUNET_OK; 328 return GNUNET_OK;
319 if (0 == 329 }
320 GNUNET_TIME_absolute_get_remaining (val->discard_time).rel_value_us) 330 if (GNUNET_TIME_absolute_is_past (val->discard_time))
331 {
332 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
333 "Result for key %s is expired\n",
334 GNUNET_h2s (key));
321 return GNUNET_OK; 335 return GNUNET_OK;
336 }
337 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
338 "Found result for key %s\n",
339 GNUNET_h2s (key));
322 if (NULL != get_ctx->iter) 340 if (NULL != get_ctx->iter)
323 ret = get_ctx->iter (get_ctx->iter_cls, 341 ret = get_ctx->iter (get_ctx->iter_cls,
324 key, 342 key,
@@ -409,13 +427,16 @@ struct GetClosestContext
409{ 427{
410 struct Value **values; 428 struct Value **values;
411 429
430 const struct GNUNET_HashCode *key;
431
432 enum GNUNET_BLOCK_Type type;
433
412 unsigned int num_results; 434 unsigned int num_results;
413 435
414 const struct GNUNET_HashCode *key;
415}; 436};
416 437
417 438
418static int 439static enum GNUNET_GenericReturnValue
419find_closest (void *cls, 440find_closest (void *cls,
420 const struct GNUNET_HashCode *key, 441 const struct GNUNET_HashCode *key,
421 void *value) 442 void *value)
@@ -427,6 +448,9 @@ find_closest (void *cls,
427 if (1 != GNUNET_CRYPTO_hash_cmp (key, 448 if (1 != GNUNET_CRYPTO_hash_cmp (key,
428 gcc->key)) 449 gcc->key))
429 return GNUNET_OK; /* useless */ 450 return GNUNET_OK; /* useless */
451 if ( (val->type != gcc->type) &&
452 (GNUNET_BLOCK_TYPE_ANY != gcc->type) )
453 return GNUNET_OK; /* useless */
430 j = gcc->num_results; 454 j = gcc->num_results;
431 for (unsigned int i = 0; i < gcc->num_results; i++) 455 for (unsigned int i = 0; i < gcc->num_results; i++)
432 { 456 {
@@ -435,8 +459,9 @@ find_closest (void *cls,
435 j = i; 459 j = i;
436 break; 460 break;
437 } 461 }
438 if (1 == GNUNET_CRYPTO_hash_cmp (&gcc->values[i]->key, 462 if (1 ==
439 key)) 463 GNUNET_CRYPTO_hash_cmp (&gcc->values[i]->key,
464 key))
440 { 465 {
441 j = i; 466 j = i;
442 break; 467 break;
@@ -457,6 +482,7 @@ find_closest (void *cls,
457 * 482 *
458 * @param cls closure (internal context for the plugin) 483 * @param cls closure (internal context for the plugin)
459 * @param key area of the keyspace to look into 484 * @param key area of the keyspace to look into
485 * @param type desired block type for the replies
460 * @param num_results number of results that should be returned to @a iter 486 * @param num_results number of results that should be returned to @a iter
461 * @param iter maybe NULL (to just count) 487 * @param iter maybe NULL (to just count)
462 * @param iter_cls closure for @a iter 488 * @param iter_cls closure for @a iter
@@ -465,6 +491,7 @@ find_closest (void *cls,
465static unsigned int 491static unsigned int
466heap_plugin_get_closest (void *cls, 492heap_plugin_get_closest (void *cls,
467 const struct GNUNET_HashCode *key, 493 const struct GNUNET_HashCode *key,
494 enum GNUNET_BLOCK_Type type,
468 unsigned int num_results, 495 unsigned int num_results,
469 GNUNET_DATACACHE_Iterator iter, 496 GNUNET_DATACACHE_Iterator iter,
470 void *iter_cls) 497 void *iter_cls)
@@ -473,14 +500,15 @@ heap_plugin_get_closest (void *cls,
473 struct Value *values[num_results]; 500 struct Value *values[num_results];
474 struct GetClosestContext gcc = { 501 struct GetClosestContext gcc = {
475 .values = values, 502 .values = values,
476 .num_results = num_results, 503 .type = type,
504 .num_results = num_results * 2,
477 .key = key 505 .key = key
478 }; 506 };
479 507
480 GNUNET_CONTAINER_multihashmap_iterate (plugin->map, 508 GNUNET_CONTAINER_multihashmap_iterate (plugin->map,
481 &find_closest, 509 &find_closest,
482 &gcc); 510 &gcc);
483 for (unsigned int i = 0; i < num_results; i++) 511 for (unsigned int i = 0; i < num_results * 2; i++)
484 { 512 {
485 if (NULL == values[i]) 513 if (NULL == values[i])
486 return i; 514 return i;
@@ -493,7 +521,7 @@ heap_plugin_get_closest (void *cls,
493 values[i]->path_info_len, 521 values[i]->path_info_len,
494 values[i]->path_info); 522 values[i]->path_info);
495 } 523 }
496 return num_results; 524 return num_results * 2;
497} 525}
498 526
499 527
diff --git a/src/datacache/plugin_datacache_postgres.c b/src/datacache/plugin_datacache_postgres.c
index 6a44c44a5..1a83cda86 100644
--- a/src/datacache/plugin_datacache_postgres.c
+++ b/src/datacache/plugin_datacache_postgres.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 Copyright (C) 2006, 2009, 2010, 2012, 2015, 2017, 2018 GNUnet e.V. 3 Copyright (C) 2006, 2009, 2010, 2012, 2015, 2017, 2018, 2022 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 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 6 under the terms of the GNU Affero General Public License as published
@@ -109,9 +109,20 @@ init_connection (struct Plugin *plugin)
109 " ORDER BY prox ASC, discard_time ASC LIMIT 1", 109 " ORDER BY prox ASC, discard_time ASC LIMIT 1",
110 0), 110 0),
111 GNUNET_PQ_make_prepare ("get_closest", 111 GNUNET_PQ_make_prepare ("get_closest",
112 "SELECT discard_time,type,value,path,key FROM gn011dc " 112 "(SELECT discard_time,type,value,path,key FROM gn011dc"
113 "WHERE key>=$1 AND discard_time >= $2 ORDER BY key ASC LIMIT $3", 113 " WHERE key >= $1"
114 3), 114 " AND discard_time >= $2"
115 " AND ( (type = $3) OR ( 0 = $3) )"
116 " ORDER BY key ASC"
117 " LIMIT $4)"
118 " UNION "
119 "(SELECT discard_time,type,value,path,key FROM gn011dc"
120 " WHERE key <= $1"
121 " AND discard_time >= $2"
122 " AND ( (type = $3) OR ( 0 = $3) )"
123 " ORDER BY key DESC"
124 " LIMIT $4)",
125 4),
115 GNUNET_PQ_make_prepare ("delrow", 126 GNUNET_PQ_make_prepare ("delrow",
116 "DELETE FROM gn011dc WHERE oid=$1", 127 "DELETE FROM gn011dc WHERE oid=$1",
117 1), 128 1),
@@ -511,6 +522,7 @@ extract_result_cb (void *cls,
511 * 522 *
512 * @param cls closure (internal context for the plugin) 523 * @param cls closure (internal context for the plugin)
513 * @param key area of the keyspace to look into 524 * @param key area of the keyspace to look into
525 * @param type desired block type for the replies
514 * @param num_results number of results that should be returned to @a iter 526 * @param num_results number of results that should be returned to @a iter
515 * @param iter maybe NULL (to just count) 527 * @param iter maybe NULL (to just count)
516 * @param iter_cls closure for @a iter 528 * @param iter_cls closure for @a iter
@@ -519,16 +531,19 @@ extract_result_cb (void *cls,
519static unsigned int 531static unsigned int
520postgres_plugin_get_closest (void *cls, 532postgres_plugin_get_closest (void *cls,
521 const struct GNUNET_HashCode *key, 533 const struct GNUNET_HashCode *key,
534 enum GNUNET_BLOCK_Type type,
522 unsigned int num_results, 535 unsigned int num_results,
523 GNUNET_DATACACHE_Iterator iter, 536 GNUNET_DATACACHE_Iterator iter,
524 void *iter_cls) 537 void *iter_cls)
525{ 538{
526 struct Plugin *plugin = cls; 539 struct Plugin *plugin = cls;
527 uint32_t num_results32 = (uint32_t) num_results; 540 uint32_t num_results32 = (uint32_t) num_results;
541 uint32_t type32 = (uint32_t) type;
528 struct GNUNET_TIME_Absolute now; 542 struct GNUNET_TIME_Absolute now;
529 struct GNUNET_PQ_QueryParam params[] = { 543 struct GNUNET_PQ_QueryParam params[] = {
530 GNUNET_PQ_query_param_auto_from_type (key), 544 GNUNET_PQ_query_param_auto_from_type (key),
531 GNUNET_PQ_query_param_absolute_time (&now), 545 GNUNET_PQ_query_param_absolute_time (&now),
546 GNUNET_PQ_query_param_uint32 (&type32),
532 GNUNET_PQ_query_param_uint32 (&num_results32), 547 GNUNET_PQ_query_param_uint32 (&num_results32),
533 GNUNET_PQ_query_param_end 548 GNUNET_PQ_query_param_end
534 }; 549 };
diff --git a/src/datacache/plugin_datacache_sqlite.c b/src/datacache/plugin_datacache_sqlite.c
index d08b32caf..6f2165433 100644
--- a/src/datacache/plugin_datacache_sqlite.c
+++ b/src/datacache/plugin_datacache_sqlite.c
@@ -454,6 +454,7 @@ sqlite_plugin_del (void *cls)
454 * 454 *
455 * @param cls closure (internal context for the plugin) 455 * @param cls closure (internal context for the plugin)
456 * @param key area of the keyspace to look into 456 * @param key area of the keyspace to look into
457 * @param type desired block type for the replies
457 * @param num_results number of results that should be returned to @a iter 458 * @param num_results number of results that should be returned to @a iter
458 * @param iter maybe NULL (to just count) 459 * @param iter maybe NULL (to just count)
459 * @param iter_cls closure for @a iter 460 * @param iter_cls closure for @a iter
@@ -462,11 +463,13 @@ sqlite_plugin_del (void *cls)
462static unsigned int 463static unsigned int
463sqlite_plugin_get_closest (void *cls, 464sqlite_plugin_get_closest (void *cls,
464 const struct GNUNET_HashCode *key, 465 const struct GNUNET_HashCode *key,
466 enum GNUNET_BLOCK_Type type,
465 unsigned int num_results, 467 unsigned int num_results,
466 GNUNET_DATACACHE_Iterator iter, 468 GNUNET_DATACACHE_Iterator iter,
467 void *iter_cls) 469 void *iter_cls)
468{ 470{
469 struct Plugin *plugin = cls; 471 struct Plugin *plugin = cls;
472 uint32_t type32 = type;
470 uint32_t num_results32 = num_results; 473 uint32_t num_results32 = num_results;
471 struct GNUNET_TIME_Absolute now; 474 struct GNUNET_TIME_Absolute now;
472 struct GNUNET_TIME_Absolute exp; 475 struct GNUNET_TIME_Absolute exp;
@@ -474,38 +477,46 @@ sqlite_plugin_get_closest (void *cls,
474 void *dat; 477 void *dat;
475 unsigned int cnt; 478 unsigned int cnt;
476 size_t psize; 479 size_t psize;
477 uint32_t type; 480 uint32_t rtype;
478 struct GNUNET_HashCode hc; 481 struct GNUNET_HashCode hc;
479 struct GNUNET_DHT_PathElement *path; 482 struct GNUNET_DHT_PathElement *path;
480 struct GNUNET_SQ_QueryParam params[] = 483 struct GNUNET_SQ_QueryParam params[] = {
481 { GNUNET_SQ_query_param_auto_from_type (key), 484 GNUNET_SQ_query_param_auto_from_type (key),
482 GNUNET_SQ_query_param_absolute_time (&now), 485 GNUNET_SQ_query_param_absolute_time (&now),
486 GNUNET_SQ_query_param_uint32 (&type32),
483 GNUNET_SQ_query_param_uint32 (&num_results32), 487 GNUNET_SQ_query_param_uint32 (&num_results32),
484 GNUNET_SQ_query_param_end }; 488 GNUNET_SQ_query_param_end
485 struct GNUNET_SQ_ResultSpec rs[] = 489 };
486 { GNUNET_SQ_result_spec_variable_size (&dat, &size), 490 struct GNUNET_SQ_ResultSpec rs[] = {
491 GNUNET_SQ_result_spec_variable_size (&dat, &size),
487 GNUNET_SQ_result_spec_absolute_time (&exp), 492 GNUNET_SQ_result_spec_absolute_time (&exp),
488 GNUNET_SQ_result_spec_variable_size ((void **) &path, &psize), 493 GNUNET_SQ_result_spec_variable_size ((void **) &path, &psize),
489 GNUNET_SQ_result_spec_uint32 (&type), 494 GNUNET_SQ_result_spec_uint32 (&rtype),
490 GNUNET_SQ_result_spec_auto_from_type (&hc), 495 GNUNET_SQ_result_spec_auto_from_type (&hc),
491 GNUNET_SQ_result_spec_end }; 496 GNUNET_SQ_result_spec_end
497 };
492 498
493 now = GNUNET_TIME_absolute_get (); 499 now = GNUNET_TIME_absolute_get ();
494 LOG (GNUNET_ERROR_TYPE_DEBUG, 500 LOG (GNUNET_ERROR_TYPE_DEBUG,
495 "Processing GET_CLOSEST for key `%s'\n", 501 "Processing GET_CLOSEST for key `%s'\n",
496 GNUNET_h2s (key)); 502 GNUNET_h2s (key));
497 if (GNUNET_OK != GNUNET_SQ_bind (plugin->get_closest_stmt, params)) 503 if (GNUNET_OK !=
504 GNUNET_SQ_bind (plugin->get_closest_stmt,
505 params))
498 { 506 {
499 LOG_SQLITE (plugin->dbh, 507 LOG_SQLITE (plugin->dbh,
500 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 508 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
501 "sqlite3_bind_xxx"); 509 "sqlite3_bind_xxx");
502 GNUNET_SQ_reset (plugin->dbh, plugin->get_closest_stmt); 510 GNUNET_SQ_reset (plugin->dbh,
511 plugin->get_closest_stmt);
503 return 0; 512 return 0;
504 } 513 }
505 cnt = 0; 514 cnt = 0;
506 while (SQLITE_ROW == sqlite3_step (plugin->get_closest_stmt)) 515 while (SQLITE_ROW == sqlite3_step (plugin->get_closest_stmt))
507 { 516 {
508 if (GNUNET_OK != GNUNET_SQ_extract_result (plugin->get_closest_stmt, rs)) 517 if (GNUNET_OK !=
518 GNUNET_SQ_extract_result (plugin->get_closest_stmt,
519 rs))
509 { 520 {
510 GNUNET_break (0); 521 GNUNET_break (0);
511 break; 522 break;
@@ -522,14 +533,22 @@ sqlite_plugin_get_closest (void *cls,
522 "Found %u-byte result at %s when processing GET_CLOSE\n", 533 "Found %u-byte result at %s when processing GET_CLOSE\n",
523 (unsigned int) size, 534 (unsigned int) size,
524 GNUNET_h2s (&hc)); 535 GNUNET_h2s (&hc));
525 if (GNUNET_OK != iter (iter_cls, &hc, size, dat, type, exp, psize, path)) 536 if (GNUNET_OK != iter (iter_cls,
537 &hc,
538 size,
539 dat,
540 rtype,
541 exp,
542 psize,
543 path))
526 { 544 {
527 GNUNET_SQ_cleanup_result (rs); 545 GNUNET_SQ_cleanup_result (rs);
528 break; 546 break;
529 } 547 }
530 GNUNET_SQ_cleanup_result (rs); 548 GNUNET_SQ_cleanup_result (rs);
531 } 549 }
532 GNUNET_SQ_reset (plugin->dbh, plugin->get_closest_stmt); 550 GNUNET_SQ_reset (plugin->dbh,
551 plugin->get_closest_stmt);
533 return cnt; 552 return cnt;
534} 553}
535 554
@@ -620,7 +639,7 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
620 &plugin->get_stmt)) || 639 &plugin->get_stmt)) ||
621 (SQLITE_OK != sq_prepare (plugin->dbh, 640 (SQLITE_OK != sq_prepare (plugin->dbh,
622 "SELECT _ROWID_,key,value FROM ds091" 641 "SELECT _ROWID_,key,value FROM ds091"
623 " WHERE expire < ?" 642 " WHERE expire < ?1"
624 " ORDER BY expire ASC LIMIT 1", 643 " ORDER BY expire ASC LIMIT 1",
625 &plugin->del_expired_stmt)) || 644 &plugin->del_expired_stmt)) ||
626 (SQLITE_OK != sq_prepare (plugin->dbh, 645 (SQLITE_OK != sq_prepare (plugin->dbh,
@@ -632,8 +651,19 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
632 &plugin->del_stmt)) || 651 &plugin->del_stmt)) ||
633 (SQLITE_OK != 652 (SQLITE_OK !=
634 sq_prepare (plugin->dbh, 653 sq_prepare (plugin->dbh,
635 "SELECT value,expire,path,type,key FROM ds091 " 654 "SELECT * FROM ("
636 "WHERE key>=? AND expire >= ? ORDER BY KEY ASC LIMIT ?", 655 " SELECT value,expire,path,type,key FROM ds091 "
656 " WHERE key>=?1 "
657 " AND expire >= ?2"
658 " AND ( (type=?3) or (0 == ?3) )"
659 " ORDER BY KEY ASC LIMIT ?4)"
660 "UNION "
661 "SELECT * FROM ("
662 " SELECT value,expire,path,type,key FROM ds091 "
663 " WHERE key<=?1 "
664 " AND expire >= ?2"
665 " AND ( (type=?3) or (0 == ?3) )"
666 " ORDER BY KEY DESC LIMIT ?4)",
637 &plugin->get_closest_stmt))) 667 &plugin->get_closest_stmt)))
638 { 668 {
639 LOG_SQLITE (plugin->dbh, 669 LOG_SQLITE (plugin->dbh,
diff --git a/src/datacache/plugin_datacache_template.c b/src/datacache/plugin_datacache_template.c
index 231413ce9..2f7b41dbe 100644
--- a/src/datacache/plugin_datacache_template.c
+++ b/src/datacache/plugin_datacache_template.c
@@ -116,6 +116,7 @@ template_plugin_del (void *cls)
116 * 116 *
117 * @param cls closure (internal context for the plugin) 117 * @param cls closure (internal context for the plugin)
118 * @param key area of the keyspace to look into 118 * @param key area of the keyspace to look into
119 * @param type desired block type for the replies
119 * @param num_results number of results that should be returned to @a iter 120 * @param num_results number of results that should be returned to @a iter
120 * @param iter maybe NULL (to just count) 121 * @param iter maybe NULL (to just count)
121 * @param iter_cls closure for @a iter 122 * @param iter_cls closure for @a iter
@@ -124,6 +125,7 @@ template_plugin_del (void *cls)
124static unsigned int 125static unsigned int
125template_plugin_get_closest (void *cls, 126template_plugin_get_closest (void *cls,
126 const struct GNUNET_HashCode *key, 127 const struct GNUNET_HashCode *key,
128 enum GNUNET_BLOCK_Type type,
127 unsigned int num_results, 129 unsigned int num_results,
128 GNUNET_DATACACHE_Iterator iter, 130 GNUNET_DATACACHE_Iterator iter,
129 void *iter_cls) 131 void *iter_cls)