GNUnet  0.20.0
ibf.h File Reference

invertible bloom filter More...

#include "platform.h"
#include "gnunet_util_lib.h"
Include dependency graph for ibf.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  IBF_Key
 Keys that can be inserted into and removed from an IBF. More...
 
struct  IBF_KeyHash
 Hash of an IBF key. More...
 
struct  IBF_Count
 Type of the count field of IBF buckets. More...
 
struct  InvertibleBloomFilter
 Invertible bloom filter (IBF). More...
 

Macros

#define IBF_BUCKET_SIZE
 Size of one ibf bucket in bytes. More...
 

Functions

void ibf_write_slice (const struct InvertibleBloomFilter *ibf, uint32_t start, uint32_t count, void *buf)
 Write buckets from an ibf to a buffer. More...
 
void ibf_read_slice (const void *buf, uint32_t start, uint32_t count, struct InvertibleBloomFilter *ibf)
 Read buckets from a buffer into an ibf. More...
 
struct IBF_Key ibf_key_from_hashcode (const struct GNUNET_HashCode *hash)
 Create a key from a hashcode. More...
 
void ibf_hashcode_from_key (struct IBF_Key key, struct GNUNET_HashCode *dst)
 Create a hashcode from a key, by replicating the key until the hascode is filled. More...
 
struct InvertibleBloomFilteribf_create (uint32_t size, uint8_t hash_num)
 Create an invertible bloom filter. More...
 
void ibf_insert (struct InvertibleBloomFilter *ibf, struct IBF_Key key)
 Insert a key into an IBF. More...
 
void ibf_remove (struct InvertibleBloomFilter *ibf, struct IBF_Key key)
 Remove a key from an IBF. More...
 
void ibf_subtract (struct InvertibleBloomFilter *ibf1, const struct InvertibleBloomFilter *ibf2)
 Subtract ibf2 from ibf1, storing the result in ibf1. More...
 
int ibf_decode (struct InvertibleBloomFilter *ibf, int *ret_side, struct IBF_Key *ret_id)
 Decode and remove an element from the IBF, if possible. More...
 
struct InvertibleBloomFilteribf_dup (const struct InvertibleBloomFilter *ibf)
 Create a copy of an IBF, the copy has to be destroyed properly. More...
 
void ibf_destroy (struct InvertibleBloomFilter *ibf)
 Destroy all resources associated with the invertible bloom filter. More...
 

Detailed Description

invertible bloom filter

Author
Florian Dold
Florian Dold
Elias Summermatter

Definition in file ibf.h.

Macro Definition Documentation

◆ IBF_BUCKET_SIZE

#define IBF_BUCKET_SIZE
Value:
(sizeof(struct IBF_Count) + sizeof(struct IBF_Key) \
+ sizeof(struct IBF_KeyHash))
Type of the count field of IBF buckets.
Definition: ibf.h:64
Hash of an IBF key.
Definition: ibf.h:55
Keys that can be inserted into and removed from an IBF.
Definition: ibf.h:46

Size of one ibf bucket in bytes.

Definition at line 72 of file ibf.h.

Function Documentation

◆ ibf_write_slice()

void ibf_write_slice ( const struct InvertibleBloomFilter ibf,
uint32_t  start,
uint32_t  count,
void *  buf 
)

Write buckets from an ibf to a buffer.

Exactly (IBF_BUCKET_SIZE*ibf->size) bytes are written to buf.

Parameters
ibfthe ibf to write
startwith which bucket to start
counthow many buckets to write
bufbuffer to write the data to

Definition at line 291 of file ibf.c.

293 {
294  struct IBF_Key *key_dst;
295  struct IBF_KeyHash *key_hash_dst;
296  struct IBF_Count *count_dst;
297 
298  GNUNET_assert (start + count <= ibf->size);
299 
300  /* copy keys */
301  key_dst = (struct IBF_Key *) buf;
302  GNUNET_memcpy (key_dst, ibf->key_sum + start, count * sizeof *key_dst);
303  key_dst += count;
304  /* copy key hashes */
305  key_hash_dst = (struct IBF_KeyHash *) key_dst;
306  GNUNET_memcpy (key_hash_dst, ibf->key_hash_sum + start, count
307  * sizeof *key_hash_dst);
308  key_hash_dst += count;
309  /* copy counts */
310  count_dst = (struct IBF_Count *) key_hash_dst;
311  GNUNET_memcpy (count_dst, ibf->count + start, count * sizeof *count_dst);
312 }
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:39
static char buf[2048]
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static unsigned int size
Size of the "table".
Definition: peer.c:68
struct IBF_KeyHash * key_hash_sum
Xor sums of the hashes of the keys of inserted elements.
Definition: ibf.h:105
struct IBF_Count * count
How many times has a bucket been hit? Can be negative, as a result of IBF subtraction.
Definition: ibf.h:112
struct IBF_Key * key_sum
Xor sums of the elements' keys, used to identify the elements.
Definition: ibf.h:99

