gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [gnunet] branch master updated: first half of new BLOCK API


From: gnunet
Subject: [GNUnet-SVN] [gnunet] branch master updated: first half of new BLOCK API to generalize duplicate detection beyond BFs
Date: Mon, 20 Feb 2017 15:08:14 +0100

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository gnunet.

The following commit(s) were added to refs/heads/master by this push:
     new a3882b58f first half of new BLOCK API to generalize duplicate 
detection beyond BFs
a3882b58f is described below

commit a3882b58f1c5976677aa65b0af8a48e8e946b06e
Author: Christian Grothoff <address@hidden>
AuthorDate: Mon Feb 20 15:09:00 2017 +0100

    first half of new BLOCK API to generalize duplicate detection beyond BFs
---
 src/block/Makefile.am                |  15 ++-
 src/block/bg_bf.c                    | 173 +++++++++++++++++++++++++++++++++++
 src/block/block.c                    |  72 +++++++++++++++
 src/dht/Makefile.am                  |   1 +
 src/dht/plugin_block_dht.c           |  36 +++++++-
 src/dns/plugin_block_dns.c           |   6 +-
 src/fs/Makefile.am                   |   1 +
 src/fs/plugin_block_fs.c             |  48 +++++++++-
 src/gns/Makefile.am                  |   1 +
 src/gns/plugin_block_gns.c           |  45 ++++++++-
 src/include/gnunet_block_group_lib.h |  82 +++++++++++++++++
 src/include/gnunet_block_lib.h       |  51 +++++++++++
 src/include/gnunet_block_plugin.h    |  87 +++++++++++++++++-
 src/regex/Makefile.am                |   1 +
 src/regex/plugin_block_regex.c       |  37 +++++++-
 15 files changed, 645 insertions(+), 11 deletions(-)

diff --git a/src/block/Makefile.am b/src/block/Makefile.am
index c54a4c246..4a6d8e71e 100644
--- a/src/block/Makefile.am
+++ b/src/block/Makefile.am
@@ -11,7 +11,9 @@ if USE_COVERAGE
   AM_CFLAGS = --coverage
 endif
 
-lib_LTLIBRARIES = libgnunetblock.la
+lib_LTLIBRARIES = \
+  libgnunetblock.la \
+  libgnunetblockgroup.la
 
 plugin_LTLIBRARIES = \
   libgnunet_plugin_block_test.la
@@ -49,3 +51,14 @@ libgnunetblock_la_DEPENDENCIES = \
 libgnunetblock_la_LDFLAGS = \
   $(GN_LIB_LDFLAGS) \
   -version-info 0:0:0
