int main (int argc, char *argv[]) { struct GNUNET_CONTAINER_BloomFilter *bf; struct GNUNET_CONTAINER_BloomFilter *bfi; GNUNET_HashCode tmp; int i; int ok1; int ok2; int falseok; char buf[SIZE]; struct stat sbuf; GNUNET_log_setup ("test-container-bloomfilter", "WARNING", NULL); GNUNET_CRYPTO_seed_weak_random (1); if (0 == STAT (TESTFILE, &sbuf)) if (0 != UNLINK (TESTFILE)) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "unlink", TESTFILE); bf = GNUNET_CONTAINER_bloomfilter_load (TESTFILE, SIZE, K); for (i = 0; i < 200; i++) { nextHC (&tmp); GNUNET_CONTAINER_bloomfilter_add (bf, &tmp); } GNUNET_CRYPTO_seed_weak_random (1); ok1 = 0; for (i = 0; i < 200; i++) { nextHC (&tmp); if (GNUNET_CONTAINER_bloomfilter_test (bf, &tmp) == GNUNET_YES) ok1++; } if (ok1 != 200) { printf ("Got %d elements out of" "200 expected after insertion.\n", ok1); GNUNET_CONTAINER_bloomfilter_free (bf); return -1; } if (GNUNET_OK != GNUNET_CONTAINER_bloomfilter_get_raw_data (bf, buf, SIZE)) { GNUNET_CONTAINER_bloomfilter_free (bf); return -1; } GNUNET_CONTAINER_bloomfilter_free (bf); bf = GNUNET_CONTAINER_bloomfilter_load (TESTFILE, SIZE, K); GNUNET_assert (bf != NULL); bfi = GNUNET_CONTAINER_bloomfilter_init (buf, SIZE, K); GNUNET_assert (bfi != NULL); GNUNET_CRYPTO_seed_weak_random (1); ok1 = 0; ok2 = 0; for (i = 0; i < 200; i++) { nextHC (&tmp); if (GNUNET_CONTAINER_bloomfilter_test (bf, &tmp) == GNUNET_YES) ok1++; if (GNUNET_CONTAINER_bloomfilter_test (bfi, &tmp) == GNUNET_YES) ok2++; } if (ok1 != 200) { printf ("Got %d elements out of 200 " "expected after reloading.\n", ok1); GNUNET_CONTAINER_bloomfilter_free (bf); GNUNET_CONTAINER_bloomfilter_free (bfi); return -1; } if (ok2 != 200) { printf ("Got %d elements out of 200 " "expected after initialization.\n", ok2); GNUNET_CONTAINER_bloomfilter_free (bf); GNUNET_CONTAINER_bloomfilter_free (bfi); return -1; } GNUNET_CRYPTO_seed_weak_random (1); for (i = 0; i < 100; i++) { nextHC (&tmp); GNUNET_CONTAINER_bloomfilter_remove (bf, &tmp); GNUNET_CONTAINER_bloomfilter_remove (bfi, &tmp); } GNUNET_CRYPTO_seed_weak_random (1); ok1 = 0; ok2 = 0; for (i = 0; i < 200; i++) { nextHC (&tmp); if (GNUNET_CONTAINER_bloomfilter_test (bf, &tmp) == GNUNET_YES) ok1++; if (GNUNET_CONTAINER_bloomfilter_test (bfi, &tmp) == GNUNET_YES) ok2++; } if (ok1 != 100) { printf ("Expected 100 elements in loaded filter" " after adding 200 and deleting 100, got %d\n", ok1); GNUNET_CONTAINER_bloomfilter_free (bf); GNUNET_CONTAINER_bloomfilter_free (bfi); return -1; } if (ok2 != 200) { printf ("Expected 200 elements in initialized filter" " after adding 200 and deleting 100 " "(which should do nothing for a filter not backed by a file), got %d\n", ok2); GNUNET_CONTAINER_bloomfilter_free (bf); GNUNET_CONTAINER_bloomfilter_free (bfi); return -1; } GNUNET_CRYPTO_seed_weak_random (3); GNUNET_CONTAINER_bloomfilter_clear (bf); falseok = 0; for (i = 0; i < 1000; i++) { nextHC (&tmp); if (GNUNET_CONTAINER_bloomfilter_test (bf, &tmp) == GNUNET_YES) falseok++; } if (falseok > 0) { GNUNET_CONTAINER_bloomfilter_free (bf); GNUNET_CONTAINER_bloomfilter_free (bfi); return -1; } if (GNUNET_OK != GNUNET_CONTAINER_bloomfilter_or (bf, buf, SIZE)) { GNUNET_CONTAINER_bloomfilter_free (bf); GNUNET_CONTAINER_bloomfilter_free (bfi); return -1; } GNUNET_CRYPTO_seed_weak_random (2); i = 20; GNUNET_CONTAINER_bloomfilter_resize (bfi, &add_iterator, &i, SIZE * 2, K); GNUNET_CRYPTO_seed_weak_random (2); i = 20; GNUNET_CONTAINER_bloomfilter_resize (bf, &add_iterator, &i, SIZE * 2, K); GNUNET_CRYPTO_seed_weak_random (2); ok1 = 0; ok2 = 0; for (i = 0; i < 20; i++) { nextHC (&tmp); if (GNUNET_CONTAINER_bloomfilter_test (bf, &tmp) == GNUNET_YES) ok1++; if (GNUNET_CONTAINER_bloomfilter_test (bfi, &tmp) == GNUNET_YES) ok2++; } if (ok1 != 20) { printf ("Expected 20 elements in resized file-backed filter" " after adding 20, got %d\n", ok1); GNUNET_CONTAINER_bloomfilter_free (bf); GNUNET_CONTAINER_bloomfilter_free (bfi); return -1; } if (ok2 != 20) { printf ("Expected 20 elements in resized filter" " after adding 20, got %d\n", ok2); GNUNET_CONTAINER_bloomfilter_free (bf); GNUNET_CONTAINER_bloomfilter_free (bfi); return -1; } GNUNET_CONTAINER_bloomfilter_free (bf); GNUNET_CONTAINER_bloomfilter_free (bfi); GNUNET_break (0 == UNLINK (TESTFILE)); return 0; }
/** * Create a data cache. * * @param cfg configuration to use * @param section section in the configuration that contains our options * @return handle to use to access the service */ struct GNUNET_DATACACHE_Handle * GNUNET_DATACACHE_create (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section) { unsigned int bf_size; unsigned long long quota; struct GNUNET_DATACACHE_Handle *ret; char *libname; char *name; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_size (cfg, section, "QUOTA", "a)) { LOG (GNUNET_ERROR_TYPE_ERROR, _("No `%s' specified for `%s' in configuration!\n"), "QUOTA", section); return NULL; } if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, section, "DATABASE", &name)) { LOG (GNUNET_ERROR_TYPE_ERROR, _("No `%s' specified for `%s' in configuration!\n"), "DATABASE", section); return NULL; } bf_size = quota / 32; /* 8 bit per entry, 1 bit per 32 kb in DB */ ret = GNUNET_malloc (sizeof (struct GNUNET_DATACACHE_Handle)); if (GNUNET_YES != GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "DISABLE_BF")) { if (GNUNET_YES != GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "DISABLE_BF_RC")) { ret->bloom_name = GNUNET_DISK_mktemp ("gnunet-datacachebloom"); } if (NULL != ret->bloom_name) { ret->filter = GNUNET_CONTAINER_bloomfilter_load (ret->bloom_name, quota / 1024, /* 8 bit per entry in DB, expect 1k entries */ 5); } if (NULL == ret->filter) { ret->filter = GNUNET_CONTAINER_bloomfilter_init (NULL, bf_size, 5); /* approx. 3% false positives at max use */ } } ret->stats = GNUNET_STATISTICS_create ("datacache", cfg); ret->section = GNUNET_strdup (section); ret->env.cfg = cfg; ret->env.delete_notify = &env_delete_notify; ret->env.section = ret->section; ret->env.cls = ret; ret->env.delete_notify = &env_delete_notify; ret->env.quota = quota; LOG (GNUNET_ERROR_TYPE_INFO, _("Loading `%s' datacache plugin\n"), name); GNUNET_asprintf (&libname, "libgnunet_plugin_datacache_%s", name); ret->short_name = name; ret->lib_name = libname; ret->api = GNUNET_PLUGIN_load (libname, &ret->env); if (ret->api == NULL) { LOG (GNUNET_ERROR_TYPE_ERROR, _("Failed to load datacache plugin for `%s'\n"), name); GNUNET_DATACACHE_destroy (ret); return NULL; } return ret; }