diff options
author | Christian Grothoff <christian@grothoff.org> | 2015-04-30 07:56:00 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2015-04-30 07:56:00 +0000 |
commit | 786745c969589eae2aa069885b40eba0f3989507 (patch) | |
tree | 6f5c8573b021ba628b4f135f3fb964728b3e1724 /src/datacache/plugin_datacache_postgres.c | |
parent | a49b0f351926cf4376a58937a94e37426e3ae167 (diff) | |
download | gnunet-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.c | 137 |
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 | */ | ||
527 | static unsigned int | ||
528 | postgres_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; |