aboutsummaryrefslogtreecommitdiff
path: root/src/datacache/plugin_datacache_postgres.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-04-30 07:56:00 +0000
committerChristian Grothoff <christian@grothoff.org>2015-04-30 07:56:00 +0000
commit786745c969589eae2aa069885b40eba0f3989507 (patch)
tree6f5c8573b021ba628b4f135f3fb964728b3e1724 /src/datacache/plugin_datacache_postgres.c
parenta49b0f351926cf4376a58937a94e37426e3ae167 (diff)
downloadgnunet-786745c969589eae2aa069885b40eba0f3989507.tar.gz
gnunet-786745c969589eae2aa069885b40eba0f3989507.zip
implementing 'get_closest' API for sqlite and postgres datacache plugins
Diffstat (limited to 'src/datacache/plugin_datacache_postgres.c')
-rw-r--r--src/datacache/plugin_datacache_postgres.c137
1 files changed, 133 insertions, 4 deletions
diff --git a/src/datacache/plugin_datacache_postgres.c b/src/datacache/plugin_datacache_postgres.c
index 13f944d7c..1156d214e 100644
--- a/src/datacache/plugin_datacache_postgres.c
+++ b/src/datacache/plugin_datacache_postgres.c
@@ -163,6 +163,11 @@ init_connection (struct Plugin *plugin)
163 "ORDER BY key ASC LIMIT 1 OFFSET $1", 1)) || 163 "ORDER BY key ASC LIMIT 1 OFFSET $1", 1)) ||
164 (GNUNET_OK != 164 (GNUNET_OK !=
165 GNUNET_POSTGRES_prepare (plugin->dbh, 165 GNUNET_POSTGRES_prepare (plugin->dbh,
166 "get_closest",
167 "SELECT discard_time,type,value,path,key FROM gn090dc "
168 "WHERE key>=$1 ORDER BY key ASC LIMIT $2", 1)) ||
169 (GNUNET_OK !=
170 GNUNET_POSTGRES_prepare (plugin->dbh,
166 "delrow", 171 "delrow",
167 "DELETE FROM gn090dc WHERE oid=$1", 1)) || 172 "DELETE FROM gn090dc WHERE oid=$1", 1)) ||
168 (GNUNET_OK != 173 (GNUNET_OK !=
@@ -259,11 +264,11 @@ postgres_plugin_get (void *cls,
259 264
260 const char *paramValues[] = { 265 const char *paramValues[] = {
261 (const char *) key, 266 (const char *) key,
262 (const char *) &btype, 267 (const char *) &btype
263 }; 268 };
264 int paramLengths[] = { 269 int paramLengths[] = {
265 sizeof (struct GNUNET_HashCode), 270 sizeof (struct GNUNET_HashCode),
266 sizeof (btype), 271 sizeof (btype)
267 }; 272 };
268 const int paramFormats[] = { 1, 1 }; 273 const int paramFormats[] = { 1, 1 };
269 struct GNUNET_TIME_Absolute expiration_time; 274 struct GNUNET_TIME_Absolute expiration_time;
@@ -433,10 +438,10 @@ postgres_plugin_get_random (void *cls,
433 unsigned int type; 438 unsigned int type;
434 PGresult *res; 439 PGresult *res;
435 const char *paramValues[] = { 440 const char *paramValues[] = {
436 (const char *) &off_be, 441 (const char *) &off_be
437 }; 442 };
438 int paramLengths[] = { 443 int paramLengths[] = {
439 sizeof (off_be), 444 sizeof (off_be)
440 }; 445 };
441 const int paramFormats[] = { 1 }; 446 const int paramFormats[] = { 1 };
442 447
@@ -507,6 +512,129 @@ postgres_plugin_get_random (void *cls,
507 512
508 513
509/** 514/**
515 * Iterate over the results that are "close" to a particular key in
516 * the datacache. "close" is defined as numerically larger than @a
517 * key (when interpreted as a circular address space), with small
518 * distance.
519 *
520 * @param cls closure (internal context for the plugin)
521 * @param key area of the keyspace to look into
522 * @param num_results number of results that should be returned to @a iter
523 * @param iter maybe NULL (to just count)
524 * @param iter_cls closure for @a iter
525 * @return the number of results found
526 */
527static unsigned int
528postgres_plugin_get_closest (void *cls,
529 const struct GNUNET_HashCode *key,
530 unsigned int num_results,
531 GNUNET_DATACACHE_Iterator iter,
532 void *iter_cls)
533{
534 struct Plugin *plugin = cls;
535 uint32_t nbo_limit = htonl (num_results);
536 const char *paramValues[] = {
537 (const char *) key,
538 (const char *) &nbo_limit,
539 };
540 int paramLengths[] = {
541 sizeof (struct GNUNET_HashCode),
542 sizeof (nbo_limit)
543
544 };
545 const int paramFormats[] = { 1, 1 };
546 struct GNUNET_TIME_Absolute expiration_time;
547 uint32_t size;
548 unsigned int type;
549 unsigned int cnt;
550 unsigned int i;
551 unsigned int path_len;
552 const struct GNUNET_PeerIdentity *path;
553 PGresult *res;
554
555 res =
556 PQexecPrepared (plugin->dbh,
557 "get_closest",
558 2,
559 paramValues,
560 paramLengths,
561 paramFormats,
562 1);
563 if (GNUNET_OK !=
564 GNUNET_POSTGRES_check_result (plugin->dbh,
565 res,
566 PGRES_TUPLES_OK,
567 "PQexecPrepared",
568 "get_closest"))
569 {
570 LOG (GNUNET_ERROR_TYPE_DEBUG,
571 "Ending iteration (postgres error)\n");
572 return 0;
573 }
574
575 if (0 == (cnt = PQntuples (res)))
576 {
577 /* no result */
578 LOG (GNUNET_ERROR_TYPE_DEBUG,
579 "Ending iteration (no more results)\n");
580 PQclear (res);
581 return 0;
582 }
583 if (NULL == iter)
584 {
585 PQclear (res);
586 return cnt;
587 }
588 if ( (5 != PQnfields (res)) ||
589 (sizeof (uint64_t) != PQfsize (res, 0)) ||
590 (sizeof (uint32_t) != PQfsize (res, 1)) ||
591 (sizeof (struct GNUNET_HashCode) != PQfsize (res, 4)) )
592 {
593 GNUNET_break (0);
594 PQclear (res);
595 return 0;
596 }
597 for (i = 0; i < cnt; i++)
598 {
599 expiration_time.abs_value_us =
600 GNUNET_ntohll (*(uint64_t *) PQgetvalue (res, i, 0));
601 type = ntohl (*(uint32_t *) PQgetvalue (res, i, 1));
602 size = PQgetlength (res, i, 2);
603 path_len = PQgetlength (res, i, 3);
604 if (0 != (path_len % sizeof (struct GNUNET_PeerIdentity)))
605 {
606 GNUNET_break (0);
607 path_len = 0;
608 }
609 path_len %= sizeof (struct GNUNET_PeerIdentity);
610 path = (const struct GNUNET_PeerIdentity *) PQgetvalue (res, i, 3);
611 key = (const struct GNUNET_HashCode *) PQgetvalue (res, i, 4);
612 LOG (GNUNET_ERROR_TYPE_DEBUG,
613 "Found result of size %u bytes and type %u in database\n",
614 (unsigned int) size,
615 (unsigned int) type);
616 if (GNUNET_SYSERR ==
617 iter (iter_cls,
618 key,
619 size,
620 PQgetvalue (res, i, 2),
621 (enum GNUNET_BLOCK_Type) type,
622 expiration_time,
623 path_len,
624 path))
625 {
626 LOG (GNUNET_ERROR_TYPE_DEBUG,
627 "Ending iteration (client error)\n");
628 PQclear (res);
629 return cnt;
630 }
631 }
632 PQclear (res);
633 return cnt;
634}
635
636
637/**
510 * Entry point for the plugin. 638 * Entry point for the plugin.
511 * 639 *
512 * @param cls closure (the `struct GNUNET_DATACACHE_PluginEnvironmnet`) 640 * @param cls closure (the `struct GNUNET_DATACACHE_PluginEnvironmnet`)
@@ -534,6 +662,7 @@ libgnunet_plugin_datacache_postgres_init (void *cls)
534 api->put = &postgres_plugin_put; 662 api->put = &postgres_plugin_put;
535 api->del = &postgres_plugin_del; 663 api->del = &postgres_plugin_del;
536 api->get_random = &postgres_plugin_get_random; 664 api->get_random = &postgres_plugin_get_random;
665 api->get_closest = &postgres_plugin_get_closest;
537 LOG (GNUNET_ERROR_TYPE_INFO, 666 LOG (GNUNET_ERROR_TYPE_INFO,
538 "Postgres datacache running\n"); 667 "Postgres datacache running\n");
539 return api; 668 return api;