GNUnet 0.21.1
ibf.h File Reference
#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, uint64_t count, void *buf, uint8_t counter_max_length)
 Write buckets from an ibf to a buffer. 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...
 
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...
 
uint8_t ibf_get_max_counter (struct InvertibleBloomFilter *ibf)
 Returns the minimal bytes needed to store the counter of the IBF. 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...
 

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 73 of file ibf.h.

Function Documentation

◆ 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

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
#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
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
struct IBF_KeyHash * key_hash_sum
Xor sums of the hashes of the keys of inserted elements.
Definition: ibf.h:105
struct IBF_Key * key_sum
Xor sums of the elements' keys, used to identify the elements.
Definition: ibf.h:99

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

Here is the call 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 write to
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;
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

References 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_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 44 of file ibf.c.

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

Referenced by insert_iterator(), and register_hashcode().

Here is the caller graph for this function:

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

References key, and p.

Referenced by iter_hashcodes(), and register_hashcode().

Here is the caller graph for this function:

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

Referenced by handle_union_p2p_ibf(), prepare_ibf(), run(), and strata_estimator_create().

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

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

Referenced by insert_iterator(), prepare_ibf_iterator(), and strata_estimator_insert().

Here is the call graph for this function:
Here is the caller 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 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}

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

Referenced by strata_estimator_remove().

Here is the call graph for this function:
Here is the caller 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 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;
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

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.

Referenced by decode_and_send(), run(), and strata_estimator_difference().

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
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}
#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
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR

References InvertibleBloomFilter::count, IBF_Count::count_val, GNUNET_assert, 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.

Referenced by decode_and_send(), run(), and strata_estimator_difference().

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

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

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

Referenced by decode_and_send(), strata_estimator_difference(), and strata_estimator_dup().

Here is the caller graph for this function:

◆ 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);
408 GNUNET_free (ibf->count);
409 GNUNET_free (ibf);
410}

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

Referenced by _GSS_operation_destroy(), decode_and_send(), prepare_ibf(), strata_estimator_create(), strata_estimator_destroy(), strata_estimator_difference(), and union_op_cancel().

Here is the caller 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:

◆ 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 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 InvertibleBloomFilter::count, IBF_Count::count_val, and start.

Referenced by ibf_read_slice().

Here is the caller graph for this function: