aboutsummaryrefslogtreecommitdiff
path: root/src/datacache/plugin_datacache_postgres.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/datacache/plugin_datacache_postgres.c')
-rw-r--r--src/datacache/plugin_datacache_postgres.c99
1 files changed, 64 insertions, 35 deletions
diff --git a/src/datacache/plugin_datacache_postgres.c b/src/datacache/plugin_datacache_postgres.c
index 2c233c4c2..ea87acc1f 100644
--- a/src/datacache/plugin_datacache_postgres.c
+++ b/src/datacache/plugin_datacache_postgres.c
@@ -1,21 +1,19 @@
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 GNUnet e.V. 3 Copyright (C) 2006, 2009, 2010, 2012, 2015, 2017, 2018 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/**
@@ -67,47 +65,54 @@ static int
67init_connection (struct Plugin *plugin) 65init_connection (struct Plugin *plugin)
68{ 66{
69 struct GNUNET_PQ_ExecuteStatement es[] = { 67 struct GNUNET_PQ_ExecuteStatement es[] = {
70 GNUNET_PQ_make_execute ("CREATE TEMPORARY TABLE IF NOT EXISTS gn090dc (" 68 GNUNET_PQ_make_execute ("CREATE TEMPORARY TABLE IF NOT EXISTS gn011dc ("
71 " type INTEGER NOT NULL," 69 " type INTEGER NOT NULL,"
70 " prox INTEGER NOT NULL,"
72 " discard_time BIGINT NOT NULL," 71 " discard_time BIGINT NOT NULL,"
73 " key BYTEA NOT NULL," 72 " key BYTEA NOT NULL,"
74 " value BYTEA NOT NULL," 73 " value BYTEA NOT NULL,"
75 " path BYTEA DEFAULT NULL)" 74 " path BYTEA DEFAULT NULL)"
76 "WITH OIDS"), 75 "WITH OIDS"),
77 GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS idx_key ON gn090dc (key)"), 76 GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS idx_key ON gn011dc (key)"),
78 GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS idx_dt ON gn090dc (discard_time)"), 77 GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS idx_dt ON gn011dc (discard_time)"),
79 GNUNET_PQ_make_execute ("ALTER TABLE gn090dc ALTER value SET STORAGE EXTERNAL"), 78 GNUNET_PQ_make_execute ("ALTER TABLE gn011dc ALTER value SET STORAGE EXTERNAL"),
80 GNUNET_PQ_make_execute ("ALTER TABLE gn090dc ALTER key SET STORAGE PLAIN"), 79 GNUNET_PQ_make_execute ("ALTER TABLE gn011dc ALTER key SET STORAGE PLAIN"),
81 GNUNET_PQ_EXECUTE_STATEMENT_END 80 GNUNET_PQ_EXECUTE_STATEMENT_END
82 }; 81 };
83 struct GNUNET_PQ_PreparedStatement ps[] = { 82 struct GNUNET_PQ_PreparedStatement ps[] = {
84 GNUNET_PQ_make_prepare ("getkt", 83 GNUNET_PQ_make_prepare ("getkt",
85 "SELECT discard_time,type,value,path FROM gn090dc " 84 "SELECT discard_time,type,value,path FROM gn011dc "
86 "WHERE key=$1 AND type=$2", 85 "WHERE key=$1 AND type=$2 AND discard_time >= $3",
87 2), 86 3),
88 GNUNET_PQ_make_prepare ("getk", 87 GNUNET_PQ_make_prepare ("getk",
89 "SELECT discard_time,type,value,path FROM gn090dc " 88 "SELECT discard_time,type,value,path FROM gn011dc "
90 "WHERE key=$1", 89 "WHERE key=$1 AND discard_time >= $2",
90 2),
91 GNUNET_PQ_make_prepare ("getex",
92 "SELECT length(value) AS len,oid,key FROM gn011dc"
93 " WHERE discard_time < $1"
94 " ORDER BY discard_time ASC LIMIT 1",
91 1), 95 1),
92 GNUNET_PQ_make_prepare ("getm", 96 GNUNET_PQ_make_prepare ("getm",
93 "SELECT length(value) AS len,oid,key FROM gn090dc " 97 "SELECT length(value) AS len,oid,key FROM gn011dc"
94 "ORDER BY discard_time ASC LIMIT 1", 98 " ORDER BY prox ASC, discard_time ASC LIMIT 1",
95 0), 99 0),
96 GNUNET_PQ_make_prepare ("get_random", 100 GNUNET_PQ_make_prepare ("get_random",
97 "SELECT discard_time,type,value,path,key FROM gn090dc " 101 "SELECT discard_time,type,value,path,key FROM gn011dc"
98 "ORDER BY key ASC LIMIT 1 OFFSET $1", 102 " WHERE discard_time >= $1"
99 1), 103 " ORDER BY key ASC LIMIT 1 OFFSET $2",
104 2),
100 GNUNET_PQ_make_prepare ("get_closest", 105 GNUNET_PQ_make_prepare ("get_closest",
101 "SELECT discard_time,type,value,path,key FROM gn090dc " 106 "SELECT discard_time,type,value,path,key FROM gn011dc "
102 "WHERE key>=$1 ORDER BY key ASC LIMIT $2", 107 "WHERE key>=$1 AND discard_time >= $2 ORDER BY key ASC LIMIT $3",
103 1), 108 3),
104 GNUNET_PQ_make_prepare ("delrow", 109 GNUNET_PQ_make_prepare ("delrow",
105 "DELETE FROM gn090dc WHERE oid=$1", 110 "DELETE FROM gn011dc WHERE oid=$1",
106 1), 111 1),
107 GNUNET_PQ_make_prepare ("put", 112 GNUNET_PQ_make_prepare ("put",
108 "INSERT INTO gn090dc (type, discard_time, key, value, path) " 113 "INSERT INTO gn011dc (type, prox, discard_time, key, value, path) "
109 "VALUES ($1, $2, $3, $4, $5)", 114 "VALUES ($1, $2, $3, $4, $5, $6)",
110 5), 115 6),
111 GNUNET_PQ_PREPARED_STATEMENT_END 116 GNUNET_PQ_PREPARED_STATEMENT_END
112 }; 117 };
113 118
@@ -141,6 +146,7 @@ init_connection (struct Plugin *plugin)
141 * 146 *
142 * @param cls closure (our `struct Plugin`) 147 * @param cls closure (our `struct Plugin`)
143 * @param key key to store @a data under 148 * @param key key to store @a data under
149 * @param prox proximity of @a key to my PID
144 * @param data_size number of bytes in @a data 150 * @param data_size number of bytes in @a data
145 * @param data data to store 151 * @param data data to store
146 * @param type type of the value 152 * @param type type of the value
@@ -152,6 +158,7 @@ init_connection (struct Plugin *plugin)
152static ssize_t 158static ssize_t
153postgres_plugin_put (void *cls, 159postgres_plugin_put (void *cls,
154 const struct GNUNET_HashCode *key, 160 const struct GNUNET_HashCode *key,
161 uint32_t prox,
155 size_t data_size, 162 size_t data_size,
156 const char *data, 163 const char *data,
157 enum GNUNET_BLOCK_Type type, 164 enum GNUNET_BLOCK_Type type,
@@ -163,6 +170,7 @@ postgres_plugin_put (void *cls,
163 uint32_t type32 = (uint32_t) type; 170 uint32_t type32 = (uint32_t) type;
164 struct GNUNET_PQ_QueryParam params[] = { 171 struct GNUNET_PQ_QueryParam params[] = {
165 GNUNET_PQ_query_param_uint32 (&type32), 172 GNUNET_PQ_query_param_uint32 (&type32),
173 GNUNET_PQ_query_param_uint32 (&prox),
166 GNUNET_PQ_query_param_absolute_time (&discard_time), 174 GNUNET_PQ_query_param_absolute_time (&discard_time),
167 GNUNET_PQ_query_param_auto_from_type (key), 175 GNUNET_PQ_query_param_auto_from_type (key),
168 GNUNET_PQ_query_param_fixed_size (data, data_size), 176 GNUNET_PQ_query_param_fixed_size (data, data_size),
@@ -302,18 +310,22 @@ postgres_plugin_get (void *cls,
302{ 310{
303 struct Plugin *plugin = cls; 311 struct Plugin *plugin = cls;
304 uint32_t type32 = (uint32_t) type; 312 uint32_t type32 = (uint32_t) type;
313 struct GNUNET_TIME_Absolute now;
305 struct GNUNET_PQ_QueryParam paramk[] = { 314 struct GNUNET_PQ_QueryParam paramk[] = {
306 GNUNET_PQ_query_param_auto_from_type (key), 315 GNUNET_PQ_query_param_auto_from_type (key),
316 GNUNET_PQ_query_param_absolute_time (&now),
307 GNUNET_PQ_query_param_end 317 GNUNET_PQ_query_param_end
308 }; 318 };
309 struct GNUNET_PQ_QueryParam paramkt[] = { 319 struct GNUNET_PQ_QueryParam paramkt[] = {
310 GNUNET_PQ_query_param_auto_from_type (key), 320 GNUNET_PQ_query_param_auto_from_type (key),
311 GNUNET_PQ_query_param_uint32 (&type32), 321 GNUNET_PQ_query_param_uint32 (&type32),
322 GNUNET_PQ_query_param_absolute_time (&now),
312 GNUNET_PQ_query_param_end 323 GNUNET_PQ_query_param_end
313 }; 324 };
314 enum GNUNET_DB_QueryStatus res; 325 enum GNUNET_DB_QueryStatus res;
315 struct HandleResultContext hr_ctx; 326 struct HandleResultContext hr_ctx;
316 327
328 now = GNUNET_TIME_absolute_get ();
317 hr_ctx.iter = iter; 329 hr_ctx.iter = iter;
318 hr_ctx.iter_cls = iter_cls; 330 hr_ctx.iter_cls = iter_cls;
319 hr_ctx.key = key; 331 hr_ctx.key = key;
@@ -359,11 +371,22 @@ postgres_plugin_del (void *cls)
359 GNUNET_PQ_query_param_uint32 (&oid), 371 GNUNET_PQ_query_param_uint32 (&oid),
360 GNUNET_PQ_query_param_end 372 GNUNET_PQ_query_param_end
361 }; 373 };
374 struct GNUNET_TIME_Absolute now;
375 struct GNUNET_PQ_QueryParam xparam[] = {
376 GNUNET_PQ_query_param_absolute_time (&now),
377 GNUNET_PQ_query_param_end
378 };
362 379
380 now = GNUNET_TIME_absolute_get ();
363 res = GNUNET_PQ_eval_prepared_singleton_select (plugin->dbh, 381 res = GNUNET_PQ_eval_prepared_singleton_select (plugin->dbh,
364 "getm", 382 "getex",
365 pempty, 383 xparam,
366 rs); 384 rs);
385 if (0 >= res)
386 res = GNUNET_PQ_eval_prepared_singleton_select (plugin->dbh,
387 "getm",
388 pempty,
389 rs);
367 if (0 > res) 390 if (0 > res)
368 return GNUNET_SYSERR; 391 return GNUNET_SYSERR;
369 if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == res) 392 if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == res)
@@ -405,6 +428,7 @@ postgres_plugin_get_random (void *cls,
405{ 428{
406 struct Plugin *plugin = cls; 429 struct Plugin *plugin = cls;
407 uint32_t off; 430 uint32_t off;
431 struct GNUNET_TIME_Absolute now;
408 struct GNUNET_TIME_Absolute expiration_time; 432 struct GNUNET_TIME_Absolute expiration_time;
409 size_t data_size; 433 size_t data_size;
410 void *data; 434 void *data;
@@ -414,6 +438,7 @@ postgres_plugin_get_random (void *cls,
414 uint32_t type; 438 uint32_t type;
415 enum GNUNET_DB_QueryStatus res; 439 enum GNUNET_DB_QueryStatus res;
416 struct GNUNET_PQ_QueryParam params[] = { 440 struct GNUNET_PQ_QueryParam params[] = {
441 GNUNET_PQ_query_param_absolute_time (&now),
417 GNUNET_PQ_query_param_uint32 (&off), 442 GNUNET_PQ_query_param_uint32 (&off),
418 GNUNET_PQ_query_param_end 443 GNUNET_PQ_query_param_end
419 }; 444 };
@@ -437,6 +462,7 @@ postgres_plugin_get_random (void *cls,
437 return 0; 462 return 0;
438 if (NULL == iter) 463 if (NULL == iter)
439 return 1; 464 return 1;
465 now = GNUNET_TIME_absolute_get ();
440 off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, 466 off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
441 plugin->num_items); 467 plugin->num_items);
442 res = GNUNET_PQ_eval_prepared_singleton_select (plugin->dbh, 468 res = GNUNET_PQ_eval_prepared_singleton_select (plugin->dbh,
@@ -598,8 +624,10 @@ postgres_plugin_get_closest (void *cls,
598{ 624{
599 struct Plugin *plugin = cls; 625 struct Plugin *plugin = cls;
600 uint32_t num_results32 = (uint32_t) num_results; 626 uint32_t num_results32 = (uint32_t) num_results;
627 struct GNUNET_TIME_Absolute now;
601 struct GNUNET_PQ_QueryParam params[] = { 628 struct GNUNET_PQ_QueryParam params[] = {
602 GNUNET_PQ_query_param_auto_from_type (key), 629 GNUNET_PQ_query_param_auto_from_type (key),
630 GNUNET_PQ_query_param_absolute_time (&now),
603 GNUNET_PQ_query_param_uint32 (&num_results32), 631 GNUNET_PQ_query_param_uint32 (&num_results32),
604 GNUNET_PQ_query_param_end 632 GNUNET_PQ_query_param_end
605 }; 633 };
@@ -608,6 +636,7 @@ postgres_plugin_get_closest (void *cls,
608 636
609 erc.iter = iter; 637 erc.iter = iter;
610 erc.iter_cls = iter_cls; 638 erc.iter_cls = iter_cls;
639 now = GNUNET_TIME_absolute_get ();
611 res = GNUNET_PQ_eval_prepared_multi_select (plugin->dbh, 640 res = GNUNET_PQ_eval_prepared_multi_select (plugin->dbh,
612 "get_closest", 641 "get_closest",
613 params, 642 params,