References buf, InvertibleBloomFilter::count, GNUNET_assert, GNUNET_memcpy, InvertibleBloomFilter::key_hash_sum, InvertibleBloomFilter::key_sum, size, and start.

Referenced by send_ibf(), and strata_estimator_write().

Here is the caller graph for this function:

◆ ibf_read_slice()

void ibf_read_slice ( const void *  buf,
uint32_t  start,
uint32_t  count,
struct InvertibleBloomFilter ibf 
)

Read buckets from a buffer into an ibf.

Parameters
bufpointer to the buffer to read from
startwhich bucket to start at
counthow many buckets to read
ibfthe ibf to write to
bufpointer to the buffer to read from
startwhich bucket to start at
counthow many buckets to read
ibfthe ibf to read from

Definition at line 324 of file ibf.c.

326 {
327  struct IBF_Key *key_src;
328  struct IBF_KeyHash *key_hash_src;
329  struct IBF_Count *count_src;
330 
331  GNUNET_assert (count > 0);
332  GNUNET_assert (start + count <= ibf->size);
333 
334  /* copy keys */
335  key_src = (struct IBF_Key *) buf;
336  GNUNET_memcpy (ibf->key_sum + start, key_src, count * sizeof *key_src);
337  key_src += count;
338  /* copy key hashes */
339  key_hash_src = (struct IBF_KeyHash *) key_src;
340  GNUNET_memcpy (ibf->key_hash_sum + start, key_hash_src, count
341  * sizeof *key_hash_src);
342  key_hash_src += count;
343  /* copy counts */
344  count_src = (struct IBF_Count *) key_hash_src;
345  GNUNET_memcpy (ibf->count + start, count_src, count * sizeof *count_src);
346 }

References buf, InvertibleBloomFilter::count, GNUNET_assert, GNUNET_memcpy, InvertibleBloomFilter::key_hash_sum, InvertibleBloomFilter::key_sum, size, and start.

Referenced by handle_union_p2p_ibf(), and strata_estimator_read().

Here is the caller graph for this function:

◆ ibf_key_from_hashcode()

struct IBF_Key ibf_key_from_hashcode ( const struct GNUNET_HashCode hash)

Create a key from a hashcode.

Parameters
hashthe hashcode
Returns
a key

Definition at line 1 of file ibf.c.

45 {
46  return *(struct IBF_Key *) hash;
47 }

◆ ibf_hashcode_from_key()

void ibf_hashcode_from_key ( struct IBF_Key  key,
struct GNUNET_HashCode dst 
)

Create a hashcode from a key, by replicating the key until the hascode is filled.

Parameters
keythe key
dsthashcode to store the result in

Definition at line 58 of file ibf.c.

60 {
61  struct IBF_Key *p;
62  unsigned int i;
63  const unsigned int keys_per_hashcode = sizeof(struct GNUNET_HashCode)
64  / sizeof(struct IBF_Key);
65 
66  p = (struct IBF_Key *) dst;
67  for (i = 0; i < keys_per_hashcode; i++)
68  *p++ = key;
69 }
struct GNUNET_HashCode key
The key used in the DHT.
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-uri.c:38
A 512-bit hashcode.

◆ ibf_create()

struct InvertibleBloomFilter* ibf_create ( uint32_t  size,
uint8_t  hash_num 
)

Create an invertible bloom filter.

Parameters
sizenumber of IBF buckets
hash_numnumber of buckets one element is hashed in, usually 3 or 4
Returns
the newly created invertible bloom filter, NULL on error
Parameters
sizenumber of IBF buckets
hash_numnumber of buckets one element is hashed in
Returns
the newly created invertible bloom filter, NULL on error

