diff options
Diffstat (limited to 'src/datacache/plugin_datacache_sqlite.c')
-rw-r--r-- | src/datacache/plugin_datacache_sqlite.c | 115 |
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 | */ | ||
537 | static unsigned int | ||
538 | sqlite_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; |