+
+
+libgnunetblockgroup_la_SOURCES = \
+  bg_bf.c
+libgnunetblockgroup_la_LIBADD = \
+ $(top_builddir)/src/util/libgnunetutil.la
+libgnunetblockgroup_la_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la
+libgnunetblockgroup_la_LDFLAGS = \
+  $(GN_LIB_LDFLAGS) \
+  -version-info 0:0:0
diff --git a/src/block/bg_bf.c b/src/block/bg_bf.c
new file mode 100644
index 000000000..f03ae5247
--- /dev/null
+++ b/src/block/bg_bf.c
@@ -0,0 +1,173 @@
+/*
+     This file is part of GNUnet
+     Copyright (C) 2017 GNUnet e.V.
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 3, or (at your
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+     Boston, MA 02110-1301, USA.
+*/
+/**
+ * @file block/bg_bf.c
+ * @brief implementation of a block group using a Bloom filter
+ *        to drop duplicate blocks
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_block_group_lib.h"
+#include "gnunet_block_plugin.h"
+
+
+/**
+ * Internal data structure for a block group.
+ */
+struct BfGroupInternals
+{
+  /**
+   * A Bloom filter to weed out duplicate replies probabilistically.
+   */
+  struct GNUNET_CONTAINER_BloomFilter *bf;
+
+  /**
+   * Set from the nonce to mingle the hashes before going into the @e bf.
+   */
+  uint32_t bf_mutator;
+
+  /**
+   * Size of @a bf.
+   */
+  uint32_t bf_size;
+
+};
+
+
+/**
+ * Serialize state of a block group.
+ *
+ * @param bg group to serialize
+ * @param[out] raw_data set to the serialized state
+ * @param[out] raw_data_size set to the number of bytes in @a raw_data
+ * @return #GNUNET_OK on success, #GNUNET_NO if serialization is not
+ *         supported, #GNUNET_SYSERR on error
+ */
+static int
+bf_group_serialize_cb (struct GNUNET_BLOCK_Group *bg,
+                       void **raw_data,
+                       size_t *raw_data_size)
+{
+  struct BfGroupInternals *gi = bg->internal_cls;
+  char *raw;
+
+  raw = GNUNET_malloc (gi->bf_size);
+  if (GNUNET_OK !=
+      GNUNET_CONTAINER_bloomfilter_get_raw_data (gi->bf,
+                                                 raw,
+                                                 gi->bf_size))
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  *raw_data = raw;
+  *raw_data_size = gi->bf_size;
+  return GNUNET_OK;
+}
+
+
+/**
+ * Destroy resources used by a block group.
+ *
+ * @param bg group to destroy, NULL is allowed
+ */
+static void
+bf_group_destroy_cb (struct GNUNET_BLOCK_Group *bg)
+{
+  struct BfGroupInternals *gi = bg->internal_cls;
+
+  GNUNET_CONTAINER_bloomfilter_free (gi->bf);
+  GNUNET_free (gi);
+  GNUNET_free (bg);
+}
+
+
+/**
+ * Create a new block group that filters duplicates using a Bloom filter.
+ *
+ * @param ctx block context in which the block group is created
+ * @param bf_size size of the Bloom filter
+ * @param bf_k K-value for the Bloom filter
+ * @param type block type
+ * @param nonce random value used to seed the group creation
+ * @param raw_data optional serialized prior state of the group, NULL if 
unavailable/fresh
+ * @param raw_data_size number of bytes in @a raw_data, 0 if unavailable/fresh
+ * @return block group handle, NULL if block groups are not supported
+ *         by this @a type of block (this is not an error)
+ */
+struct GNUNET_BLOCK_Group *
+GNUNET_BLOCK_GROUP_bf_create (void *cls,
+                              size_t bf_size,
+                              unsigned int bf_k,
+                              enum GNUNET_BLOCK_Type type,
+                              uint32_t nonce,
+                              const void *raw_data,
+                              size_t raw_data_size)
+{
+  struct BfGroupInternals *gi;
+  struct GNUNET_BLOCK_Group *bg;
+
+  gi = GNUNET_new (struct BfGroupInternals);
+  gi->bf = GNUNET_CONTAINER_bloomfilter_init ((bf_size != raw_data_size) ? 
NULL : raw_data,
+                                              bf_size,
+                                              bf_k);
+  gi->bf_mutator = nonce;
+  gi->bf_size = bf_size;
+  bg = GNUNET_new (struct GNUNET_BLOCK_Group);
+  bg->type = type;
+  bg->serialize_cb = &bf_group_serialize_cb;
+  bg->destroy_cb = &bf_group_destroy_cb;
+  bg->internal_cls = gi;
+  return bg;
+}
+
+
+/**
+ * Test if @a hc is contained in the Bloom filter of @a bg.  If so,
+ * return #GNUNET_YES.  If not, add @a hc to the Bloom filter and
+ * return #GNUNET_NO.
+ *
+ * @param bg block group to use for testing
+ * @param hc hash of element to evaluate
+ * @return #GNUNET_YES if @a hc is (likely) a duplicate
+ *         #GNUNET_NO if @a hc was definitively not in @bg (but now is)
+ */
+int
+GNUNET_BLOCK_GROUP_bf_test_and_set (struct GNUNET_BLOCK_Group *bg,
+                                    const struct GNUNET_HashCode *hc)
+{
+  struct BfGroupInternals *gi = bg->internal_cls;
+  struct GNUNET_HashCode mhash;
+
+  GNUNET_BLOCK_mingle_hash (hc,
+                            gi->bf_mutator,
+                            &mhash);
+  if (GNUNET_YES ==
+      GNUNET_CONTAINER_bloomfilter_test (gi->bf,
+                                         &mhash))
+    return GNUNET_YES;
+  GNUNET_CONTAINER_bloomfilter_add (gi->bf,
+                                    &mhash);
+  return GNUNET_NO;
+}
+
+
+/* end of bg_bf.c */
diff --git a/src/block/block.c b/src/block/block.c
index c104f4bd1..d4f5462dd 100644
--- a/src/block/block.c
+++ b/src/block/block.c
@@ -159,6 +159,46 @@ GNUNET_BLOCK_context_destroy (struct GNUNET_BLOCK_Context 
*ctx)
 
 
 /**
+ * Serialize state of a block group.
+ *
+ * @param bg group to serialize
+ * @param[out] raw_data set to the serialized state
+ * @param[out] raw_data_size set to the number of bytes in @a raw_data
+ * @return #GNUNET_OK on success, #GNUNET_NO if serialization is not
+ *         supported, #GNUNET_SYSERR on error
+ */
+int
+GNUNET_BLOCK_group_serialize (struct GNUNET_BLOCK_Group *bg,
+                              void **raw_data,
+                              size_t *raw_data_size)
+{
+  *raw_data = NULL;
+  *raw_data_size = 0;
+  if (NULL == bg)
+    return GNUNET_NO;
+  if (NULL == bg->serialize_cb)
+    return GNUNET_NO;
+  return bg->serialize_cb (bg,
+                           raw_data,
+                           raw_data_size);
+}
+
+
+/**
+ * Destroy resources used by a block group.
+ *
+ * @param bg group to destroy, NULL is allowed
+ */
+void
+GNUNET_BLOCK_group_destroy (struct GNUNET_BLOCK_Group *bg)
+{
+  if (NULL == bg)
+    return;
+  bg->destroy_cb (bg);
+}
+
+
+/**
  * Find a plugin for the given type.
  *
  * @param ctx context to search
@@ -189,6 +229,38 @@ find_plugin (struct GNUNET_BLOCK_Context *ctx,
 
 
 /**
+ * Create a new block group.
+ *
+ * @param ctx block context in which the block group is created
+ * @param type type of the block for which we are creating the group
+ * @param nonce random value used to seed the group creation
+ * @param raw_data optional serialized prior state of the group, NULL if 
unavailable/fresh
+ * @param raw_data_size number of bytes in @a raw_data, 0 if unavailable/fresh
+ * @return block group handle, NULL if block groups are not supported
+ *         by this @a type of block (this is not an error)
+ */
+struct GNUNET_BLOCK_Group *
+GNUNET_BLOCK_group_create (struct GNUNET_BLOCK_Context *ctx,
+                           enum GNUNET_BLOCK_Type type,
+                           uint32_t nonce,
+                           const void *raw_data,
+                           size_t raw_data_size)
+{
+  struct GNUNET_BLOCK_PluginFunctions *plugin;
+
+  plugin = find_plugin (ctx,
+                        type);
+  if (NULL == plugin->create_group)
+    return NULL;
+  return plugin->create_group (plugin->cls,
+                               type,
+                               nonce,
+                               raw_data,
+                               raw_data_size);
+}
+
+
+/**
  * Function called to validate a reply or a request.  For
  * request evaluation, simply pass "NULL" for the reply_block.
  * Note that it is assumed that the reply has already been
diff --git a/src/dht/Makefile.am b/src/dht/Makefile.am
index 26beb300b..93dae9f6e 100644
--- a/src/dht/Makefile.am
+++ b/src/dht/Makefile.am
@@ -40,6 +40,7 @@ libgnunet_plugin_block_dht_la_SOURCES = \
 libgnunet_plugin_block_dht_la_LIBADD = \
   $(top_builddir)/src/hello/libgnunethello.la \
   $(top_builddir)/src/block/libgnunetblock.la \
+  $(top_builddir)/src/block/libgnunetblockgroup.la \
   $(top_builddir)/src/util/libgnunetutil.la \
   $(LTLIBINTL)
 libgnunet_plugin_block_dht_la_LDFLAGS = \
diff --git a/src/dht/plugin_block_dht.c b/src/dht/plugin_block_dht.c
index 4256a0fe6..4c5f122a4 100644
--- a/src/dht/plugin_block_dht.c
+++ b/src/dht/plugin_block_dht.c
@@ -25,14 +25,47 @@
  *        DHT (see fs block plugin)
  * @author Christian Grothoff
  */
-
 #include "platform.h"
 #include "gnunet_constants.h"
 #include "gnunet_hello_lib.h"
 #include "gnunet_block_plugin.h"
+#include "gnunet_block_group_lib.h"
 
 #define DEBUG_DHT GNUNET_EXTRA_LOGGING
 
+/**
+ * How big is the BF we use for DHT blocks?
+ */
+#define DHT_BF_SIZE 8
+
+
+/**
+ * Create a new block group.
+ *
+ * @param ctx block context in which the block group is created
+ * @param type type of the block for which we are creating the group
+ * @param nonce random value used to seed the group creation
+ * @param raw_data optional serialized prior state of the group, NULL if 
unavailable/fresh
+ * @param raw_data_size number of bytes in @a raw_data, 0 if unavailable/fresh
+ * @return block group handle, NULL if block groups are not supported
+ *         by this @a type of block (this is not an error)
+ */
+static struct GNUNET_BLOCK_Group *
+block_plugin_dht_create_group (void *cls,
+                               enum GNUNET_BLOCK_Type type,
+                               uint32_t nonce,
+                               const void *raw_data,
+                               size_t raw_data_size)
+{
+  return GNUNET_BLOCK_GROUP_bf_create (cls,
+                                       DHT_BF_SIZE,
+                                       GNUNET_CONSTANTS_BLOOMFILTER_K,
+                                       type,
+                                       nonce,
+                                       raw_data,
+                                       raw_data_size);
+}
+
 
 /**
  * Function called to validate a reply or a request.  For
@@ -182,6 +215,7 @@ libgnunet_plugin_block_dht_init (void *cls)
   api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions);
   api->evaluate = &block_plugin_dht_evaluate;
   api->get_key = &block_plugin_dht_get_key;
+  api->create_group = &block_plugin_dht_create_group;
   api->types = types;
   return api;
 }
diff --git a/src/dns/plugin_block_dns.c b/src/dns/plugin_block_dns.c
index 8c6ec93ee..e4bc9209c 100644
--- a/src/dns/plugin_block_dns.c
+++ b/src/dns/plugin_block_dns.c
@@ -96,9 +96,9 @@ block_plugin_dns_evaluate (void *cls,
     }
     if (GNUNET_OK !=
         GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_DNS_RECORD,
-                                 &ad->purpose,
-                                 &ad->signature,
-                                 &ad->peer.public_key))
+                                    &ad->purpose,
+                                    &ad->signature,
+                                    &ad->peer.public_key))
     {
       GNUNET_break_op (0);
       return GNUNET_BLOCK_EVALUATION_RESULT_INVALID;
diff --git a/src/fs/Makefile.am b/src/fs/Makefile.am
index 75451c7f6..4374d45ea 100644
--- a/src/fs/Makefile.am
+++ b/src/fs/Makefile.am
@@ -219,6 +219,7 @@ gnunet_unindex_LDADD = \
 libgnunet_plugin_block_fs_la_SOURCES = \
   plugin_block_fs.c
 libgnunet_plugin_block_fs_la_LIBADD = \
+  $(top_builddir)/src/block/libgnunetblockgroup.la \
   $(top_builddir)/src/block/libgnunetblock.la \
   libgnunetfs.la \
   $(top_builddir)/src/util/libgnunetutil.la \
diff --git a/src/fs/plugin_block_fs.c b/src/fs/plugin_block_fs.c
index 415a2e3ed..038734082 100644
--- a/src/fs/plugin_block_fs.c
+++ b/src/fs/plugin_block_fs.c
@@ -23,12 +23,12 @@
  * @brief blocks used for file-sharing
  * @author Christian Grothoff
  */
