GNUnet  0.20.0
ibf.c File Reference
#include "platform.h"
#include "ibf.h"
#include "gnunet_util_lib.h"
Include dependency graph for ibf.c:

Go to the source code of this file.

Macros

#define LOG(kind, ...)   GNUNET_log_from (kind, "setu", __VA_ARGS__)
 
#define IBF_KEY_HASH_VAL(k)
 Compute the key's hash from the key. More...
 

Functions

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...
 
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. More...
 
static void ibf_insert_into (struct InvertibleBloomFilter *ibf, struct IBF_Key key, const int *buckets, int side)
 
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...
 
static int ibf_is_empty (struct InvertibleBloomFilter *ibf)
 Test is the IBF is empty, i.e. 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...
 
uint8_t ibf_get_max_counter (struct InvertibleBloomFilter *ibf)
 Returns the minimal bytes needed to store the counter of the IBF. More...
 
void ibf_write_slice (const struct InvertibleBloomFilter *ibf, uint32_t start, uint64_t count, void *buf, uint8_t counter_max_length)
 Write buckets from an ibf to a buffer. More...
 
void pack_counter (const struct InvertibleBloomFilter *ibf, uint32_t start, uint64_t count, uint8_t *buf, uint8_t counter_max_length)
 Packs the counter to transmit only the smallest possible amount of bytes and preventing overflow of the counter. More...
 
void unpack_counter (const struct InvertibleBloomFilter *ibf, uint32_t start, uint64_t count, uint8_t *buf, uint8_t counter_max_length)
 Unpacks the counter to transmit only the smallest possible amount of bytes and preventing overflow of the counter. More...
 
void ibf_read_slice (const void *buf, uint32_t start, uint64_t count, struct InvertibleBloomFilter *ibf, uint8_t counter_max_length)
 Read buckets from a buffer into an ibf. More...
 
void ibf_subtract (struct InvertibleBloomFilter *ibf1, const struct InvertibleBloomFilter *ibf2)
 Subtract ibf2 from ibf1, storing the result in ibf1. 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...
 

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from (kind, "setu", __VA_ARGS__)

Definition at line 31 of file ibf.c.

◆ IBF_KEY_HASH_VAL

