aboutsummaryrefslogtreecommitdiff
path: root/src/datacache/plugin_datacache_sqlite.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/datacache/plugin_datacache_sqlite.c')
-rw-r--r--src/datacache/plugin_datacache_sqlite.c112
1 files changed, 77 insertions, 35 deletions
diff --git a/src/datacache/plugin_datacache_sqlite.c b/src/datacache/plugin_datacache_sqlite.c
index 15438b29b..4684e514c 100644
--- a/src/datacache/plugin_datacache_sqlite.c
+++ b/src/datacache/plugin_datacache_sqlite.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet 2 This file is part of GNUnet
3 Copyright (C) 2006, 2009, 2015 GNUnet e.V. 3 Copyright (C) 2006, 2009, 2015 GNUnet e.V.
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 it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
@@ -38,7 +36,7 @@
38 * How much overhead do we assume per entry in the 36 * How much overhead do we assume per entry in the
39 * datacache? 37 * datacache?
40 */ 38 */
41#define OVERHEAD (sizeof(struct GNUNET_HashCode) + 32) 39#define OVERHEAD (sizeof(struct GNUNET_HashCode) + 36)
42 40
43/** 41/**
44 * Context for all functions in this plugin. 42 * Context for all functions in this plugin.
@@ -83,6 +81,11 @@ struct Plugin
83 /** 81 /**
84 * Prepared statement for #sqlite_plugin_del. 82 * Prepared statement for #sqlite_plugin_del.
85 */ 83 */
84 sqlite3_stmt *del_expired_stmt;
85
86 /**
87 * Prepared statement for #sqlite_plugin_del.
88 */
86 sqlite3_stmt *del_stmt; 89 sqlite3_stmt *del_stmt;
87 90
88 /** 91 /**
@@ -150,6 +153,7 @@ sq_prepare (sqlite3 *dbh,
150 * 153 *
151 * @param cls closure (our `struct Plugin`) 154 * @param cls closure (our `struct Plugin`)
152 * @param key key to store @a data under 155 * @param key key to store @a data under
156 * @param xor_distance how close is @a key to our PID?
153 * @param size number of bytes in @a data 157 * @param size number of bytes in @a data
154 * @param data data to store 158 * @param data data to store
155 * @param type type of the value 159 * @param type type of the value
@@ -161,6 +165,7 @@ sq_prepare (sqlite3 *dbh,
161static ssize_t 165static ssize_t
162sqlite_plugin_put (void *cls, 166sqlite_plugin_put (void *cls,
163 const struct GNUNET_HashCode *key, 167 const struct GNUNET_HashCode *key,
168 uint32_t xor_distance,
164 size_t size, 169 size_t size,
165 const char *data, 170 const char *data,
166 enum GNUNET_BLOCK_Type type, 171 enum GNUNET_BLOCK_Type type,
@@ -174,6 +179,7 @@ sqlite_plugin_put (void *cls,
174 GNUNET_SQ_query_param_uint32 (&type32), 179 GNUNET_SQ_query_param_uint32 (&type32),
175 GNUNET_SQ_query_param_absolute_time (&discard_time), 180 GNUNET_SQ_query_param_absolute_time (&discard_time),
176 GNUNET_SQ_query_param_auto_from_type (key), 181 GNUNET_SQ_query_param_auto_from_type (key),
182 GNUNET_SQ_query_param_uint32 (&xor_distance),
177 GNUNET_SQ_query_param_fixed_size (data, size), 183 GNUNET_SQ_query_param_fixed_size (data, size),
178 GNUNET_SQ_query_param_fixed_size (path_info, 184 GNUNET_SQ_query_param_fixed_size (path_info,
179 path_info_len * sizeof (struct GNUNET_PeerIdentity)), 185 path_info_len * sizeof (struct GNUNET_PeerIdentity)),
@@ -387,6 +393,7 @@ sqlite_plugin_del (void *cls)
387 void *data; 393 void *data;
388 size_t dsize; 394 size_t dsize;
389 struct GNUNET_HashCode hc; 395 struct GNUNET_HashCode hc;
396 struct GNUNET_TIME_Absolute now;
390 struct GNUNET_SQ_ResultSpec rs[] = { 397 struct GNUNET_SQ_ResultSpec rs[] = {
391 GNUNET_SQ_result_spec_uint64 (&rowid), 398 GNUNET_SQ_result_spec_uint64 (&rowid),
392 GNUNET_SQ_result_spec_auto_from_type (&hc), 399 GNUNET_SQ_result_spec_auto_from_type (&hc),
@@ -398,27 +405,52 @@ sqlite_plugin_del (void *cls)
398 GNUNET_SQ_query_param_uint64 (&rowid), 405 GNUNET_SQ_query_param_uint64 (&rowid),
399 GNUNET_SQ_query_param_end 406 GNUNET_SQ_query_param_end
400 }; 407 };
408 struct GNUNET_SQ_QueryParam time_params[] = {
409 GNUNET_SQ_query_param_absolute_time (&now),
410 GNUNET_SQ_query_param_end
411 };
401 412
402 LOG (GNUNET_ERROR_TYPE_DEBUG, 413 LOG (GNUNET_ERROR_TYPE_DEBUG,
403 "Processing DEL\n"); 414 "Processing DEL\n");
404 if (SQLITE_ROW != 415 now = GNUNET_TIME_absolute_get ();
405 sqlite3_step (plugin->del_select_stmt)) 416 if (GNUNET_OK !=
417 GNUNET_SQ_bind (plugin->del_expired_stmt,
418 time_params))
406 { 419 {
407 LOG_SQLITE (plugin->dbh, 420 LOG_SQLITE (plugin->dbh,
408 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 421 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
409 "sqlite3_step"); 422 "sqlite3_bind");
410 GNUNET_SQ_reset (plugin->dbh, 423 GNUNET_SQ_reset (plugin->dbh,
411 plugin->del_select_stmt); 424 plugin->del_expired_stmt);
412 return GNUNET_SYSERR; 425 return GNUNET_SYSERR;
413 } 426 }
414 if (GNUNET_OK != 427 if ( (SQLITE_ROW !=
415 GNUNET_SQ_extract_result (plugin->del_select_stmt, 428 sqlite3_step (plugin->del_expired_stmt)) ||
416 rs)) 429 (GNUNET_OK !=
430 GNUNET_SQ_extract_result (plugin->del_expired_stmt,
431 rs)) )
417 { 432 {
418 GNUNET_break (0);
419 GNUNET_SQ_reset (plugin->dbh, 433 GNUNET_SQ_reset (plugin->dbh,
420 plugin->del_select_stmt); 434 plugin->del_expired_stmt);
421 return GNUNET_SYSERR; 435 if (SQLITE_ROW !=
436 sqlite3_step (plugin->del_select_stmt))
437 {
438 LOG_SQLITE (plugin->dbh,
439 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
440 "sqlite3_step");
441 GNUNET_SQ_reset (plugin->dbh,
442 plugin->del_select_stmt);
443 return GNUNET_SYSERR;
444 }
445 if (GNUNET_OK !=
446 GNUNET_SQ_extract_result (plugin->del_select_stmt,
447 rs))
448 {
449 GNUNET_SQ_reset (plugin->dbh,
450 plugin->del_select_stmt);
451 GNUNET_break (0);
452 return GNUNET_SYSERR;
453 }
422 } 454 }
423 GNUNET_SQ_cleanup_result (rs); 455 GNUNET_SQ_cleanup_result (rs);
424 GNUNET_SQ_reset (plugin->dbh, 456 GNUNET_SQ_reset (plugin->dbh,
@@ -709,13 +741,15 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
709 SQLITE3_EXEC (dbh, "PRAGMA sqlite_temp_store=3"); 741 SQLITE3_EXEC (dbh, "PRAGMA sqlite_temp_store=3");
710 742
711 SQLITE3_EXEC (dbh, 743 SQLITE3_EXEC (dbh,
712 "CREATE TABLE ds090 (" " type INTEGER NOT NULL DEFAULT 0," 744 "CREATE TABLE ds091 ("
713 " expire INTEGER NOT NULL DEFAULT 0," 745 " type INTEGER NOT NULL DEFAULT 0,"
746 " expire INTEGER NOT NULL,"
714 " key BLOB NOT NULL DEFAULT ''," 747 " key BLOB NOT NULL DEFAULT '',"
715 " value BLOB NOT NULL DEFAULT ''," 748 " prox INTEGER NOT NULL,"
749 " value BLOB NOT NULL,"
716 " path BLOB DEFAULT '')"); 750 " path BLOB DEFAULT '')");
717 SQLITE3_EXEC (dbh, "CREATE INDEX idx_hashidx ON ds090 (key,type,expire)"); 751 SQLITE3_EXEC (dbh, "CREATE INDEX idx_hashidx ON ds091 (key,type,expire)");
718 SQLITE3_EXEC (dbh, "CREATE INDEX idx_expire ON ds090 (expire)"); 752 SQLITE3_EXEC (dbh, "CREATE INDEX idx_expire ON ds091 (prox,expire)");
719 plugin = GNUNET_new (struct Plugin); 753 plugin = GNUNET_new (struct Plugin);
720 plugin->env = env; 754 plugin->env = env;
721 plugin->dbh = dbh; 755 plugin->dbh = dbh;
@@ -723,35 +757,42 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
723 757
724 if ( (SQLITE_OK != 758 if ( (SQLITE_OK !=
725 sq_prepare (plugin->dbh, 759 sq_prepare (plugin->dbh,
726 "INSERT INTO ds090 (type, expire, key, value, path) " 760 "INSERT INTO ds091 (type, expire, key, prox, value, path) "
727 "VALUES (?, ?, ?, ?, ?)", 761 "VALUES (?, ?, ?, ?, ?, ?)",
728 &plugin->insert_stmt)) || 762 &plugin->insert_stmt)) ||
729 (SQLITE_OK != 763 (SQLITE_OK !=
730 sq_prepare (plugin->dbh, 764 sq_prepare (plugin->dbh,
731 "SELECT count(*) FROM ds090 " 765 "SELECT count(*) FROM ds091 "
732 "WHERE key=? AND type=? AND expire >= ?", 766 "WHERE key=? AND type=? AND expire >= ?",
733 &plugin->get_count_stmt)) || 767 &plugin->get_count_stmt)) ||
734 (SQLITE_OK != 768 (SQLITE_OK !=
735 sq_prepare (plugin->dbh, 769 sq_prepare (plugin->dbh,
736 "SELECT value,expire,path FROM ds090 " 770 "SELECT value,expire,path FROM ds091"
737 "WHERE key=? AND type=? AND expire >= ? LIMIT 1 OFFSET ?", 771 " WHERE key=? AND type=? AND expire >= ? LIMIT 1 OFFSET ?",
738 &plugin->get_stmt)) || 772 &plugin->get_stmt)) ||
739 (SQLITE_OK != 773 (SQLITE_OK !=
740 sq_prepare (plugin->dbh, 774 sq_prepare (plugin->dbh,
741 "SELECT _ROWID_,key,value FROM ds090 ORDER BY expire ASC LIMIT 1", 775 "SELECT _ROWID_,key,value FROM ds091"
776 " WHERE expire < ?"
777 " ORDER BY expire ASC LIMIT 1",
778 &plugin->del_expired_stmt)) ||
779 (SQLITE_OK !=
780 sq_prepare (plugin->dbh,
781 "SELECT _ROWID_,key,value FROM ds091"
782 " ORDER BY prox ASC, expire ASC LIMIT 1",
742 &plugin->del_select_stmt)) || 783 &plugin->del_select_stmt)) ||
743 (SQLITE_OK != 784 (SQLITE_OK !=
744 sq_prepare (plugin->dbh, 785 sq_prepare (plugin->dbh,
745 "DELETE FROM ds090 WHERE _ROWID_=?", 786 "DELETE FROM ds091 WHERE _ROWID_=?",
746 &plugin->del_stmt)) || 787 &plugin->del_stmt)) ||
747 (SQLITE_OK != 788 (SQLITE_OK !=
748 sq_prepare (plugin->dbh, 789 sq_prepare (plugin->dbh,
749 "SELECT value,expire,path,key,type FROM ds090 " 790 "SELECT value,expire,path,key,type FROM ds091 "
750 "ORDER BY key LIMIT 1 OFFSET ?", 791 "ORDER BY key LIMIT 1 OFFSET ?",
751 &plugin->get_random_stmt)) || 792 &plugin->get_random_stmt)) ||
752 (SQLITE_OK != 793 (SQLITE_OK !=
753 sq_prepare (plugin->dbh, 794 sq_prepare (plugin->dbh,
754 "SELECT value,expire,path,type,key FROM ds090 " 795 "SELECT value,expire,path,type,key FROM ds091 "
755 "WHERE key>=? AND expire >= ? ORDER BY KEY ASC LIMIT ?", 796 "WHERE key>=? AND expire >= ? ORDER BY KEY ASC LIMIT ?",
756 &plugin->get_closest_stmt)) 797 &plugin->get_closest_stmt))
757 ) 798 )
@@ -807,6 +848,7 @@ libgnunet_plugin_datacache_sqlite_done (void *cls)
807 sqlite3_finalize (plugin->get_count_stmt); 848 sqlite3_finalize (plugin->get_count_stmt);
808 sqlite3_finalize (plugin->get_stmt); 849 sqlite3_finalize (plugin->get_stmt);
809 sqlite3_finalize (plugin->del_select_stmt); 850 sqlite3_finalize (plugin->del_select_stmt);
851 sqlite3_finalize (plugin->del_expired_stmt);
810 sqlite3_finalize (plugin->del_stmt); 852 sqlite3_finalize (plugin->del_stmt);
811 sqlite3_finalize (plugin->get_random_stmt); 853 sqlite3_finalize (plugin->get_random_stmt);
812 sqlite3_finalize (plugin->get_closest_stmt); 854 sqlite3_finalize (plugin->get_closest_stmt);