-
 #include "platform.h"
 #include "gnunet_block_plugin.h"
 #include "gnunet_fs_service.h"
 #include "block_fs.h"
 #include "gnunet_signatures.h"
+#include "gnunet_block_group_lib.h"
 
 
 /**
@@ -38,6 +38,51 @@
 #define BLOOMFILTER_K 16
 
 /**
+ * How big is the BF we use for FS blocks?
+ */
+#define FS_BF_SIZE 8
+
+
+/**
+ * Create a new block group.
+ *
+ * @param ctx block context in which the block group is created
+ * @param type type of the block for which we are creating the group
+ * @param nonce random value used to seed the group creation
+ * @param raw_data optional serialized prior state of the group, NULL if 
unavailable/fresh
+ * @param raw_data_size number of bytes in @a raw_data, 0 if unavailable/fresh
+ * @return block group handle, NULL if block groups are not supported
+ *         by this @a type of block (this is not an error)
+ */
+static struct GNUNET_BLOCK_Group *
+block_plugin_fs_create_group (void *cls,
+                               enum GNUNET_BLOCK_Type type,
+                               uint32_t nonce,
+                               const void *raw_data,
+                               size_t raw_data_size)
+{
+  switch (type)
+  {
+  case GNUNET_BLOCK_TYPE_FS_DBLOCK:
+    return NULL;
+  case GNUNET_BLOCK_TYPE_FS_IBLOCK:
+    return NULL;
+  case GNUNET_BLOCK_TYPE_FS_UBLOCK:
+    return GNUNET_BLOCK_GROUP_bf_create (cls,
+                                         FS_BF_SIZE,
+                                         BLOOMFILTER_K,
+                                         type,
+                                         nonce,
+                                         raw_data,
+                                         raw_data_size);
+  default:
+    GNUNET_break (0);
+    return NULL;
+  }
+}
+
+
+/**
  * Function called to validate a reply or a request.  For
  * request evaluation, simply pass "NULL" for the reply_block.
  * Note that it is assumed that the reply has already been
@@ -214,6 +259,7 @@ libgnunet_plugin_block_fs_init (void *cls)
   api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions);
   api->evaluate = &block_plugin_fs_evaluate;
   api->get_key = &block_plugin_fs_get_key;
+  api->create_group = &block_plugin_fs_create_group;
   api->types = types;
   return api;
 }
diff --git a/src/gns/Makefile.am b/src/gns/Makefile.am
index 8f27890d7..d59908c0a 100644
--- a/src/gns/Makefile.am
+++ b/src/gns/Makefile.am
@@ -227,6 +227,7 @@ libgnunet_plugin_block_gns_la_SOURCES = \
 libgnunet_plugin_block_gns_la_LIBADD = \
   $(top_builddir)/src/util/libgnunetutil.la \
   $(top_builddir)/src/block/libgnunetblock.la \
+  $(top_builddir)/src/block/libgnunetblockgroup.la \
   $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la
 libgnunet_plugin_block_gns_la_LDFLAGS = \
   $(GN_PLUGIN_LDFLAGS)
diff --git a/src/gns/plugin_block_gns.c b/src/gns/plugin_block_gns.c
index f0e34a04b..8d3e84042 100644
--- a/src/gns/plugin_block_gns.c
+++ b/src/gns/plugin_block_gns.c
@@ -22,9 +22,11 @@
  * @file gns/plugin_block_gns.c
  * @brief blocks used for GNS records
  * @author Martin Schanzenbach
+ * @author Christian Grothoff
  */
 
 #include "platform.h"
