/*
This file is part of GNUnet
- Copyright (C) 2012 Christian Grothoff (and other contributing authors)
+ Copyright (C) 2012 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
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., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
*/
/**
* @file set/gnunet-service-set_union_strata_estimator.c
* @brief invertible bloom filter
* @author Florian Dold
+ * @author Christian Grothoff
*/
#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet-service-set_union_strata_estimator.h"
+/**
+ * Should we try compressing the strata estimator? This will
+ * break compatibility with the 0.10.1-network.
+ */
+#define FAIL_10_1_COMPATIBILTIY 1
+
+
/**
* Write the given strata estimator to the buffer.
*
* @param se strata estimator to serialize
- * @param buf buffer to write to, must be of appropriate size
+ * @param[out] buf buffer to write to, must be of appropriate size
+ * @return number of bytes written to @a buf
*/
-void
+size_t
strata_estimator_write (const struct StrataEstimator *se,
void *buf)
{
+ char *sbuf = buf;
unsigned int i;
+ size_t osize;
GNUNET_assert (NULL != se);
for (i = 0; i < se->strata_count; i++)
{
- ibf_write_slice (se->strata[i], 0, se->ibf_size, buf);
- buf += se->ibf_size * IBF_BUCKET_SIZE;
+ ibf_write_slice (se->strata[i],
+ 0,
+ se->ibf_size,
+ &sbuf[se->ibf_size * IBF_BUCKET_SIZE * i]);
}
+ osize = se->ibf_size * IBF_BUCKET_SIZE * se->strata_count;
+#if FAIL_10_1_COMPATIBILTIY
+ {
+ char *cbuf;
+ size_t nsize;
+
+ if (GNUNET_YES ==
+ GNUNET_try_compression (buf,
+ osize,
+ &cbuf,
+ &nsize))
+ {
+ GNUNET_memcpy (buf, cbuf, nsize);
+ osize = nsize;
+ GNUNET_free (cbuf);
+ }
+ }
+#endif
+ return osize;
}
* estimator. The strata estimator must already be allocated.
*
* @param buf buffer to read from
- * @param se strata estimator to write to
+ * @param buf_len number of bytes in @a buf
+ * @param is_compressed is the data compressed?
+ * @param[out] se strata estimator to write to
+ * @return #GNUNET_OK on success
*/
-void
+int
strata_estimator_read (const void *buf,
+ size_t buf_len,
+ int is_compressed,
struct StrataEstimator *se)
{
unsigned int i;
+ size_t osize;
+ char *dbuf;
+
+ dbuf = NULL;
+ if (GNUNET_YES == is_compressed)
+ {
+ osize = se->ibf_size * IBF_BUCKET_SIZE * se->strata_count;
+ dbuf = GNUNET_decompress (buf,
+ buf_len,
+ osize);
+ if (NULL == dbuf)
+ {
+ GNUNET_break_op (0); /* bad compressed input data */
+ return GNUNET_SYSERR;
+ }
+ buf = dbuf;
+ buf_len = osize;
+ }
+
+ if (buf_len != se->strata_count * se->ibf_size * IBF_BUCKET_SIZE)
+ {
+ GNUNET_break (0); /* very odd error */
+ GNUNET_free_non_null (dbuf);
+ return GNUNET_SYSERR;
+ }
for (i = 0; i < se->strata_count; i++)
{
ibf_read_slice (buf, 0, se->ibf_size, se->strata[i]);
buf += se->ibf_size * IBF_BUCKET_SIZE;
}
+ GNUNET_free_non_null (dbuf);
+ return GNUNET_OK;
}
* @param strata_count number of stratas, that is, number of ibfs in the estimator
* @param ibf_size size of each ibf stratum
* @param ibf_hashnum hashnum parameter of each ibf
- * @return a freshly allocated, empty strata estimator
+ * @return a freshly allocated, empty strata estimator, NULL on error
*/
struct StrataEstimator *
strata_estimator_create (unsigned int strata_count,
{
struct StrataEstimator *se;
unsigned int i;
+ unsigned int j;
- /* fixme: allocate everything in one chunk */
se = GNUNET_new (struct StrataEstimator);
se->strata_count = strata_count;
se->ibf_size = ibf_size;
- se->strata = GNUNET_malloc (sizeof (struct InvertibleBloomFilter *) * strata_count);
+ se->strata = GNUNET_new_array (strata_count,
+ struct InvertibleBloomFilter *);
for (i = 0; i < strata_count; i++)
+ {
se->strata[i] = ibf_create (ibf_size, ibf_hashnum);
+ if (NULL == se->strata[i])
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to allocate memory for strata estimator\n");
+ for (j = 0; j < i; j++)
+ ibf_destroy (se->strata[i]);
+ GNUNET_free (se);
+ return NULL;
+ }
+ }
return se;
}
c = GNUNET_new (struct StrataEstimator);
c->strata_count = se->strata_count;
c->ibf_size = se->ibf_size;
- c->strata = GNUNET_malloc (sizeof (struct InvertibleBloomFilter *) * se->strata_count);
+ c->strata = GNUNET_new_array (se->strata_count,
+ struct InvertibleBloomFilter *);
for (i = 0; i < se->strata_count; i++)
c->strata[i] = ibf_dup (se->strata[i]);
return c;
GNUNET_free (se->strata);
GNUNET_free (se);
}
-