#define IBF_KEY_HASH_VAL (   k)
Value:
(GNUNET_CRYPTO_crc32_n (&(k), sizeof(struct \
int32_t GNUNET_CRYPTO_crc32_n(const void *buf, size_t len)
Compute the CRC32 checksum for the first len bytes of the buffer.
Definition: crypto_crc.c:99
Hash of an IBF key.
Definition: ibf.h:55

Compute the key's hash from the key.

Redefine to use a different hash function.

Definition at line 38 of file ibf.c.

Function Documentation

◆ 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.

49 {
50  return *(struct IBF_Key *) hash;
51 }
Keys that can be inserted into and removed from an IBF.
Definition: ibf.h:46

◆ 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 62 of file ibf.c.

64 {
65  struct IBF_Key *p;
66  unsigned int i;
67  const unsigned int keys_per_hashcode = sizeof(struct GNUNET_HashCode)
68  / sizeof(struct IBF_Key);
69 
70  p = (struct IBF_Key *) dst;
71  for (i = 0; i < keys_per_hashcode; i++)
72  *p++ = key;
73 }
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.

References key, and p.

◆ 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
Returns
the newly created invertible bloom filter, NULL on error

Definition at line 84 of file ibf.c.

85 {
86  struct InvertibleBloomFilter *ibf;
87 
88  GNUNET_assert (0 != size);
89 
90  ibf = GNUNET_new (struct InvertibleBloomFilter);
91  ibf->count = GNUNET_malloc_large (size * sizeof(uint64_t));
92  if (NULL == ibf->count)
93  {
94  GNUNET_free (ibf);
95  return NULL;
96  }
97  ibf->key_sum = GNUNET_malloc_large (size * sizeof(struct IBF_Key));
98  if (NULL == ibf->key_sum)
99  {
100  GNUNET_free (ibf->count);
101  GNUNET_free (ibf);
102  return NULL;
103  }
104  ibf->key_hash_sum = GNUNET_malloc_large (size * sizeof(struct IBF_KeyHash));
105  if (NULL == ibf->key_hash_sum)
106  {
107  GNUNET_free (ibf->key_sum);
108  GNUNET_free (ibf->count);
109  GNUNET_free (ibf);
110  return NULL;
111  }
112  ibf->size = size;
113  ibf->hash_num = hash_num;
114 
115  return ibf;
116 }
static unsigned int hash_num
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#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.
static unsigned int size
Size of the "table".
Definition: peer.c:68
Invertible bloom filter (IBF).
Definition: ibf.h:83
struct IBF_KeyHash * key_hash_sum
Xor sums of the hashes of the keys of inserted elements.
Definition: ibf.h:105
uint32_t size
How many cells does this IBF have?
Definition: ibf.h:87
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
uint8_t hash_num
In how many cells do we hash one element? Usually 4 or 3.
Definition: ibf.h:93

References InvertibleBloomFilter::count, GNUNET_assert, GNUNET_free, GNUNET_malloc_large, GNUNET_new, hash_num, InvertibleBloomFilter::hash_num, InvertibleBloomFilter::key_hash_sum, InvertibleBloomFilter::key_sum, InvertibleBloomFilter::size, and size.

◆ ibf_get_indices()

static void ibf_get_indices ( const struct InvertibleBloomFilter ibf,
struct IBF_Key  key,
int *  dst 
)
static

Store unique bucket indices for the specified key in dst.

Definition at line 123 of file ibf.c.

126 {
127  uint32_t filled;
128  uint32_t i;
129  uint32_t bucket;
130 
131  bucket = GNUNET_CRYPTO_crc32_n (&key, sizeof key);
132  for (i = 0, filled = 0; filled < ibf->hash_num; i++)
133  {
134  uint64_t x;
135 
136  for (unsigned int j = 0; j < filled; j++)
137  if (dst[j] == bucket % ibf->size)
138  goto try_next;
139  dst[filled++] = bucket % ibf->size;
140 try_next:
141  x = ((uint64_t) bucket << 32) | i;
142  bucket = GNUNET_CRYPTO_crc32_n (&x, sizeof x);
143  }
144 }

References GNUNET_CRYPTO_crc32_n(), InvertibleBloomFilter::hash_num, key, and InvertibleBloomFilter::size.

Referenced by ibf_decode(), ibf_insert(), and ibf_remove().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ibf_insert_into()

static void ibf_insert_into ( struct InvertibleBloomFilter ibf,
struct IBF_Key  key,
const int *  buckets,
int  side 
)
static

Definition at line 148 of file ibf.c.

152 {
153  for (unsigned int i = 0; i < ibf->hash_num; i++)
154  {
155  const int bucket = buckets[i];
156 
157  ibf->count[bucket].count_val += side;
158  ibf->key_sum[bucket].key_val ^= key.key_val;
159  ibf->key_hash_sum[bucket].key_hash_val
160  ^= IBF_KEY_HASH_VAL (key);
161  }
162 }
#define IBF_KEY_HASH_VAL(k)
Compute the key's hash from the key.
Definition: ibf.c:38
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

References InvertibleBloomFilter::count, IBF_Count::count_val, InvertibleBloomFilter::hash_num, IBF_KEY_HASH_VAL, key, InvertibleBloomFilter::key_hash_sum, IBF_KeyHash::key_hash_val, InvertibleBloomFilter::key_sum, and IBF_Key::key_val.

Referenced by ibf_decode(), ibf_insert(), and ibf_remove().

Here is the caller graph for this function:

◆ 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 172 of file ibf.c.

174 {
175  int buckets[ibf->hash_num];
176 
177  GNUNET_assert (ibf->hash_num <= ibf->size);
178  ibf_get_indices (ibf, key, buckets);
179  ibf_insert_into (ibf, key, buckets, 1);
180 }
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:123
static void ibf_insert_into(struct InvertibleBloomFilter *ibf, struct IBF_Key key, const int *buckets, int side)
Definition: ibf.c:148

References GNUNET_assert, InvertibleBloomFilter::hash_num, ibf_get_indices(), ibf_insert_into(), key, and InvertibleBloomFilter::size.

Here is the call graph for this function:

◆ 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 190 of file ibf.c.

192 {
193  int buckets[ibf->hash_num];
194 
195  GNUNET_assert (ibf->hash_num <= ibf->size);
196  ibf_get_indices (ibf, key, buckets);
197  ibf_insert_into (ibf, key, buckets, -1);
198 }

References GNUNET_assert, InvertibleBloomFilter::hash_num, ibf_get_indices(), ibf_insert_into(), key, and InvertibleBloomFilter::size.

Here is the call graph for this function:

◆ ibf_is_empty()

static int ibf_is_empty ( struct InvertibleBloomFilter ibf)
static

Test is the IBF is empty, i.e.

all counts, keys and key hashes are zero.

Definition at line 205 of file ibf.c.

206 {
207  for (uint32_t i = 0; i < ibf->size; i++)
208  {
209  if (0 != ibf->count[i].count_val)
210  return GNUNET_NO;
211  if (0 != ibf->key_hash_sum[i].key_hash_val)
212  return GNUNET_NO;
213  if (0 != ibf->key_sum[i].key_val)
214  return GNUNET_NO;
215  }
216  return GNUNET_YES;
217 }
@ GNUNET_YES
@ GNUNET_NO

References InvertibleBloomFilter::count, IBF_Count::count_val, GNUNET_NO, GNUNET_YES, InvertibleBloomFilter::key_hash_sum, IBF_KeyHash::key_hash_val, InvertibleBloomFilter::key_sum, IBF_Key::key_val, and InvertibleBloomFilter::size.

Referenced by ibf_decode().

Here is the caller graph for this function:

◆ 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 221 of file ibf.c.

224 {
225  struct IBF_KeyHash hash;
226  int buckets[ibf->hash_num];
227 
228  for (uint32_t i = 0; i < ibf->size; i++)
229  {
230  int hit;
231 
232  /* we can only decode from pure buckets */
233  if ( (1 != ibf->count[i].count_val) &&
234  (-1 != ibf->count[i].count_val) )
235  continue;
236 
237  hash.key_hash_val = IBF_KEY_HASH_VAL (ibf->key_sum[i]);
238 
239  /* test if the hash matches the key */
240  if (hash.key_hash_val != ibf->key_hash_sum[i].key_hash_val)
241  continue;
242 
243  /* test if key in bucket hits its own location,
244  * if not, the key hash was subject to collision */
245  hit = GNUNET_NO;
246  ibf_get_indices (ibf, ibf->key_sum[i], buckets);
247  for (int j = 0; j < ibf->hash_num; j++)
248  if (buckets[j] == i)
249  hit = GNUNET_YES;
250 
251  if (GNUNET_NO == hit)
252  continue;
253 
254  if (1 == ibf->count[i].count_val)
255  {
256  ibf->remote_decoded_count++;
257  }
258  else
259  {
260  ibf->local_decoded_count++;
261  }
262 
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_SYSERR
static int ibf_is_empty(struct InvertibleBloomFilter *ibf)
Test is the IBF is empty, i.e.
Definition: ibf.c:205
int remote_decoded_count
If an IBF is decoded this count stores how many elements are on the remote site.
Definition: ibf.h:108
int local_decoded_count
If an IBF is decoded this count stores how many elements are on the local site.
Definition: ibf.h:101

References InvertibleBloomFilter::count, IBF_Count::count_val, GNUNET_NO, GNUNET_SYSERR, GNUNET_YES, InvertibleBloomFilter::hash_num, ibf_get_indices(), ibf_insert_into(), ibf_is_empty(), IBF_KEY_HASH_VAL, InvertibleBloomFilter::key_hash_sum, IBF_KeyHash::key_hash_val, InvertibleBloomFilter::key_sum, InvertibleBloomFilter::local_decoded_count, InvertibleBloomFilter::remote_decoded_count, and InvertibleBloomFilter::size.

Here is the call graph for this function:

◆ ibf_get_max_counter()

uint8_t ibf_get_max_counter ( struct InvertibleBloomFilter ibf)

Returns the minimal bytes needed to store the counter of the IBF.

Parameters
ibfthe IBF

Definition at line 287 of file ibf.c.

288 {
289  long long max_counter = 0;
290  for (uint64_t i = 0; i < ibf->size; i++)
291  {
292  if (ibf->count[i].count_val > max_counter)
293  {
294  max_counter = ibf->count[i].count_val;
295  }
296  }
297  return 64 - __builtin_clzll (max_counter);
298 }

References InvertibleBloomFilter::count, IBF_Count::count_val, and InvertibleBloomFilter::size.

Referenced by send_ibf().

Here is the caller graph for this function:

◆ ibf_write_slice()

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

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
maxbit length of a counter for unpacking

Definition at line 312 of file ibf.c.

317 {
318  struct IBF_Key *key_dst;
319  struct IBF_KeyHash *key_hash_dst;
320 
321  GNUNET_assert (start + count <= ibf->size);
322 
323  /* copy keys */
324  key_dst = (struct IBF_Key *) buf;
325  GNUNET_memcpy (key_dst,
326  ibf->key_sum + start,
327  count * sizeof(*key_dst));
328  key_dst += count;
329  /* copy key hashes */
330  key_hash_dst = (struct IBF_KeyHash *) key_dst;
331  GNUNET_memcpy (key_hash_dst,
332  ibf->key_hash_sum + start,
333  count * sizeof(*key_hash_dst));
334  key_hash_dst += count;
335 
336  /* pack and copy counter */
337  pack_counter (ibf,
338  start,
339  count,
340  (uint8_t *) key_hash_dst,
341  counter_max_length);
342 
343 
344 }
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.
void pack_counter(const struct InvertibleBloomFilter *ibf, uint32_t start, uint64_t count, uint8_t *buf, uint8_t counter_max_length)
Packs the counter to transmit only the smallest possible amount of bytes and preventing overflow of t...
Definition: ibf.c:349

References buf, GNUNET_assert, GNUNET_memcpy, InvertibleBloomFilter::key_hash_sum, InvertibleBloomFilter::key_sum, pack_counter(), size, and start.

Here is the call graph for this function:

◆ pack_counter()

void pack_counter ( const struct InvertibleBloomFilter ibf,
uint32_t  start,
uint64_t  count,
uint8_t *  buf,
uint8_t  counter_max_length 
)

Packs the counter to transmit only the smallest possible amount of bytes and preventing overflow of the counter.

Parameters
ibfthe ibf to write
startwith which bucket to start
counthow many buckets to write
bufbuffer to write the data to
maxbit length of a counter for unpacking

Iterate over IBF bucket

Pack and compose counters to byte values

Shift bits if more than a byte has to be written or the store size is not empty

Pack data left in story before finishing

Definition at line 349 of file ibf.c.

354 {
355  uint8_t store_size = 0;
356  uint8_t store = 0;
357  uint16_t byte_ctr = 0;
358 
362  for (uint64_t i = start; i< (count + start);)
363  {
364  uint64_t count_val_to_write = ibf->count[i].count_val;
365  uint8_t count_len_to_write = counter_max_length;
366 
370  while ((count_len_to_write + store_size) >= 8)
371  {
372  uint8_t bit_shift = 0;
373 
378  if ((store_size > 0) || (count_len_to_write > 8))
379  {
380  uint8_t bit_unused = 8 - store_size;
381  bit_shift = count_len_to_write - bit_unused;
382  store = store << bit_unused;
383  }
384 
385  buf[byte_ctr] = ((count_val_to_write >> bit_shift) | store) & 0xFF;
386  byte_ctr++;
387  count_len_to_write -= (8 - store_size);
388  count_val_to_write = count_val_to_write & ((1ULL <<
389  count_len_to_write) - 1);
390  store = 0;
391  store_size = 0;
392  }
393  store = (store << count_len_to_write) | count_val_to_write;
394  store_size = store_size + count_len_to_write;
395  count_len_to_write = 0;
396  i++;
397  }
398 
402  if (store_size > 0)
403  {
404  buf[byte_ctr] = store << (8 - store_size);
405  byte_ctr++;
406  }
407 
408 }

References buf, InvertibleBloomFilter::count, IBF_Count::count_val, and start.

Referenced by ibf_write_slice().

Here is the caller graph for this function:

◆ unpack_counter()

void unpack_counter ( const struct InvertibleBloomFilter ibf,
uint32_t  start,
uint64_t  count,
uint8_t *  buf,
uint8_t  counter_max_length 
)

Unpacks the counter to transmit only the smallest possible amount of bytes and preventing overflow of the counter.

Parameters
ibfthe ibf to write
startwith which bucket to start
counthow many buckets to write
bufbuffer to write the data to
maxbit length of a counter for unpacking

Iterate over received bytes

Pack data left in story before finishing

Stop decoding when end is reached

Definition at line 413 of file ibf.c.

418 {
419  uint64_t ibf_counter_ctr = 0;
420  uint64_t store = 0;
421  uint64_t store_bit_ctr = 0;
422  uint64_t byte_ctr = 0;
423 
427  while (true)
428  {
429  uint8_t byte_read = buf[byte_ctr];
430  uint8_t bit_to_read_left = 8;
431  byte_ctr++;
432 
436  while (true)
437  {
441  if (ibf_counter_ctr > (count - 1))
442  return;
443 
444  /*
445  * Unpack the counter
446  */
447  if ((store_bit_ctr + bit_to_read_left) >= counter_max_length)
448  {
449  uint8_t bytes_used = counter_max_length - store_bit_ctr;
450  if (store_bit_ctr > 0)
451  {
452  store = store << bytes_used;
453  }
454 
455  uint8_t bytes_to_shift = bit_to_read_left - bytes_used;
456  uint64_t counter_part = byte_read >> bytes_to_shift;
457  store = store | counter_part;
458  ibf->count[ibf_counter_ctr + start].count_val = store;
459  byte_read = byte_read & ((1 << bytes_to_shift) - 1);
460  bit_to_read_left -= bytes_used;
461  ibf_counter_ctr++;
462  store = 0;
463  store_bit_ctr = 0;
464  }
465  else
466  {
467  store_bit_ctr += bit_to_read_left;
468  if (0 == store)
469  {
470  store = byte_read;
471  }
472  else
473  {
474  store = store << bit_to_read_left;
475  store = store | byte_read;
476  }
477  break;
478  }
479  }
480  }
481 }

References buf, InvertibleBloomFilter::count, IBF_Count::count_val, and start.

Referenced by ibf_read_slice().

Here is the caller graph for this function:

◆ ibf_read_slice()

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

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 read from
maxbit length of a counter for unpacking

Definition at line 494 of file ibf.c.

499 {
500  struct IBF_Key *key_src;
501  struct IBF_KeyHash *key_hash_src;
502  struct IBF_Count *count_src;
503 
504  GNUNET_assert (count > 0);
505  GNUNET_assert (start + count <= ibf->size);
506 
507  /* copy keys */
508  key_src = (struct IBF_Key *) buf;
509  GNUNET_memcpy (ibf->key_sum + start,
510  key_src,
511  count * sizeof *key_src);
512  key_src += count;
513  /* copy key hashes */
514  key_hash_src = (struct IBF_KeyHash *) key_src;
516  key_hash_src,
517  count * sizeof *key_hash_src);
518  key_hash_src += count;
519 
520  /* copy and unpack counts */
521  count_src = (struct IBF_Count *) key_hash_src;
522  unpack_counter (ibf,start,count,(uint8_t *) count_src,counter_max_length);
523 }
void unpack_counter(const struct InvertibleBloomFilter *ibf, uint32_t start, uint64_t count, uint8_t *buf, uint8_t counter_max_length)
Unpacks the counter to transmit only the smallest possible amount of bytes and preventing overflow of...
Definition: ibf.c:413
Type of the count field of IBF buckets.
Definition: ibf.h:64

References buf, GNUNET_assert, GNUNET_memcpy, InvertibleBloomFilter::key_hash_sum, InvertibleBloomFilter::key_sum, size, start, and unpack_counter().

Here is the call graph for this function:

◆ 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 534 of file ibf.c.

536 {
537  GNUNET_assert (ibf1->size == ibf2->size);
538  GNUNET_assert (ibf1->hash_num == ibf2->hash_num);
539 
540  for (uint32_t i = 0; i < ibf1->size; i++)
541  {
542  ibf1->count[i].count_val -= ibf2->count[i].count_val;
543  ibf1->key_hash_sum[i].key_hash_val ^= ibf2->key_hash_sum[i].key_hash_val;
544  ibf1->key_sum[i].key_val ^= ibf2->key_sum[i].key_val;
545  }
546 }

References InvertibleBloomFilter::count, IBF_Count::count_val, GNUNET_assert, InvertibleBloomFilter::hash_num, InvertibleBloomFilter::key_hash_sum, IBF_KeyHash::key_hash_val, InvertibleBloomFilter::key_sum, IBF_Key::key_val, and InvertibleBloomFilter::size.

◆ 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 555 of file ibf.c.

556 {
557  struct InvertibleBloomFilter *copy;
558 
559  copy = GNUNET_malloc (sizeof *copy);
560  copy->hash_num = ibf->hash_num;
561  copy->size = ibf->size;
563  ibf->size * sizeof(struct IBF_KeyHash));
564  copy->key_sum = GNUNET_memdup (ibf->key_sum,
565  ibf->size * sizeof(struct IBF_Key));
566  copy->count = GNUNET_memdup (ibf->count,
567  ibf->size * sizeof(struct IBF_Count));
568  return copy;
569 }
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_memdup(buf, size)
Allocate and initialize a block of memory.

References InvertibleBloomFilter::count, GNUNET_malloc, GNUNET_memdup, InvertibleBloomFilter::hash_num, InvertibleBloomFilter::key_hash_sum, InvertibleBloomFilter::key_sum, and InvertibleBloomFilter::size.

◆ 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 579 of file ibf.c.

580 {
581  GNUNET_free (ibf->key_sum);
582  GNUNET_free (ibf->key_hash_sum);
583  GNUNET_free (ibf->count);
584  GNUNET_free (ibf);
585 }

References InvertibleBloomFilter::count, GNUNET_free, InvertibleBloomFilter::key_hash_sum, and InvertibleBloomFilter::key_sum.