+#include "gnunet_block_group_lib.h"
 #include "gnunet_block_plugin.h"
 #include "gnunet_namestore_service.h"
 #include "gnunet_signatures.h"
@@ -36,6 +38,40 @@
 #define BLOOMFILTER_K 16
 
 /**
+ * How big is the BF we use for GNS blocks?
+ */
+#define GNS_BF_SIZE 8
+
+
+/**
+ * Create a new block group.
+ *
+ * @param ctx block context in which the block group is created
+ * @param type type of the block for which we are creating the group
+ * @param nonce random value used to seed the group creation
+ * @param raw_data optional serialized prior state of the group, NULL if 
unavailable/fresh
+ * @param raw_data_size number of bytes in @a raw_data, 0 if unavailable/fresh
+ * @return block group handle, NULL if block groups are not supported
+ *         by this @a type of block (this is not an error)
+ */
+static struct GNUNET_BLOCK_Group *
+block_plugin_gns_create_group (void *cls,
+                               enum GNUNET_BLOCK_Type type,
+                               uint32_t nonce,
+                               const void *raw_data,
+                               size_t raw_data_size)
+{
+  return GNUNET_BLOCK_GROUP_bf_create (cls,
+                                       GNS_BF_SIZE,
+                                       BLOOMFILTER_K,
+                                       type,
+                                       nonce,
+                                       raw_data,
+                                       raw_data_size);
+}
+
+
+/**
  * Function called to validate a reply or a request.  For
  * request evaluation, simply pass "NULL" for the reply_block.
  * Note that it is assumed that the reply has already been
@@ -141,9 +177,11 @@ block_plugin_gns_evaluate (void *cls,
  *         (or if extracting a key from a block of this type does not work)
  */
 static int
