diff options
Diffstat (limited to 'src/datacache/plugin_datacache_postgres.c')
-rw-r--r-- | src/datacache/plugin_datacache_postgres.c | 99 |
1 files changed, 64 insertions, 35 deletions
diff --git a/src/datacache/plugin_datacache_postgres.c b/src/datacache/plugin_datacache_postgres.c index 2c233c4c21..ea87acc1f0 100644 --- a/src/datacache/plugin_datacache_postgres.c +++ b/src/datacache/plugin_datacache_postgres.c @@ -1,21 +1,19 @@ /* This file is part of GNUnet - Copyright (C) 2006, 2009, 2010, 2012, 2015, 2017 GNUnet e.V. + Copyright (C) 2006, 2009, 2010, 2012, 2015, 2017, 2018 GNUnet e.V. - GNUnet is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ /** @@ -67,47 +65,54 @@ static int init_connection (struct Plugin *plugin) { struct GNUNET_PQ_ExecuteStatement es[] = { - GNUNET_PQ_make_execute ("CREATE TEMPORARY TABLE IF NOT EXISTS gn090dc (" + GNUNET_PQ_make_execute ("CREATE TEMPORARY TABLE IF NOT EXISTS gn011dc (" " type INTEGER NOT NULL," + " prox INTEGER NOT NULL," " discard_time BIGINT NOT NULL," " key BYTEA NOT NULL," " value BYTEA NOT NULL," " path BYTEA DEFAULT NULL)" "WITH OIDS"), - GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS idx_key ON gn090dc (key)"), - GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS idx_dt ON gn090dc (discard_time)"), - GNUNET_PQ_make_execute ("ALTER TABLE gn090dc ALTER value SET STORAGE EXTERNAL"), - GNUNET_PQ_make_execute ("ALTER TABLE gn090dc ALTER key SET STORAGE PLAIN"), + GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS idx_key ON gn011dc (key)"), + GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS idx_dt ON gn011dc (discard_time)"), + GNUNET_PQ_make_execute ("ALTER TABLE gn011dc ALTER value SET STORAGE EXTERNAL"), + GNUNET_PQ_make_execute ("ALTER TABLE gn011dc ALTER key SET STORAGE PLAIN"), GNUNET_PQ_EXECUTE_STATEMENT_END }; struct GNUNET_PQ_PreparedStatement ps[] = { GNUNET_PQ_make_prepare ("getkt", - "SELECT discard_time,type,value,path FROM gn090dc " - "WHERE key=$1 AND type=$2", - 2), + "SELECT discard_time,type,value,path FROM gn011dc " + "WHERE key=$1 AND type=$2 AND discard_time >= $3", + 3), GNUNET_PQ_make_prepare ("getk", - "SELECT discard_time,type,value,path FROM gn090dc " - "WHERE key=$1", + "SELECT discard_time,type,value,path FROM gn011dc " + "WHERE key=$1 AND discard_time >= $2", + 2), + GNUNET_PQ_make_prepare ("getex", + "SELECT length(value) AS len,oid,key FROM gn011dc" + " WHERE discard_time < $1" + " ORDER BY discard_time ASC LIMIT 1", 1), GNUNET_PQ_make_prepare ("getm", - "SELECT length(value) AS len,oid,key FROM gn090dc " - "ORDER BY discard_time ASC LIMIT 1", + "SELECT length(value) AS len,oid,key FROM gn011dc" + " ORDER BY prox ASC, discard_time ASC LIMIT 1", 0), GNUNET_PQ_make_prepare ("get_random", - "SELECT discard_time,type,value,path,key FROM gn090dc " - "ORDER BY key ASC LIMIT 1 OFFSET $1", - 1), + "SELECT discard_time,type,value,path,key FROM gn011dc" + " WHERE discard_time >= $1" + " ORDER BY key ASC LIMIT 1 OFFSET $2", + 2), GNUNET_PQ_make_prepare ("get_closest", - "SELECT discard_time,type,value,path,key FROM gn090dc " - "WHERE key>=$1 ORDER BY key ASC LIMIT $2", - 1), + "SELECT discard_time,type,value,path,key FROM gn011dc " + "WHERE key>=$1 AND discard_time >= $2 ORDER BY key ASC LIMIT $3", + 3), GNUNET_PQ_make_prepare ("delrow", - "DELETE FROM gn090dc WHERE oid=$1", + "DELETE FROM gn011dc WHERE oid=$1", 1), GNUNET_PQ_make_prepare ("put", - "INSERT INTO gn090dc (type, discard_time, key, value, path) " - "VALUES ($1, $2, $3, $4, $5)", - 5), + "INSERT INTO gn011dc (type, prox, discard_time, key, value, path) " + "VALUES ($1, $2, $3, $4, $5, $6)", + 6), GNUNET_PQ_PREPARED_STATEMENT_END }; @@ -141,6 +146,7 @@ init_connection (struct Plugin *plugin) * * @param cls closure (our `struct Plugin`) * @param key key to store @a data under + * @param prox proximity of @a key to my PID * @param data_size number of bytes in @a data * @param data data to store * @param type type of the value @@ -152,6 +158,7 @@ init_connection (struct Plugin *plugin) static ssize_t postgres_plugin_put (void *cls, const struct GNUNET_HashCode *key, + uint32_t prox, size_t data_size, const char *data, enum GNUNET_BLOCK_Type type, @@ -163,6 +170,7 @@ postgres_plugin_put (void *cls, uint32_t type32 = (uint32_t) type; struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_uint32 (&type32), + GNUNET_PQ_query_param_uint32 (&prox), GNUNET_PQ_query_param_absolute_time (&discard_time), GNUNET_PQ_query_param_auto_from_type (key), GNUNET_PQ_query_param_fixed_size (data, data_size), @@ -302,18 +310,22 @@ postgres_plugin_get (void *cls, { struct Plugin *plugin = cls; uint32_t type32 = (uint32_t) type; + struct GNUNET_TIME_Absolute now; struct GNUNET_PQ_QueryParam paramk[] = { GNUNET_PQ_query_param_auto_from_type (key), + GNUNET_PQ_query_param_absolute_time (&now), GNUNET_PQ_query_param_end }; struct GNUNET_PQ_QueryParam paramkt[] = { GNUNET_PQ_query_param_auto_from_type (key), GNUNET_PQ_query_param_uint32 (&type32), + GNUNET_PQ_query_param_absolute_time (&now), GNUNET_PQ_query_param_end }; enum GNUNET_DB_QueryStatus res; struct HandleResultContext hr_ctx; + now = GNUNET_TIME_absolute_get (); hr_ctx.iter = iter; hr_ctx.iter_cls = iter_cls; hr_ctx.key = key; @@ -359,11 +371,22 @@ postgres_plugin_del (void *cls) GNUNET_PQ_query_param_uint32 (&oid), GNUNET_PQ_query_param_end }; + struct GNUNET_TIME_Absolute now; + struct GNUNET_PQ_QueryParam xparam[] = { + GNUNET_PQ_query_param_absolute_time (&now), + GNUNET_PQ_query_param_end + }; + now = GNUNET_TIME_absolute_get (); res = GNUNET_PQ_eval_prepared_singleton_select (plugin->dbh, - "getm", - pempty, + "getex", + xparam, rs); + if (0 >= res) + res = GNUNET_PQ_eval_prepared_singleton_select (plugin->dbh, + "getm", + pempty, + rs); if (0 > res) return GNUNET_SYSERR; if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == res) @@ -405,6 +428,7 @@ postgres_plugin_get_random (void *cls, { struct Plugin *plugin = cls; uint32_t off; + struct GNUNET_TIME_Absolute now; struct GNUNET_TIME_Absolute expiration_time; size_t data_size; void *data; @@ -414,6 +438,7 @@ postgres_plugin_get_random (void *cls, uint32_t type; enum GNUNET_DB_QueryStatus res; struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_absolute_time (&now), GNUNET_PQ_query_param_uint32 (&off), GNUNET_PQ_query_param_end }; @@ -437,6 +462,7 @@ postgres_plugin_get_random (void *cls, return 0; if (NULL == iter) return 1; + now = GNUNET_TIME_absolute_get (); off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, plugin->num_items); res = GNUNET_PQ_eval_prepared_singleton_select (plugin->dbh, @@ -598,8 +624,10 @@ postgres_plugin_get_closest (void *cls, { struct Plugin *plugin = cls; uint32_t num_results32 = (uint32_t) num_results; + struct GNUNET_TIME_Absolute now; struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (key), + GNUNET_PQ_query_param_absolute_time (&now), GNUNET_PQ_query_param_uint32 (&num_results32), GNUNET_PQ_query_param_end }; @@ -608,6 +636,7 @@ postgres_plugin_get_closest (void *cls, erc.iter = iter; erc.iter_cls = iter_cls; + now = GNUNET_TIME_absolute_get (); res = GNUNET_PQ_eval_prepared_multi_select (plugin->dbh, "get_closest", params, |