aboutsummaryrefslogtreecommitdiff
path: root/src/datacache
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2018-06-03 15:07:09 +0200
committerChristian Grothoff <christian@grothoff.org>2018-06-03 15:07:09 +0200
commit18a1d4ec5085690d16345a52f3e75d059c834195 (patch)
treeeddcbab91006a80cfa604c802bb1fccdaae1103d /src/datacache
parent2e619a454b7c78aa5f592debd6c8a31e7d7c1143 (diff)
downloadgnunet-18a1d4ec5085690d16345a52f3e75d059c834195.tar.gz
gnunet-18a1d4ec5085690d16345a52f3e75d059c834195.zip
proper datacache expiration by proximity first
Diffstat (limited to 'src/datacache')
-rw-r--r--src/datacache/datacache.c6
-rw-r--r--src/datacache/plugin_datacache_heap.c90
-rw-r--r--src/datacache/plugin_datacache_sqlite.c84
-rw-r--r--src/datacache/plugin_datacache_template.c4
4 files changed, 93 insertions, 91 deletions
diff --git a/src/datacache/datacache.c b/src/datacache/datacache.c
index 18a2ed228..7c0a975da 100644
--- a/src/datacache/datacache.c
+++ b/src/datacache/datacache.c
@@ -260,7 +260,7 @@ GNUNET_DATACACHE_destroy (struct GNUNET_DATACACHE_Handle *h)
260 * 260 *
261 * @param h handle to the datacache 261 * @param h handle to the datacache
262 * @param key key to store data under 262 * @param key key to store data under
263 * @param am_closest are we the closest peer? 263 * @param xor_distance distance of @a key to our PID
264 * @param data_size number of bytes in @a data 264 * @param data_size number of bytes in @a data
265 * @param data data to store 265 * @param data data to store
266 * @param type type of the value 266 * @param type type of the value
@@ -272,7 +272,7 @@ GNUNET_DATACACHE_destroy (struct GNUNET_DATACACHE_Handle *h)
272int 272int
273GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h, 273GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h,
274 const struct GNUNET_HashCode *key, 274 const struct GNUNET_HashCode *key,
275 int am_closest, 275 uint32_t xor_distance,
276 size_t data_size, 276 size_t data_size,
277 const char *data, 277 const char *data,
278 enum GNUNET_BLOCK_Type type, 278 enum GNUNET_BLOCK_Type type,
@@ -284,7 +284,7 @@ GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h,
284 284
285 used = h->api->put (h->api->cls, 285 used = h->api->put (h->api->cls,
286 key, 286 key,
287 am_closest, 287 xor_distance,
288 data_size, 288 data_size,
289 data, 289 data,
290 type, 290 type,
diff --git a/src/datacache/plugin_datacache_heap.c b/src/datacache/plugin_datacache_heap.c
index c32edf8e2..ad5e7834d 100644
--- a/src/datacache/plugin_datacache_heap.c
+++ b/src/datacache/plugin_datacache_heap.c
@@ -31,7 +31,7 @@
31 31
32#define LOG_STRERROR_FILE(kind,op,fn) GNUNET_log_from_strerror_file (kind, "datacache-heap", op, fn) 32#define LOG_STRERROR_FILE(kind,op,fn) GNUNET_log_from_strerror_file (kind, "datacache-heap", op, fn)
33 33
34 34#define NUM_HEAPS 24
35 35
36/** 36/**
37 * Context for all functions in this plugin. 37 * Context for all functions in this plugin.
@@ -49,14 +49,9 @@ struct Plugin
49 struct GNUNET_CONTAINER_MultiHashMap *map; 49 struct GNUNET_CONTAINER_MultiHashMap *map;
50 50
51 /** 51 /**
52 * Heap for expirations. 52 * Heaps sorted by distance.
53 */ 53 */
54 struct GNUNET_CONTAINER_Heap *heap; 54 struct GNUNET_CONTAINER_Heap *heaps[NUM_HEAPS];
55
56 /**
57 * Heap from the plugin for "closest" values.
58 */
59 struct GNUNET_CONTAINER_Heap *cheap;
60 55
61}; 56};
62 57
@@ -97,9 +92,9 @@ struct Value
97 unsigned int path_info_len; 92 unsigned int path_info_len;
98 93
99 /** 94 /**
100 * Am I the closest peer? Determines which heap we are in! 95 * How close is the hash to us? Determines which heap we are in!
101 */ 96 */
102 int am_closest; 97 uint32_t distance;
103 98
104 /** 99 /**
105 * Type of the block. 100 * Type of the block.
@@ -128,16 +123,6 @@ struct PutContext
128 const char *data; 123 const char *data;
129 124
130 /** 125 /**
131 * Heap from the plugin for "closest" values.
132 */
133 struct GNUNET_CONTAINER_Heap *cheap;
134
135 /**
136 * Heap from the plugin.
137 */
138 struct GNUNET_CONTAINER_Heap *heap;
139
140 /**
141 * Path information. 126 * Path information.
142 */ 127 */
143 const struct GNUNET_PeerIdentity *path_info; 128 const struct GNUNET_PeerIdentity *path_info;
@@ -195,8 +180,8 @@ put_cb (void *cls,
195 val->path_info_len, 180 val->path_info_len,
196 put_ctx->path_info_len); 181 put_ctx->path_info_len);
197 GNUNET_memcpy (val->path_info, 182 GNUNET_memcpy (val->path_info,
198 put_ctx->path_info, 183 put_ctx->path_info,
199 put_ctx->path_info_len * sizeof (struct GNUNET_PeerIdentity)); 184 put_ctx->path_info_len * sizeof (struct GNUNET_PeerIdentity));
200 GNUNET_CONTAINER_heap_update_cost (val->hn, 185 GNUNET_CONTAINER_heap_update_cost (val->hn,
201 val->discard_time.abs_value_us); 186 val->discard_time.abs_value_us);
202 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 187 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -216,7 +201,7 @@ put_cb (void *cls,
216 * 201 *
217 * @param cls closure (our `struct Plugin`) 202 * @param cls closure (our `struct Plugin`)
218 * @param key key to store data under 203 * @param key key to store data under
219 * @param am_closest are we the closest peer? 204 * @param xor_distance how close is @a key to our PID?
220 * @param size number of bytes in @a data 205 * @param size number of bytes in @a data
221 * @param data data to store 206 * @param data data to store
222 * @param type type of the value 207 * @param type type of the value
@@ -228,7 +213,7 @@ put_cb (void *cls,
228static ssize_t 213static ssize_t
229heap_plugin_put (void *cls, 214heap_plugin_put (void *cls,
230 const struct GNUNET_HashCode *key, 215 const struct GNUNET_HashCode *key,
231 int am_closest, 216 uint32_t xor_distance,
232 size_t size, 217 size_t size,
233 const char *data, 218 const char *data,
234 enum GNUNET_BLOCK_Type type, 219 enum GNUNET_BLOCK_Type type,
@@ -241,8 +226,6 @@ heap_plugin_put (void *cls,
241 struct PutContext put_ctx; 226 struct PutContext put_ctx;
242 227
243 put_ctx.found = GNUNET_NO; 228 put_ctx.found = GNUNET_NO;
244 put_ctx.heap = plugin->heap;
245 put_ctx.cheap = plugin->cheap;
246 put_ctx.data = data; 229 put_ctx.data = data;
247 put_ctx.size = size; 230 put_ctx.size = size;
248 put_ctx.path_info = path_info; 231 put_ctx.path_info = path_info;
@@ -256,12 +239,17 @@ heap_plugin_put (void *cls,
256 if (GNUNET_YES == put_ctx.found) 239 if (GNUNET_YES == put_ctx.found)
257 return 0; 240 return 0;
258 val = GNUNET_malloc (sizeof (struct Value) + size); 241 val = GNUNET_malloc (sizeof (struct Value) + size);
259 GNUNET_memcpy (&val[1], data, size); 242 GNUNET_memcpy (&val[1],
243 data,
244 size);
260 val->key = *key; 245 val->key = *key;
261 val->type = type; 246 val->type = type;
262 val->discard_time = discard_time; 247 val->discard_time = discard_time;
263 val->size = size; 248 val->size = size;
264 val->am_closest = am_closest; 249 if (xor_distance >= NUM_HEAPS)
250 val->distance = NUM_HEAPS - 1;
251 else
252 val->distance = xor_distance;
265 GNUNET_array_grow (val->path_info, 253 GNUNET_array_grow (val->path_info,
266 val->path_info_len, 254 val->path_info_len,
267 path_info_len); 255 path_info_len);
@@ -272,9 +260,7 @@ heap_plugin_put (void *cls,
272 &val->key, 260 &val->key,
273 val, 261 val,
274 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 262 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
275 val->hn = GNUNET_CONTAINER_heap_insert (am_closest 263 val->hn = GNUNET_CONTAINER_heap_insert (plugin->heaps[val->distance],
276 ? plugin->cheap
277 : plugin->heap,
278 val, 264 val,
279 val->discard_time.abs_value_us); 265 val->discard_time.abs_value_us);
280 return size + OVERHEAD; 266 return size + OVERHEAD;
@@ -392,9 +378,12 @@ heap_plugin_del (void *cls)
392 struct Plugin *plugin = cls; 378 struct Plugin *plugin = cls;
393 struct Value *val; 379 struct Value *val;
394 380
395 val = GNUNET_CONTAINER_heap_remove_root (plugin->heap); 381 for (unsigned int i=0;i<NUM_HEAPS;i++)
396 if (NULL == val) 382 {
397 val = GNUNET_CONTAINER_heap_remove_root (plugin->cheap); 383 val = GNUNET_CONTAINER_heap_remove_root (plugin->heaps[i]);
384 if (NULL != val)
385 break;
386 }
398 if (NULL == val) 387 if (NULL == val)
399 return GNUNET_SYSERR; 388 return GNUNET_SYSERR;
400 GNUNET_assert (GNUNET_YES == 389 GNUNET_assert (GNUNET_YES ==
@@ -547,8 +536,8 @@ libgnunet_plugin_datacache_heap_init (void *cls)
547 plugin = GNUNET_new (struct Plugin); 536 plugin = GNUNET_new (struct Plugin);
548 plugin->map = GNUNET_CONTAINER_multihashmap_create (1024, /* FIXME: base on quota! */ 537 plugin->map = GNUNET_CONTAINER_multihashmap_create (1024, /* FIXME: base on quota! */
549 GNUNET_YES); 538 GNUNET_YES);
550 plugin->heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); 539 for (unsigned int i=0;i<NUM_HEAPS;i++)
551 plugin->cheap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); 540 plugin->heaps[i] = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
552 plugin->env = env; 541 plugin->env = env;
553 api = GNUNET_new (struct GNUNET_DATACACHE_PluginFunctions); 542 api = GNUNET_new (struct GNUNET_DATACACHE_PluginFunctions);
554 api->cls = plugin; 543 api->cls = plugin;
@@ -576,26 +565,19 @@ libgnunet_plugin_datacache_heap_done (void *cls)
576 struct Plugin *plugin = api->cls; 565 struct Plugin *plugin = api->cls;
577 struct Value *val; 566 struct Value *val;
578 567
579 while (NULL != (val = GNUNET_CONTAINER_heap_remove_root (plugin->heap))) 568 for (unsigned int i=0;i<NUM_HEAPS;i++)
580 { 569 {
581 GNUNET_assert (GNUNET_YES == 570 while (NULL != (val = GNUNET_CONTAINER_heap_remove_root (plugin->heaps[i])))
582 GNUNET_CONTAINER_multihashmap_remove (plugin->map, 571 {
583 &val->key, 572 GNUNET_assert (GNUNET_YES ==
584 val)); 573 GNUNET_CONTAINER_multihashmap_remove (plugin->map,
585 GNUNET_free_non_null (val->path_info); 574 &val->key,
586 GNUNET_free (val); 575 val));
587 } 576 GNUNET_free_non_null (val->path_info);
588 while (NULL != (val = GNUNET_CONTAINER_heap_remove_root (plugin->cheap))) 577 GNUNET_free (val);
589 { 578 }
590 GNUNET_assert (GNUNET_YES == 579 GNUNET_CONTAINER_heap_destroy (plugin->heaps[i]);
591 GNUNET_CONTAINER_multihashmap_remove (plugin->map,
592 &val->key,
593 val));
594 GNUNET_free_non_null (val->path_info);
595 GNUNET_free (val);
596 } 580 }
597 GNUNET_CONTAINER_heap_destroy (plugin->heap);
598 GNUNET_CONTAINER_heap_destroy (plugin->cheap);
599 GNUNET_CONTAINER_multihashmap_destroy (plugin->map); 581 GNUNET_CONTAINER_multihashmap_destroy (plugin->map);
600 GNUNET_free (plugin); 582 GNUNET_free (plugin);
601 GNUNET_free (api); 583 GNUNET_free (api);
diff --git a/src/datacache/plugin_datacache_sqlite.c b/src/datacache/plugin_datacache_sqlite.c
index 455dcab0b..c4adb34fd 100644
--- a/src/datacache/plugin_datacache_sqlite.c
+++ b/src/datacache/plugin_datacache_sqlite.c
@@ -83,6 +83,11 @@ struct Plugin
83 /** 83 /**
84 * Prepared statement for #sqlite_plugin_del. 84 * Prepared statement for #sqlite_plugin_del.
85 */ 85 */
86 sqlite3_stmt *del_expired_stmt;
87
88 /**
89 * Prepared statement for #sqlite_plugin_del.
90 */
86 sqlite3_stmt *del_stmt; 91 sqlite3_stmt *del_stmt;
87 92
88 /** 93 /**
@@ -150,7 +155,7 @@ sq_prepare (sqlite3 *dbh,
150 * 155 *
151 * @param cls closure (our `struct Plugin`) 156 * @param cls closure (our `struct Plugin`)
152 * @param key key to store @a data under 157 * @param key key to store @a data under
153 * @param am_closest are we the closest peer? 158 * @param xor_distance how close is @a key to our PID?
154 * @param size number of bytes in @a data 159 * @param size number of bytes in @a data
155 * @param data data to store 160 * @param data data to store
156 * @param type type of the value 161 * @param type type of the value
@@ -162,7 +167,7 @@ sq_prepare (sqlite3 *dbh,
162static ssize_t 167static ssize_t
163sqlite_plugin_put (void *cls, 168sqlite_plugin_put (void *cls,
164 const struct GNUNET_HashCode *key, 169 const struct GNUNET_HashCode *key,
165 int am_closest, 170 uint32_t xor_distance,
166 size_t size, 171 size_t size,
167 const char *data, 172 const char *data,
168 enum GNUNET_BLOCK_Type type, 173 enum GNUNET_BLOCK_Type type,
@@ -172,12 +177,11 @@ sqlite_plugin_put (void *cls,
172{ 177{
173 struct Plugin *plugin = cls; 178 struct Plugin *plugin = cls;
174 uint32_t type32 = type; 179 uint32_t type32 = type;
175 uint32_t prox = am_closest;
176 struct GNUNET_SQ_QueryParam params[] = { 180 struct GNUNET_SQ_QueryParam params[] = {
177 GNUNET_SQ_query_param_uint32 (&type32), 181 GNUNET_SQ_query_param_uint32 (&type32),
178 GNUNET_SQ_query_param_absolute_time (&discard_time), 182 GNUNET_SQ_query_param_absolute_time (&discard_time),
179 GNUNET_SQ_query_param_auto_from_type (key), 183 GNUNET_SQ_query_param_auto_from_type (key),
180 GNUNET_SQ_query_param_uint32 (&prox), 184 GNUNET_SQ_query_param_uint32 (&xor_distance),
181 GNUNET_SQ_query_param_fixed_size (data, size), 185 GNUNET_SQ_query_param_fixed_size (data, size),
182 GNUNET_SQ_query_param_fixed_size (path_info, 186 GNUNET_SQ_query_param_fixed_size (path_info,
183 path_info_len * sizeof (struct GNUNET_PeerIdentity)), 187 path_info_len * sizeof (struct GNUNET_PeerIdentity)),
@@ -390,8 +394,8 @@ sqlite_plugin_del (void *cls)
390 uint64_t rowid; 394 uint64_t rowid;
391 void *data; 395 void *data;
392 size_t dsize; 396 size_t dsize;
393 uint32_t prox;
394 struct GNUNET_HashCode hc; 397 struct GNUNET_HashCode hc;
398 struct GNUNET_TIME_Absolute now;
395 struct GNUNET_SQ_ResultSpec rs[] = { 399 struct GNUNET_SQ_ResultSpec rs[] = {
396 GNUNET_SQ_result_spec_uint64 (&rowid), 400 GNUNET_SQ_result_spec_uint64 (&rowid),
397 GNUNET_SQ_result_spec_auto_from_type (&hc), 401 GNUNET_SQ_result_spec_auto_from_type (&hc),
@@ -403,54 +407,61 @@ sqlite_plugin_del (void *cls)
403 GNUNET_SQ_query_param_uint64 (&rowid), 407 GNUNET_SQ_query_param_uint64 (&rowid),
404 GNUNET_SQ_query_param_end 408 GNUNET_SQ_query_param_end
405 }; 409 };
406 struct GNUNET_SQ_QueryParam prox_params[] = { 410 struct GNUNET_SQ_QueryParam time_params[] = {
407 GNUNET_SQ_query_param_uint32 (&prox), 411 GNUNET_SQ_query_param_absolute_time (&now),
408 GNUNET_SQ_query_param_end 412 GNUNET_SQ_query_param_end
409 }; 413 };
410 414
411 LOG (GNUNET_ERROR_TYPE_DEBUG, 415 LOG (GNUNET_ERROR_TYPE_DEBUG,
412 "Processing DEL\n"); 416 "Processing DEL\n");
413 prox = GNUNET_NO; 417 now = GNUNET_TIME_absolute_get ();
414 again:
415 if (GNUNET_OK != 418 if (GNUNET_OK !=
416 GNUNET_SQ_bind (plugin->del_select_stmt, 419 GNUNET_SQ_bind (plugin->del_expired_stmt,
417 prox_params)) 420 time_params))
418 { 421 {
419 LOG_SQLITE (plugin->dbh, 422 LOG_SQLITE (plugin->dbh,
420 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 423 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
421 "sqlite3_bind"); 424 "sqlite3_bind");
422 GNUNET_SQ_reset (plugin->dbh, 425 GNUNET_SQ_reset (plugin->dbh,
423 plugin->del_stmt); 426 plugin->del_expired_stmt);
424 return GNUNET_SYSERR; 427 return GNUNET_SYSERR;
425 } 428 }
426 if (SQLITE_ROW != 429 if (SQLITE_ROW !=
427 sqlite3_step (plugin->del_select_stmt)) 430 sqlite3_step (plugin->del_expired_stmt))
428 { 431 {
429 LOG_SQLITE (plugin->dbh, 432 LOG_SQLITE (plugin->dbh,
430 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 433 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
431 "sqlite3_step"); 434 "sqlite3_step");
432 GNUNET_SQ_reset (plugin->dbh, 435 GNUNET_SQ_reset (plugin->dbh,
433 plugin->del_select_stmt); 436 plugin->del_expired_stmt);
434 if (GNUNET_NO == prox)
435 {
436 prox = GNUNET_YES;
437 goto again;
438 }
439 return GNUNET_SYSERR; 437 return GNUNET_SYSERR;
440 } 438 }
441 if (GNUNET_OK != 439 if (GNUNET_OK !=
442 GNUNET_SQ_extract_result (plugin->del_select_stmt, 440 GNUNET_SQ_extract_result (plugin->del_expired_stmt,
443 rs)) 441 rs))
444 { 442 {
445 GNUNET_SQ_reset (plugin->dbh, 443 GNUNET_SQ_reset (plugin->dbh,
446 plugin->del_select_stmt); 444 plugin->del_expired_stmt);
447 if (GNUNET_NO == prox) 445
446 if (SQLITE_ROW !=
447 sqlite3_step (plugin->del_select_stmt))
448 { 448 {
449 prox = GNUNET_YES; 449 LOG_SQLITE (plugin->dbh,
450 goto again; 450 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
451 "sqlite3_step");
452 GNUNET_SQ_reset (plugin->dbh,
453 plugin->del_select_stmt);
454 return GNUNET_SYSERR;
455 }
456 if (GNUNET_OK !=
457 GNUNET_SQ_extract_result (plugin->del_select_stmt,
458 rs))
459 {
460 GNUNET_SQ_reset (plugin->dbh,
461 plugin->del_select_stmt);
462 GNUNET_break (0);
463 return GNUNET_SYSERR;
451 } 464 }
452 GNUNET_break (0);
453 return GNUNET_SYSERR;
454 } 465 }
455 GNUNET_SQ_cleanup_result (rs); 466 GNUNET_SQ_cleanup_result (rs);
456 GNUNET_SQ_reset (plugin->dbh, 467 GNUNET_SQ_reset (plugin->dbh,
@@ -741,14 +752,15 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
741 SQLITE3_EXEC (dbh, "PRAGMA sqlite_temp_store=3"); 752 SQLITE3_EXEC (dbh, "PRAGMA sqlite_temp_store=3");
742 753
743 SQLITE3_EXEC (dbh, 754 SQLITE3_EXEC (dbh,
744 "CREATE TABLE ds091 (" " type INTEGER NOT NULL DEFAULT 0," 755 "CREATE TABLE ds091 ("
756 " type INTEGER NOT NULL DEFAULT 0,"
745 " expire INTEGER NOT NULL," 757 " expire INTEGER NOT NULL,"
746 " key BLOB NOT NULL DEFAULT ''," 758 " key BLOB NOT NULL DEFAULT '',"
747 " prox INTEGER NOT NULL," 759 " prox INTEGER NOT NULL,"
748 " value BLOB NOT NULL," 760 " value BLOB NOT NULL,"
749 " path BLOB DEFAULT '')"); 761 " path BLOB DEFAULT '')");
750 SQLITE3_EXEC (dbh, "CREATE INDEX idx_hashidx ON ds090 (key,type,expire)"); 762 SQLITE3_EXEC (dbh, "CREATE INDEX idx_hashidx ON ds091 (key,type,expire)");
751 SQLITE3_EXEC (dbh, "CREATE INDEX idx_expire ON ds090 (prox,expire)"); 763 SQLITE3_EXEC (dbh, "CREATE INDEX idx_expire ON ds091 (prox,expire)");
752 plugin = GNUNET_new (struct Plugin); 764 plugin = GNUNET_new (struct Plugin);
753 plugin->env = env; 765 plugin->env = env;
754 plugin->dbh = dbh; 766 plugin->dbh = dbh;
@@ -766,12 +778,19 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
766 &plugin->get_count_stmt)) || 778 &plugin->get_count_stmt)) ||
767 (SQLITE_OK != 779 (SQLITE_OK !=
768 sq_prepare (plugin->dbh, 780 sq_prepare (plugin->dbh,
769 "SELECT value,expire,path FROM ds091 " 781 "SELECT value,expire,path FROM ds091"
770 "WHERE key=? AND type=? AND expire >= ? LIMIT 1 OFFSET ?", 782 " WHERE key=? AND type=? AND expire >= ? LIMIT 1 OFFSET ?",
771 &plugin->get_stmt)) || 783 &plugin->get_stmt)) ||
772 (SQLITE_OK != 784 (SQLITE_OK !=
773 sq_prepare (plugin->dbh, 785 sq_prepare (plugin->dbh,
774 "SELECT _ROWID_,key,value FROM ds091 WHERE prox=? ORDER BY expire ASC LIMIT 1", 786 "SELECT _ROWID_,key,value FROM ds091"
787 " WHERE expire < ?"
788 " ORDER BY expire ASC LIMIT 1",
789 &plugin->del_expired_stmt)) ||
790 (SQLITE_OK !=
791 sq_prepare (plugin->dbh,
792 "SELECT _ROWID_,key,value FROM ds091"
793 " ORDER BY prox ASC, expire ASC LIMIT 1",
775 &plugin->del_select_stmt)) || 794 &plugin->del_select_stmt)) ||
776 (SQLITE_OK != 795 (SQLITE_OK !=
777 sq_prepare (plugin->dbh, 796 sq_prepare (plugin->dbh,
@@ -840,6 +859,7 @@ libgnunet_plugin_datacache_sqlite_done (void *cls)
840 sqlite3_finalize (plugin->get_count_stmt); 859 sqlite3_finalize (plugin->get_count_stmt);
841 sqlite3_finalize (plugin->get_stmt); 860 sqlite3_finalize (plugin->get_stmt);
842 sqlite3_finalize (plugin->del_select_stmt); 861 sqlite3_finalize (plugin->del_select_stmt);
862 sqlite3_finalize (plugin->del_expired_stmt);
843 sqlite3_finalize (plugin->del_stmt); 863 sqlite3_finalize (plugin->del_stmt);
844 sqlite3_finalize (plugin->get_random_stmt); 864 sqlite3_finalize (plugin->get_random_stmt);
845 sqlite3_finalize (plugin->get_closest_stmt); 865 sqlite3_finalize (plugin->get_closest_stmt);
diff --git a/src/datacache/plugin_datacache_template.c b/src/datacache/plugin_datacache_template.c
index 28bcbcd26..1064d3125 100644
--- a/src/datacache/plugin_datacache_template.c
+++ b/src/datacache/plugin_datacache_template.c
@@ -45,7 +45,7 @@ struct Plugin
45 * 45 *
46 * @param cls closure (our `struct Plugin`) 46 * @param cls closure (our `struct Plugin`)
47 * @param key key to store @a data under 47 * @param key key to store @a data under
48 * @param am_closest are we the closest peer? 48 * @param xor_distance distance of @a key to our PID
49 * @param size number of bytes in @a data 49 * @param size number of bytes in @a data
50 * @param data data to store 50 * @param data data to store
51 * @param type type of the value 51 * @param type type of the value
@@ -57,7 +57,7 @@ struct Plugin
57static ssize_t 57static ssize_t
58template_plugin_put (void *cls, 58template_plugin_put (void *cls,
59 const struct GNUNET_HashCode *key, 59 const struct GNUNET_HashCode *key,
60 int am_closest, 60 uint32_t xor_distance,
61 size_t size, 61 size_t size,
62 const char *data, 62 const char *data,
63 enum GNUNET_BLOCK_Type type, 63 enum GNUNET_BLOCK_Type type,