-block_plugin_gns_get_key (void *cls, enum GNUNET_BLOCK_Type type,
-                         const void *reply_block, size_t reply_block_size,
-                         struct GNUNET_HashCode *key)
+block_plugin_gns_get_key (void *cls,
+                          enum GNUNET_BLOCK_Type type,
+                          const void *reply_block,
+                          size_t reply_block_size,
+                          struct GNUNET_HashCode *key)
 {
   const struct GNUNET_GNSRECORD_Block *block;
 
@@ -178,6 +216,7 @@ libgnunet_plugin_block_gns_init (void *cls)
   api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions);
   api->evaluate = &block_plugin_gns_evaluate;
   api->get_key = &block_plugin_gns_get_key;
+  api->create_group = &block_plugin_gns_create_group;
   api->types = types;
   return api;
 }
diff --git a/src/include/gnunet_block_group_lib.h 
b/src/include/gnunet_block_group_lib.h
new file mode 100644
index 000000000..5fa14ce00
--- /dev/null
+++ b/src/include/gnunet_block_group_lib.h
@@ -0,0 +1,82 @@
+/*
+     This file is part of GNUnet.
+     Copyright (C) 2010 GNUnet e.V.
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 3, or (at your
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+     Boston, MA 02110-1301, USA.
+*/
+
+/**
+ * @author Christian Grothoff
+ *
+ * @file
+ * Library for creating block groups (to be used by block plugins)
+ *
+ * @defgroup block  Block group library
+ * Library for data group management
+ * @{
+ */
+#ifndef GNUNET_BLOCK_GROUP_LIB_H
+#define GNUNET_BLOCK_GROUP_LIB_H
+
+#include "gnunet_util_lib.h"
+#include "gnunet_block_lib.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#if 0                           /* keep Emacsens' auto-indent happy */
+}
+#endif
+#endif
+
+
+/**
+ * Create a new block group that filters duplicates using a Bloom filter.
+ *
+ * @param ctx block context in which the block group is created
+ * @param bf_size size of the Bloom filter
+ * @param bf_k K-value for the Bloom filter
+ * @param type block type
+ * @param nonce random value used to seed the group creation
+ * @param raw_data optional serialized prior state of the group, NULL if 
unavailable/fresh
+ * @param raw_data_size number of bytes in @a raw_data, 0 if unavailable/fresh
+ * @return block group handle, NULL if block groups are not supported
+ *         by this @a type of block (this is not an error)
+ */
+struct GNUNET_BLOCK_Group *
+GNUNET_BLOCK_GROUP_bf_create (void *cls,
+                              size_t bf_size,
+                              unsigned int bf_k,
+                              enum GNUNET_BLOCK_Type type,
+                              uint32_t nonce,
+                              const void *raw_data,
+                              size_t raw_data_size);
+
+
+
+#if 0                           /* keep Emacsens' auto-indent happy */
+{
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+/* ifndef GNUNET_BLOCK_GROUP_LIB_H */
+#endif
+
+/** @} */  /* end of group */
+
+/* end of gnunet_block_group_lib.h */
diff --git a/src/include/gnunet_block_lib.h b/src/include/gnunet_block_lib.h
index b21b3496b..0f0fee499 100644
--- a/src/include/gnunet_block_lib.h
+++ b/src/include/gnunet_block_lib.h
@@ -230,6 +230,57 @@ GNUNET_BLOCK_context_destroy (struct GNUNET_BLOCK_Context 
*ctx);
 
 
 /**
+ * Handle for a group of elements that will be evaluated together.
+ * They must all be of the same type.  A block group allows the
+ * plugin to keep some state across individual evaluations.
+ */
+struct GNUNET_BLOCK_Group;
+
+
+/**
+ * Create a new block group.
+ *
+ * @param ctx block context in which the block group is created
+ * @param type type of the block for which we are creating the group
+ * @param nonce random value used to seed the group creation
+ * @param raw_data optional serialized prior state of the group, NULL if 
unavailable/fresh
+ * @param raw_data_size number of bytes in @a raw_data, 0 if unavailable/fresh
+ * @return block group handle, NULL if block groups are not supported
+ *         by this @a type of block (this is not an error)
+ */
+struct GNUNET_BLOCK_Group *
+GNUNET_BLOCK_group_create (struct GNUNET_BLOCK_Context *ctx,
+                           enum GNUNET_BLOCK_Type type,
+                           uint32_t nonce,
+                           const void *raw_data,
+                           size_t raw_data_size);
+
+
+/**
+ * Serialize state of a block group.
+ *
+ * @param bg group to serialize
+ * @param[out] raw_data set to the serialized state
+ * @param[out] raw_data_size set to the number of bytes in @a raw_data
+ * @return #GNUNET_OK on success, #GNUNET_NO if serialization is not
+ *         supported, #GNUNET_SYSERR on error
+ */
+int
+GNUNET_BLOCK_group_serialize (struct GNUNET_BLOCK_Group *bg,
+                              void **raw_data,
+                              size_t *raw_data_size);
+
+
+/**
+ * Destroy resources used by a block group.
+ *
+ * @param bg group to destroy, NULL is allowed
+ */
+void
+GNUNET_BLOCK_group_destroy (struct GNUNET_BLOCK_Group *bg);
+
+
+/**
  * Function called to validate a reply or a request.  For
  * request evaluation, simply pass "NULL" for the @a reply_block.
  * Note that it is assumed that the reply has already been
diff --git a/src/include/gnunet_block_plugin.h 
b/src/include/gnunet_block_plugin.h
index 5c320457e..d7454b5d5 100644
--- a/src/include/gnunet_block_plugin.h
+++ b/src/include/gnunet_block_plugin.h
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet
-     Copyright (C) 2010,2013 GNUnet e.V.
+     Copyright (C) 2010,2013,2017 GNUnet e.V.
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -40,6 +40,86 @@
 
 
 /**
+ * Serialize state of a block group.
+ *
+ * @param bg group to serialize
+ * @param[out] raw_data set to the serialized state
+ * @param[out] raw_data_size set to the number of bytes in @a raw_data
+ * @return #GNUNET_OK on success, #GNUNET_NO if serialization is not
+ *         supported, #GNUNET_SYSERR on error
+ */
+typedef int
+(*GNUNET_BLOCK_GroupSerializeFunction)(struct GNUNET_BLOCK_Group *bg,
+                                       void **raw_data,
+                                       size_t *raw_data_size);
+
+
+/**
+ * Destroy resources used by a block group.
+ *
+ * @param bg group to destroy, NULL is allowed
+ */
+typedef void
+(*GNUNET_BLOCK_GroupDestroyFunction)(struct GNUNET_BLOCK_Group *bg);
+
+
+/**
+ * Block group data.  The plugin must initialize the callbacks
+ * and can use the @e internal_cls as it likes.
+ */
+struct GNUNET_BLOCK_Group
+{
+
+  /**
+   * Context owning the block group. Set by the main block library.
+   */
+  struct GNUENT_BLOCK_Context *ctx;
+
+  /**
+   * Type for the block group.  Set by the main block library.
+   */
+  enum GNUNET_BLOCK_Type type;
+
+  /**
+   * Serialize the block group data, can be NULL if
+   * not supported.
+   */
+  GNUNET_BLOCK_GroupSerializeFunction serialize_cb;
+
+  /**
+   * Function to call to destroy the block group.
+   * Must not be NULL.
+   */
+  GNUNET_BLOCK_GroupDestroyFunction destroy_cb;
+
+  /**
+   * Internal data structure of the plugin.
+   */
+  void *internal_cls;
+
+};
+
+
+/**
+ * Create a new block group.
+ *
+ * @param ctx block context in which the block group is created
+ * @param type type of the block for which we are creating the group
+ * @param nonce random value used to seed the group creation
+ * @param raw_data optional serialized prior state of the group, NULL if 
unavailable/fresh
+ * @param raw_data_size number of bytes in @a raw_data, 0 if unavailable/fresh
+ * @return block group handle, NULL if block groups are not supported
+ *         by this @a type of block (this is not an error)
+ */
+typedef struct GNUNET_BLOCK_Group *
+(*GNUNET_BLOCK_GroupCreateFunction)(void *cls,
+                                    enum GNUNET_BLOCK_Type type,
+                                    uint32_t nonce,
+                                    const void *raw_data,
+                                    size_t raw_data_size);
+
+
+/**
  * Function called to validate a reply or a request.  For
  * request evaluation, simply pass "NULL" for the @a reply_block.
  * Note that it is assumed that the reply has already been
@@ -121,6 +201,11 @@ struct GNUNET_BLOCK_PluginFunctions
    */
   GNUNET_BLOCK_GetKeyFunction get_key;
 
+  /**
+   * Create a block group to process a bunch of blocks in a shared
+   * context (i.e. to detect duplicates).
+   */
+  GNUNET_BLOCK_GroupCreateFunction create_group;
 };
 
 #endif
