diff options
author | Christian Grothoff <christian@grothoff.org> | 2018-06-03 15:07:09 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2018-06-03 15:07:09 +0200 |
commit | 18a1d4ec5085690d16345a52f3e75d059c834195 (patch) | |
tree | eddcbab91006a80cfa604c802bb1fccdaae1103d /src/datacache/plugin_datacache_sqlite.c | |
parent | 2e619a454b7c78aa5f592debd6c8a31e7d7c1143 (diff) | |
download | gnunet-18a1d4ec5085690d16345a52f3e75d059c834195.tar.gz gnunet-18a1d4ec5085690d16345a52f3e75d059c834195.zip |
proper datacache expiration by proximity first
Diffstat (limited to 'src/datacache/plugin_datacache_sqlite.c')
-rw-r--r-- | src/datacache/plugin_datacache_sqlite.c | 84 |
1 files changed, 52 insertions, 32 deletions
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, | |||
162 | static ssize_t | 167 | static ssize_t |
163 | sqlite_plugin_put (void *cls, | 168 | sqlite_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); |