aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2009-06-16 22:25:18 +0000
committerChristian Grothoff <christian@grothoff.org>2009-06-16 22:25:18 +0000
commitb6bda27ce9a134c78c6084393b3370bf3691f206 (patch)
treeda7395f6a4c3116be3f68dded9c4aee753399ce4 /src
parent147572ba9cf30a1ed7f14769c24e1c3f45385267 (diff)
downloadgnunet-b6bda27ce9a134c78c6084393b3370bf3691f206.tar.gz
gnunet-b6bda27ce9a134c78c6084393b3370bf3691f206.zip
added bloomfilter
Diffstat (limited to 'src')
-rw-r--r--src/datastore/gnunet-service-datastore.c70
-rw-r--r--src/datastore/plugin_datastore.h4
2 files changed, 65 insertions, 9 deletions
diff --git a/src/datastore/gnunet-service-datastore.c b/src/datastore/gnunet-service-datastore.c
index 9a24865da..98905dbd4 100644
--- a/src/datastore/gnunet-service-datastore.c
+++ b/src/datastore/gnunet-service-datastore.c
@@ -24,10 +24,12 @@
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 * 25 *
26 * TODO: 26 * TODO:
27 * 1) semantics of "PUT" (plugin) if entry exists (should likely 27 * quota management code:
28 * be similar to "UPDATE" (need to specify in PLUGIN API!) 28 * - track storage use
29 * 4) quota management code! 29 * - track reservations
30 * 5) add bloomfilter for efficiency! 30 * - refuse above-quota
31 * - content expiration job
32 * - near-quota low-priority content discard job
31 */ 33 */
32 34
33#include "platform.h" 35#include "platform.h"
@@ -118,6 +120,11 @@ static struct DatastorePlugin *plugin;
118static struct ReservationList *reservations; 120static struct ReservationList *reservations;
119 121
120/** 122/**
123 * Bloomfilter to quickly tell if we don't have the content.
124 */
125static struct GNUNET_CONTAINER_BloomFilter *filter;
126
127/**
121 * Static counter to produce reservation identifiers. 128 * Static counter to produce reservation identifiers.
122 */ 129 */
123static int reservation_gen; 130static int reservation_gen;
@@ -504,7 +511,12 @@ handle_put (void *cls,
504 ntohl(dm->anonymity), 511 ntohl(dm->anonymity),
505 GNUNET_TIME_absolute_ntoh(dm->expiration), 512 GNUNET_TIME_absolute_ntoh(dm->expiration),
506 &msg); 513 &msg);
507 transmit_status (client, ret, msg); 514 if (GNUNET_OK == ret)
515 GNUNET_CONTAINER_bloomfilter_add (filter,
516 &dm->key);
517 transmit_status (client,
518 GNUNET_SYSERR == ret ? GNUNET_SYSERR : GNUNET_OK,
519 msg);
508 GNUNET_free_non_null (msg); 520 GNUNET_free_non_null (msg);
509} 521}
510 522
@@ -521,6 +533,7 @@ handle_get (void *cls,
521 struct GNUNET_SERVER_Client *client, 533 struct GNUNET_SERVER_Client *client,
522 const struct GNUNET_MessageHeader *message) 534 const struct GNUNET_MessageHeader *message)
523{ 535{
536 static struct GNUNET_TIME_Absolute zero;
524 const struct GetMessage *msg; 537 const struct GetMessage *msg;
525 uint16_t size; 538 uint16_t size;
526 539
@@ -533,6 +546,15 @@ handle_get (void *cls,
533 return; 546 return;
534 } 547 }
535 msg = (const struct GetMessage*) message; 548 msg = (const struct GetMessage*) message;
549 if ( (size == sizeof(struct GetMessage)) &&
550 (GNUNET_YES != GNUNET_CONTAINER_bloomfilter_test (filter,
551 &msg->key)) )
552 {
553 /* don't bother database... */
554 transmit_item (client,
555 NULL, NULL, 0, NULL, 0, 0, 0, zero, 0);
556 return;
557 }
536 GNUNET_SERVER_client_drop (client); 558 GNUNET_SERVER_client_drop (client);
537 plugin->api->get (plugin->api->cls, 559 plugin->api->get (plugin->api->cls,
538 ((size == sizeof(struct GetMessage)) ? &msg->key : NULL), 560 ((size == sizeof(struct GetMessage)) ? &msg->key : NULL),
@@ -628,15 +650,17 @@ remove_callback (void *cls,
628 if (key == NULL) 650 if (key == NULL)
629 { 651 {
630 if (GNUNET_YES == rc->found) 652 if (GNUNET_YES == rc->found)
631 transmit_status (rc->client, GNUNET_OK, NULL); 653 transmit_status (rc->client, GNUNET_OK, NULL);
632 else 654 else
633 transmit_status (rc->client, GNUNET_SYSERR, _("Content not found")); 655 transmit_status (rc->client, GNUNET_SYSERR, _("Content not found"));
634 GNUNET_SERVER_client_drop (rc->client); 656 GNUNET_SERVER_client_drop (rc->client);
635 GNUNET_free (rc); 657 GNUNET_free (rc);
636 return GNUNET_OK; /* last item */ 658 return GNUNET_OK; /* last item */
637 } 659 }
638 rc->found = GNUNET_YES; 660 rc->found = GNUNET_YES;
639 plugin->api->next_request (next_cls, GNUNET_YES); 661 plugin->api->next_request (next_cls, GNUNET_YES);
662 GNUNET_CONTAINER_bloomfilter_remove (filter,
663 key);
640 return GNUNET_NO; 664 return GNUNET_NO;
641} 665}
642 666
@@ -825,6 +849,9 @@ run (void *cls,
825 struct GNUNET_SERVER_Handle *server, 849 struct GNUNET_SERVER_Handle *server,
826 struct GNUNET_CONFIGURATION_Handle *cfg) 850 struct GNUNET_CONFIGURATION_Handle *cfg)
827{ 851{
852 char *fn;
853 unsigned int bf_size;
854
828 if (GNUNET_OK != 855 if (GNUNET_OK !=
829 GNUNET_CONFIGURATION_get_value_number (cfg, 856 GNUNET_CONFIGURATION_get_value_number (cfg,
830 "DATASTORE", "QUOTA", &quota)) 857 "DATASTORE", "QUOTA", &quota))
@@ -835,9 +862,36 @@ run (void *cls,
835 "DATASTORE"); 862 "DATASTORE");
836 return; 863 return;
837 } 864 }
865 bf_size = quota / 32; /* 8 bit per entry, 1 bit per 32 kb in DB */
866 fn = NULL;
867 if ( (GNUNET_OK !=
868 GNUNET_CONFIGURATION_get_value_filename (cfg,
869 "DATASTORE",
870 "BLOOMFILTER",
871 &fn)) ||
872 (GNUNET_OK !=
873 GNUNET_DISK_directory_create_for_file (fn)) )
874 {
875 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
876 _("Could not use specified filename `%s' for bloomfilter.\n"),
877 fn != NULL ? fn : "");
878 GNUNET_free_non_null (fn);
879 fn = NULL;
880 }
881 filter = GNUNET_CONTAINER_bloomfilter_load (fn, bf_size, 5); /* approx. 3% false positives at max use */
882 GNUNET_free_non_null (fn);
883 if (filter == NULL)
884 {
885 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
886 _("Failed to initialize bloomfilter.\n"));
887 return;
888 }
838 plugin = load_plugin (cfg, sched); 889 plugin = load_plugin (cfg, sched);
839 if (NULL == plugin) 890 if (NULL == plugin)
840 return; 891 {
892 GNUNET_CONTAINER_bloomfilter_free (filter);
893 return;
894 }
841 GNUNET_SERVER_disconnect_notify (server, &cleanup_reservations, NULL); 895 GNUNET_SERVER_disconnect_notify (server, &cleanup_reservations, NULL);
842 GNUNET_SERVER_add_handlers (server, handlers); 896 GNUNET_SERVER_add_handlers (server, handlers);
843 GNUNET_SCHEDULER_add_delayed (sched, 897 GNUNET_SCHEDULER_add_delayed (sched,
diff --git a/src/datastore/plugin_datastore.h b/src/datastore/plugin_datastore.h
index 1214ae1be..8c42b8b98 100644
--- a/src/datastore/plugin_datastore.h
+++ b/src/datastore/plugin_datastore.h
@@ -123,7 +123,9 @@ typedef unsigned long long (*PluginGetSize) (void *cls);
123 * @param anonymity anonymity-level for the content 123 * @param anonymity anonymity-level for the content
124 * @param expiration expiration time for the content 124 * @param expiration expiration time for the content
125 * @param msg set to an error message (on failure) 125 * @param msg set to an error message (on failure)
126 * @return GNUNET_OK on success, GNUNET_SYSERR on failure 126 * @return GNUNET_OK on success, GNUNET_NO if the content
127 * was already present (and may have been updated);
128 * GNUNET_SYSERR on failure
127 */ 129 */
128typedef int (*PluginPut) (void *cls, 130typedef int (*PluginPut) (void *cls,
129 const GNUNET_HashCode * key, 131 const GNUNET_HashCode * key,