Definition at line 80 of file ibf.c.

81 {
82  struct InvertibleBloomFilter *ibf;
83 
84  GNUNET_assert (0 != size);
85 
86  ibf = GNUNET_new (struct InvertibleBloomFilter);
87  ibf->count = GNUNET_malloc_large (size * sizeof(uint8_t));
88  if (NULL == ibf->count)
89  {
90  GNUNET_free (ibf);
91  return NULL;
92  }
93  ibf->key_sum = GNUNET_malloc_large (size * sizeof(struct IBF_Key));
94  if (NULL == ibf->key_sum)
95  {
96  GNUNET_free (ibf->count);
97  GNUNET_free (ibf);
98  return NULL;
99  }
100  ibf->key_hash_sum = GNUNET_malloc_large (size * sizeof(struct IBF_KeyHash));
101  if (NULL == ibf->key_hash_sum)
102  {
103  GNUNET_free (ibf->key_sum);
104  GNUNET_free (ibf->count);
105  GNUNET_free (ibf);
106  return NULL;
107  }
108  ibf->size = size;
109  ibf->hash_num = hash_num;
110 
111  return ibf;
112 }
static unsigned int hash_num
#define GNUNET_malloc_large(size)
Wrapper around malloc.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
Invertible bloom filter (IBF).
Definition: ibf.h:83
uint32_t size
How many cells does this IBF have?
Definition: ibf.h:87
uint8_t hash_num
In how many cells do we hash one element? Usually 4 or 3.
Definition: ibf.h:93

◆ ibf_insert()

void ibf_insert ( struct InvertibleBloomFilter ibf,
struct IBF_Key  key 
)

Insert a key into an IBF.

Parameters
ibfthe IBF
keythe element's hash code

Definition at line 168 of file ibf.c.

169 {
170  int buckets[ibf->hash_num];
171 
172  GNUNET_assert (ibf->hash_num <= ibf->size);
173  ibf_get_indices (ibf, key, buckets);
174  ibf_insert_into (ibf, key, buckets, 1);
175 }
static void ibf_get_indices(const struct InvertibleBloomFilter *ibf, struct IBF_Key key, int *dst)
Store unique bucket indices for the specified key in dst.
Definition: ibf.c:119
static void ibf_insert_into(struct InvertibleBloomFilter *ibf, struct IBF_Key key, const int *buckets, int side)
Definition: ibf.c:144

◆ ibf_remove()

void ibf_remove ( struct InvertibleBloomFilter ibf,
struct IBF_Key  key 
)

Remove a key from an IBF.

Parameters
ibfthe IBF
keythe element's hash code

Definition at line 185 of file ibf.c.

186 {
187  int buckets[ibf->hash_num];
188 
189  GNUNET_assert (ibf->hash_num <= ibf->size);
190  ibf_get_indices (ibf, key, buckets);
191  ibf_insert_into (ibf, key, buckets, -1);
192 }

◆ ibf_subtract()

void ibf_subtract ( struct InvertibleBloomFilter ibf1,
const struct InvertibleBloomFilter ibf2 
)

Subtract ibf2 from ibf1, storing the result in ibf1.

The two IBF's must have the same parameters size and hash_num.

Parameters
ibf1IBF that is subtracted from
ibf2IBF that will be subtracted from ibf1

Definition at line 357 of file ibf.c.

359 {
360  int i;
361 
362  GNUNET_assert (ibf1->size == ibf2->size);
363  GNUNET_assert (ibf1->hash_num == ibf2->hash_num);
364 
365  for (i = 0; i < ibf1->size; i++)
366  {
367  ibf1->count[i].count_val -= ibf2->count[i].count_val;
368  ibf1->key_hash_sum[i].key_hash_val ^= ibf2->key_hash_sum[i].key_hash_val;
369  ibf1->key_sum[i].key_val ^= ibf2->key_sum[i].key_val;
370  }
371 }
int8_t count_val
Definition: ibf.h:65
uint32_t key_hash_val
Definition: ibf.h:56
uint64_t key_val
Definition: ibf.h:47

◆ ibf_decode()

int ibf_decode ( struct InvertibleBloomFilter ibf,
int *  ret_side,
struct IBF_Key ret_id 
)

Decode and remove an element from the IBF, if possible.

