diff options
author | Christian Grothoff <christian@grothoff.org> | 2009-06-16 22:25:18 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2009-06-16 22:25:18 +0000 |
commit | b6bda27ce9a134c78c6084393b3370bf3691f206 (patch) | |
tree | da7395f6a4c3116be3f68dded9c4aee753399ce4 /src | |
parent | 147572ba9cf30a1ed7f14769c24e1c3f45385267 (diff) | |
download | gnunet-b6bda27ce9a134c78c6084393b3370bf3691f206.tar.gz gnunet-b6bda27ce9a134c78c6084393b3370bf3691f206.zip |
added bloomfilter
Diffstat (limited to 'src')
-rw-r--r-- | src/datastore/gnunet-service-datastore.c | 70 | ||||
-rw-r--r-- | src/datastore/plugin_datastore.h | 4 |
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; | |||
118 | static struct ReservationList *reservations; | 120 | static struct ReservationList *reservations; |
119 | 121 | ||
120 | /** | 122 | /** |
123 | * Bloomfilter to quickly tell if we don't have the content. | ||
124 | */ | ||
125 | static struct GNUNET_CONTAINER_BloomFilter *filter; | ||
126 | |||
127 | /** | ||
121 | * Static counter to produce reservation identifiers. | 128 | * Static counter to produce reservation identifiers. |
122 | */ | 129 | */ |
123 | static int reservation_gen; | 130 | static 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", "a)) | 857 | "DATASTORE", "QUOTA", "a)) |
@@ -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 | */ |
128 | typedef int (*PluginPut) (void *cls, | 130 | typedef int (*PluginPut) (void *cls, |
129 | const GNUNET_HashCode * key, | 131 | const GNUNET_HashCode * key, |