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.c115
1 files changed, 115 insertions, 0 deletions
diff --git a/src/datacache/plugin_datacache_sqlite.c b/src/datacache/plugin_datacache_sqlite.c
index d28233772..8dd38a3ac 100644
--- a/src/datacache/plugin_datacache_sqlite.c
+++ b/src/datacache/plugin_datacache_sqlite.c
@@ -522,6 +522,120 @@ sqlite_plugin_get_random (void *cls,
522 522
523 523
524/** 524/**
525 * Iterate over the results that are "close" to a particular key in
526 * the datacache. "close" is defined as numerically larger than @a
527 * key (when interpreted as a circular address space), with small
528 * distance.
529 *
530 * @param cls closure (internal context for the plugin)
531 * @param key area of the keyspace to look into
532 * @param num_results number of results that should be returned to @a iter
533 * @param iter maybe NULL (to just count)
534 * @param iter_cls closure for @a iter
535 * @return the number of results found
536 */
537static unsigned int
538sqlite_plugin_get_closest (void *cls,
539 const struct GNUNET_HashCode *key,
540 unsigned int num_results,
541 GNUNET_DATACACHE_Iterator iter,
542 void *iter_cls)
543{
544 struct Plugin *plugin = cls;
545 sqlite3_stmt *stmt;
546 struct GNUNET_TIME_Absolute now;
547 struct GNUNET_TIME_Absolute exp;
548 unsigned int size;
549 const char *dat;
550 unsigned int cnt;
551 unsigned int psize;
552 unsigned int type;
553 int64_t ntime;
554 const struct GNUNET_PeerIdentity *path;
555
556 now = GNUNET_TIME_absolute_get ();
557 LOG (GNUNET_ERROR_TYPE_DEBUG,
558 "Processing GET_CLOSEST for key `%4s'\n",
559 GNUNET_h2s (key));
560 if (SQLITE_OK !=
561 sq_prepare (plugin->dbh,
562 "SELECT value,expire,path,type,key FROM ds090 WHERE key>=? AND expire >= ? ORDER BY KEY ASC LIMIT ?",
563 &stmt))
564 {
565 LOG_SQLITE (plugin->dbh,
566 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
567 "sq_prepare");
568 return 0;
569 }
570 ntime = (int64_t) now.abs_value_us;
571 GNUNET_assert (ntime >= 0);
572 if ((SQLITE_OK !=
573 sqlite3_bind_blob (stmt,
574 1,
575 key,
576 sizeof (struct GNUNET_HashCode),
577 SQLITE_TRANSIENT)) ||
578 (SQLITE_OK != sqlite3_bind_int64 (stmt, 2, now.abs_value_us)) ||
579 (SQLITE_OK != sqlite3_bind_int (stmt, 3, num_results)) )
580 {
581 LOG_SQLITE (plugin->dbh,
582 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
583 "sqlite3_bind_xxx");
584 sqlite3_finalize (stmt);
585 return 0;
586 }
587 cnt = 0;
588 while (SQLITE_ROW == sqlite3_step (stmt))
589 {
590 if (sizeof (struct GNUNET_HashCode) !=
591 sqlite3_column_bytes (stmt, 4))
592 {
593 GNUNET_break (0);
594 break;
595 }
596 size = sqlite3_column_bytes (stmt, 0);
597 dat = sqlite3_column_blob (stmt, 0);
598 exp.abs_value_us = sqlite3_column_int64 (stmt, 1);
599 psize = sqlite3_column_bytes (stmt, 2);
600 type = sqlite3_column_int (stmt, 3);
601 key = sqlite3_column_blob (stmt, 4);
602 if (0 != psize % sizeof (struct GNUNET_PeerIdentity))
603 {
604 GNUNET_break (0);
605 psize = 0;
606 }
607 psize /= sizeof (struct GNUNET_PeerIdentity);
608 if (0 != psize)
609 path = sqlite3_column_blob (stmt, 2);
610 else
611 path = NULL;
612 ntime = (int64_t) exp.abs_value_us;
613 if (ntime == INT64_MAX)
614 exp = GNUNET_TIME_UNIT_FOREVER_ABS;
615 cnt++;
616 LOG (GNUNET_ERROR_TYPE_DEBUG,
617 "Found %u-byte result at %s when processing GET_CLOSE\n",
618 (unsigned int) size,
619 GNUNET_h2s (key));
620 if (GNUNET_OK != iter (iter_cls,
621 key,
622 size,
623 dat,
624 type,
625 exp,
626 psize,
627 path))
628 {
629 sqlite3_finalize (stmt);
630 break;
631 }
632 }
633 sqlite3_finalize (stmt);
634 return cnt;
635}
636
637
638/**
525 * Entry point for the plugin. 639 * Entry point for the plugin.
526 * 640 *
527 * @param cls closure (the `struct GNUNET_DATACACHE_PluginEnvironment`) 641 * @param cls closure (the `struct GNUNET_DATACACHE_PluginEnvironment`)
@@ -595,6 +709,7 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
595 api->put = &sqlite_plugin_put; 709 api->put = &sqlite_plugin_put;
596 api->del = &sqlite_plugin_del; 710 api->del = &sqlite_plugin_del;
597 api->get_random = &sqlite_plugin_get_random; 711 api->get_random = &sqlite_plugin_get_random;
712 api->get_closest = &sqlite_plugin_get_closest;
598 LOG (GNUNET_ERROR_TYPE_INFO, 713 LOG (GNUNET_ERROR_TYPE_INFO,
599 "Sqlite datacache running\n"); 714 "Sqlite datacache running\n");
600 return api; 715 return api;