Parameters
ibfthe invertible bloom filter to decode
ret_sidesign of the cell's count where the decoded element came from. A negative sign indicates that the element was recovered resides in an IBF that was previously subtracted from.
ret_idreceives the hash code of the decoded element, if successful
Returns
GNUNET_YES if decoding an element was successful, GNUNET_NO if the IBF is empty, GNUNET_SYSERR if the decoding has failed
Parameters
ibfthe invertible bloom filter to decode
ret_sidesign of the cell's count where the decoded element came from. A negative sign indicates that the element was recovered resides in an IBF that was previously subtracted from.
ret_idreceives the hash code of the decoded element, if successful
Returns
GNUNET_YES if decoding an element was successful, GNUNET_NO if the IBF is empty, GNUNET_SYSERR if the decoding has failed

Definition at line 229 of file ibf.c.

231 {
232  struct IBF_KeyHash hash;
233  int i;
234  int buckets[ibf->hash_num];
235 
236  GNUNET_assert (NULL != ibf);
237 
238  for (i = 0; i < ibf->size; i++)
239  {
240  int j;
241  int hit;
242 
243  /* we can only decode from pure buckets */
244  if ((1 != ibf->count[i].count_val) && (-1 != ibf->count[i].count_val))
245  continue;
246 
247  hash.key_hash_val = IBF_KEY_HASH_VAL (ibf->key_sum[i]);
248 
249  /* test if the hash matches the key */
250  if (hash.key_hash_val != ibf->key_hash_sum[i].key_hash_val)
251  continue;
252 
253  /* test if key in bucket hits its own location,
254  * if not, the key hash was subject to collision */
255  hit = GNUNET_NO;
256  ibf_get_indices (ibf, ibf->key_sum[i], buckets);
257  for (j = 0; j < ibf->hash_num; j++)
258  if (buckets[j] == i)
259  hit = GNUNET_YES;
260 
261  if (GNUNET_NO == hit)
262  continue;
263 
264  if (NULL != ret_side)
265  *ret_side = ibf->count[i].count_val;
266  if (NULL != ret_id)
267  *ret_id = ibf->key_sum[i];
268 
269  /* insert on the opposite side, effectively removing the element */
270  ibf_insert_into (ibf, ibf->key_sum[i], buckets, -ibf->count[i].count_val);
271 
272  return GNUNET_YES;
273  }
274 
275  if (GNUNET_YES == ibf_is_empty (ibf))
276  return GNUNET_NO;
277  return GNUNET_SYSERR;
278 }
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define IBF_KEY_HASH_VAL(k)
Compute the key's hash from the key.
Definition: ibf.c:34
static int ibf_is_empty(struct InvertibleBloomFilter *ibf)
Test is the IBF is empty, i.e.
Definition: ibf.c:199

◆ ibf_dup()

struct InvertibleBloomFilter* ibf_dup ( const struct InvertibleBloomFilter ibf)

Create a copy of an IBF, the copy has to be destroyed properly.

Parameters
ibfthe IBF to copy

Definition at line 380 of file ibf.c.

381 {
382  struct InvertibleBloomFilter *copy;
383 
384  copy = GNUNET_malloc (sizeof *copy);
385  copy->hash_num = ibf->hash_num;
386  copy->size = ibf->size;
387  copy->key_hash_sum = GNUNET_memdup (ibf->key_hash_sum, ibf->size
388  * sizeof(struct IBF_KeyHash));
389  copy->key_sum = GNUNET_memdup (ibf->key_sum, ibf->size * sizeof(struct
390  IBF_Key));
391  copy->count = GNUNET_memdup (ibf->count, ibf->size * sizeof(struct
392  IBF_Count));
393  return copy;
394 }
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_memdup(buf, size)
Allocate and initialize a block of memory.

◆ ibf_destroy()

void ibf_destroy ( struct InvertibleBloomFilter ibf)

Destroy all resources associated with the invertible bloom filter.

No more ibf_*-functions may be called on ibf after calling destroy.

Parameters
ibfthe intertible bloom filter to destroy

Definition at line 404 of file ibf.c.

405 {
406  GNUNET_free (ibf->key_sum);
407  GNUNET_free (ibf->key_hash_sum);
408  GNUNET_free (ibf->count);
409  GNUNET_free (ibf);
410 }