diff --git a/src/regex/Makefile.am b/src/regex/Makefile.am
index 70f612485..80997db40 100644
--- a/src/regex/Makefile.am
+++ b/src/regex/Makefile.am
@@ -80,6 +80,7 @@ libgnunet_plugin_block_regex_la_SOURCES = \
 libgnunet_plugin_block_regex_la_LIBADD = \
  libgnunetregexblock.la \
  $(top_builddir)/src/block/libgnunetblock.la \
+ $(top_builddir)/src/block/libgnunetblockgroup.la \
  $(top_builddir)/src/util/libgnunetutil.la
 libgnunet_plugin_block_regex_la_LDFLAGS = \
  $(GN_PLUGIN_LDFLAGS)
diff --git a/src/regex/plugin_block_regex.c b/src/regex/plugin_block_regex.c
index 36926c25d..11511a71b 100644
--- a/src/regex/plugin_block_regex.c
+++ b/src/regex/plugin_block_regex.c
@@ -23,9 +23,9 @@
  * @brief blocks used for regex storage and search
  * @author Bartlomiej Polot
  */
-
 #include "platform.h"
 #include "gnunet_block_plugin.h"
+#include "gnunet_block_group_lib.h"
 #include "block_regex.h"
 #include "regex_block_lib.h"
 #include "gnunet_constants.h"
