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.c114
1 files changed, 79 insertions, 35 deletions
diff --git a/src/datacache/plugin_datacache_sqlite.c b/src/datacache/plugin_datacache_sqlite.c
index dd79d0125..dc4236a8b 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 /**
@@ -138,7 +141,8 @@ sq_prepare (sqlite3 *dbh,
138 char *dummy; 141 char *dummy;
139 142
140 return sqlite3_prepare (dbh, 143 return sqlite3_prepare (dbh,
141 zSql, strlen (zSql), 144 zSql,
145 strlen (zSql),
142 ppStmt, 146 ppStmt,
143 (const char **) &dummy); 147 (const char **) &dummy);
144} 148}
@@ -149,6 +153,7 @@ sq_prepare (sqlite3 *dbh,
149 * 153 *
150 * @param cls closure (our `struct Plugin`) 154 * @param cls closure (our `struct Plugin`)
151 * @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?
152 * @param size number of bytes in @a data 157 * @param size number of bytes in @a data
153 * @param data data to store 158 * @param data data to store
154 * @param type type of the value 159 * @param type type of the value
@@ -160,6 +165,7 @@ sq_prepare (sqlite3 *dbh,
160static ssize_t 165static ssize_t
161sqlite_plugin_put (void *cls, 166sqlite_plugin_put (void *cls,
162 const struct GNUNET_HashCode *key, 167 const struct GNUNET_HashCode *key,
168 uint32_t xor_distance,
163 size_t size, 169 size_t size,
164 const char *data, 170 const char *data,
165 enum GNUNET_BLOCK_Type type, 171 enum GNUNET_BLOCK_Type type,
@@ -173,6 +179,7 @@ sqlite_plugin_put (void *cls,
173 GNUNET_SQ_query_param_uint32 (&type32), 179 GNUNET_SQ_query_param_uint32 (&type32),
174 GNUNET_SQ_query_param_absolute_time (&discard_time), 180 GNUNET_SQ_query_param_absolute_time (&discard_time),
175 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),
176 GNUNET_SQ_query_param_fixed_size (data, size), 183 GNUNET_SQ_query_param_fixed_size (data, size),
177 GNUNET_SQ_query_param_fixed_size (path_info, 184 GNUNET_SQ_query_param_fixed_size (path_info,
178 path_info_len * sizeof (struct GNUNET_PeerIdentity)), 185 path_info_len * sizeof (struct GNUNET_PeerIdentity)),
@@ -386,6 +393,7 @@ sqlite_plugin_del (void *cls)
386 void *data; 393 void *data;
387 size_t dsize; 394 size_t dsize;
388 struct GNUNET_HashCode hc; 395 struct GNUNET_HashCode hc;
396 struct GNUNET_TIME_Absolute now;
389 struct GNUNET_SQ_ResultSpec rs[] = { 397 struct GNUNET_SQ_ResultSpec rs[] = {
390 GNUNET_SQ_result_spec_uint64 (&rowid), 398 GNUNET_SQ_result_spec_uint64 (&rowid),
391 GNUNET_SQ_result_spec_auto_from_type (&hc), 399 GNUNET_SQ_result_spec_auto_from_type (&hc),
@@ -397,27 +405,52 @@ sqlite_plugin_del (void *cls)
397 GNUNET_SQ_query_param_uint64 (&rowid), 405 GNUNET_SQ_query_param_uint64 (&rowid),
398 GNUNET_SQ_query_param_end 406 GNUNET_SQ_query_param_end
399 }; 407 };
408 struct GNUNET_SQ_QueryParam time_params[] = {
409 GNUNET_SQ_query_param_absolute_time (&now),
410 GNUNET_SQ_query_param_end
411 };
400 412
401 LOG (GNUNET_ERROR_TYPE_DEBUG, 413 LOG (GNUNET_ERROR_TYPE_DEBUG,
402 "Processing DEL\n"); 414 "Processing DEL\n");
403 if (SQLITE_ROW != 415 now = GNUNET_TIME_absolute_get ();
404 sqlite3_step (plugin->del_select_stmt)) 416 if (GNUNET_OK !=
417 GNUNET_SQ_bind (plugin->del_expired_stmt,
418 time_params))
405 { 419 {
406 LOG_SQLITE (plugin->dbh, 420 LOG_SQLITE (plugin->dbh,
407 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 421 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
408 "sqlite3_step"); 422 "sqlite3_bind");
409 GNUNET_SQ_reset (plugin->dbh, 423 GNUNET_SQ_reset (plugin->dbh,
410 plugin->del_select_stmt); 424 plugin->del_expired_stmt);
411 return GNUNET_SYSERR; 425 return GNUNET_SYSERR;
412 } 426 }
413 if (GNUNET_OK != 427 if ( (SQLITE_ROW !=
414 GNUNET_SQ_extract_result (plugin->del_select_stmt, 428 sqlite3_step (plugin->del_expired_stmt)) ||
415 rs)) 429 (GNUNET_OK !=
430 GNUNET_SQ_extract_result (plugin->del_expired_stmt,
431 rs)) )
416 { 432 {
417 GNUNET_break (0);
418 GNUNET_SQ_reset (plugin->dbh, 433 GNUNET_SQ_reset (plugin->dbh,
419 plugin->del_select_stmt); 434 plugin->del_expired_stmt);
420 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 }
421 } 454 }
422 GNUNET_SQ_cleanup_result (rs); 455 GNUNET_SQ_cleanup_result (rs);
423 GNUNET_SQ_reset (plugin->dbh, 456 GNUNET_SQ_reset (plugin->dbh,
@@ -708,13 +741,16 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
708 SQLITE3_EXEC (dbh, "PRAGMA sqlite_temp_store=3"); 741 SQLITE3_EXEC (dbh, "PRAGMA sqlite_temp_store=3");
709 742
710 SQLITE3_EXEC (dbh, 743 SQLITE3_EXEC (dbh,
711 "CREATE TABLE ds090 (" " type INTEGER NOT NULL DEFAULT 0," 744 "CREATE TABLE ds091 ("
712 " expire INTEGER NOT NULL DEFAULT 0," 745 " type INTEGER NOT NULL DEFAULT 0,"
746 " expire INTEGER NOT NULL,"
713 " key BLOB NOT NULL DEFAULT ''," 747 " key BLOB NOT NULL DEFAULT '',"
714 " value BLOB NOT NULL DEFAULT ''," 748 " prox INTEGER NOT NULL,"
749 " value BLOB NOT NULL,"
715 " path BLOB DEFAULT '')"); 750 " path BLOB DEFAULT '')");
716 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)");
717 SQLITE3_EXEC (dbh, "CREATE INDEX idx_expire ON ds090 (expire)"); 752 SQLITE3_EXEC (dbh, "CREATE INDEX idx_prox_expire ON ds091 (prox,expire)");
753 SQLITE3_EXEC (dbh, "CREATE INDEX idx_expire_only ON ds091 (expire)");
718 plugin = GNUNET_new (struct Plugin); 754 plugin = GNUNET_new (struct Plugin);
719 plugin->env = env; 755 plugin->env = env;
720 plugin->dbh = dbh; 756 plugin->dbh = dbh;
@@ -722,35 +758,42 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
722 758
723 if ( (SQLITE_OK != 759 if ( (SQLITE_OK !=
724 sq_prepare (plugin->dbh, 760 sq_prepare (plugin->dbh,
725 "INSERT INTO ds090 (type, expire, key, value, path) " 761 "INSERT INTO ds091 (type, expire, key, prox, value, path) "
726 "VALUES (?, ?, ?, ?, ?)", 762 "VALUES (?, ?, ?, ?, ?, ?)",
727 &plugin->insert_stmt)) || 763 &plugin->insert_stmt)) ||
728 (SQLITE_OK != 764 (SQLITE_OK !=
729 sq_prepare (plugin->dbh, 765 sq_prepare (plugin->dbh,
730 "SELECT count(*) FROM ds090 " 766 "SELECT count(*) FROM ds091 "
731 "WHERE key=? AND type=? AND expire >= ?", 767 "WHERE key=? AND type=? AND expire >= ?",
732 &plugin->get_count_stmt)) || 768 &plugin->get_count_stmt)) ||
733 (SQLITE_OK != 769 (SQLITE_OK !=
734 sq_prepare (plugin->dbh, 770 sq_prepare (plugin->dbh,
735 "SELECT value,expire,path FROM ds090 " 771 "SELECT value,expire,path FROM ds091"
736 "WHERE key=? AND type=? AND expire >= ? LIMIT 1 OFFSET ?", 772 " WHERE key=? AND type=? AND expire >= ? LIMIT 1 OFFSET ?",
737 &plugin->get_stmt)) || 773 &plugin->get_stmt)) ||
738 (SQLITE_OK != 774 (SQLITE_OK !=
739 sq_prepare (plugin->dbh, 775 sq_prepare (plugin->dbh,
740 "SELECT _ROWID_,key,value FROM ds090 ORDER BY expire ASC LIMIT 1", 776 "SELECT _ROWID_,key,value FROM ds091"
777 " WHERE expire < ?"
778 " ORDER BY expire ASC LIMIT 1",
779 &plugin->del_expired_stmt)) ||
780 (SQLITE_OK !=
781 sq_prepare (plugin->dbh,
782 "SELECT _ROWID_,key,value FROM ds091"
783 " ORDER BY prox ASC, expire ASC LIMIT 1",
741 &plugin->del_select_stmt)) || 784 &plugin->del_select_stmt)) ||
742 (SQLITE_OK != 785 (SQLITE_OK !=
743 sq_prepare (plugin->dbh, 786 sq_prepare (plugin->dbh,
744 "DELETE FROM ds090 WHERE _ROWID_=?", 787 "DELETE FROM ds091 WHERE _ROWID_=?",
745 &plugin->del_stmt)) || 788 &plugin->del_stmt)) ||
746 (SQLITE_OK != 789 (SQLITE_OK !=
747 sq_prepare (plugin->dbh, 790 sq_prepare (plugin->dbh,
748 "SELECT value,expire,path,key,type FROM ds090 " 791 "SELECT value,expire,path,key,type FROM ds091 "
749 "ORDER BY key LIMIT 1 OFFSET ?", 792 "ORDER BY key LIMIT 1 OFFSET ?",
750 &plugin->get_random_stmt)) || 793 &plugin->get_random_stmt)) ||
751 (SQLITE_OK != 794 (SQLITE_OK !=
752 sq_prepare (plugin->dbh, 795 sq_prepare (plugin->dbh,
753 "SELECT value,expire,path,type,key FROM ds090 " 796 "SELECT value,expire,path,type,key FROM ds091 "
754 "WHERE key>=? AND expire >= ? ORDER BY KEY ASC LIMIT ?", 797 "WHERE key>=? AND expire >= ? ORDER BY KEY ASC LIMIT ?",
755 &plugin->get_closest_stmt)) 798 &plugin->get_closest_stmt))
756 ) 799 )
@@ -806,6 +849,7 @@ libgnunet_plugin_datacache_sqlite_done (void *cls)
806 sqlite3_finalize (plugin->get_count_stmt); 849 sqlite3_finalize (plugin->get_count_stmt);
807 sqlite3_finalize (plugin->get_stmt); 850 sqlite3_finalize (plugin->get_stmt);
808 sqlite3_finalize (plugin->del_select_stmt); 851 sqlite3_finalize (plugin->del_select_stmt);
852 sqlite3_finalize (plugin->del_expired_stmt);
809 sqlite3_finalize (plugin->del_stmt); 853 sqlite3_finalize (plugin->del_stmt);
810 sqlite3_finalize (plugin->get_random_stmt); 854 sqlite3_finalize (plugin->get_random_stmt);
811 sqlite3_finalize (plugin->get_closest_stmt); 855 sqlite3_finalize (plugin->get_closest_stmt);