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;
}
Пример #2
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", &quota))
  {
    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;
}