@@ -33,6 +33,40 @@
 
 
 /**
+ * How big is the BF we use for REGEX blocks?
+ */
+#define REGEX_BF_SIZE 8
+
+
+/**
+ * Create a new block group.
+ *
+ * @param ctx block context in which the block group is created
+ * @param type type of the block for which we are creating the group
+ * @param nonce random value used to seed the group creation
+ * @param raw_data optional serialized prior state of the group, NULL if 
unavailable/fresh
+ * @param raw_data_size number of bytes in @a raw_data, 0 if unavailable/fresh
+ * @return block group handle, NULL if block groups are not supported
+ *         by this @a type of block (this is not an error)
+ */
+static struct GNUNET_BLOCK_Group *
+block_plugin_regex_create_group (void *cls,
+                                 enum GNUNET_BLOCK_Type type,
+                                 uint32_t nonce,
+                                 const void *raw_data,
+                                 size_t raw_data_size)
+{
+  return GNUNET_BLOCK_GROUP_bf_create (cls,
+                                       REGEX_BF_SIZE,
+                                       GNUNET_CONSTANTS_BLOOMFILTER_K,
+                                       type,
+                                       nonce,
+                                       raw_data,
+                                       raw_data_size);
+}
+
+
+/**
  * Function called to validate a reply or a request of type
  * #GNUNET_BLOCK_TYPE_REGEX.
  * For request evaluation, pass "NULL" for the reply_block.
@@ -346,6 +380,7 @@ libgnunet_plugin_block_regex_init (void *cls)
   api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions);
   api->evaluate = &block_plugin_regex_evaluate;
   api->get_key = &block_plugin_regex_get_key;
+  api->create_group = &block_plugin_regex_create_group;
   api->types = types;
   return api;
 }

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]