diff options
Diffstat (limited to 'src/consensus/ibf.c')
-rw-r--r-- | src/consensus/ibf.c | 87 |
1 files changed, 40 insertions, 47 deletions
diff --git a/src/consensus/ibf.c b/src/consensus/ibf.c index 4f1aca939..2d06fc29b 100644 --- a/src/consensus/ibf.c +++ b/src/consensus/ibf.c | |||
@@ -25,50 +25,8 @@ | |||
25 | * @author Florian Dold | 25 | * @author Florian Dold |
26 | */ | 26 | */ |
27 | 27 | ||
28 | #include "ibf.h" | ||
29 | |||
30 | |||
31 | /** | ||
32 | * Opaque handle to an invertible bloom filter (IBF). | ||
33 | * | ||
34 | * An IBF is a counting bloom filter that has the ability to restore | ||
35 | * the hashes of its stored elements with high probability. | ||
36 | */ | ||
37 | struct InvertibleBloomFilter | ||
38 | { | ||
39 | /** | ||
40 | * How many cells does this IBF have? | ||
41 | */ | ||
42 | unsigned int size; | ||
43 | 28 | ||
44 | /** | 29 | #include "ibf.h" |
45 | * In how many cells do we hash one element? | ||
46 | * Usually 4 or 3. | ||
47 | */ | ||
48 | unsigned int hash_num; | ||
49 | |||
50 | /** | ||
51 | * Salt for mingling hashes | ||
52 | */ | ||
53 | uint32_t salt; | ||
54 | |||
55 | /** | ||
56 | * How many times has a bucket been hit? | ||
57 | * Can be negative, as a result of IBF subtraction. | ||
58 | */ | ||
59 | int8_t *count; | ||
60 | |||
61 | /** | ||
62 | * xor sums of the elements' hash codes, used to identify the elements. | ||
63 | */ | ||
64 | struct GNUNET_HashCode *id_sum; | ||
65 | |||
66 | /** | ||
67 | * xor sums of the "hash of the hash". | ||
68 | */ | ||
69 | struct GNUNET_HashCode *hash_sum; | ||
70 | |||
71 | }; | ||
72 | 30 | ||
73 | 31 | ||
74 | /** | 32 | /** |
@@ -152,6 +110,8 @@ ibf_insert_on_side (struct InvertibleBloomFilter *ibf, | |||
152 | used_buckets[i] = bucket; | 110 | used_buckets[i] = bucket; |
153 | 111 | ||
154 | ibf->count[bucket] += side; | 112 | ibf->count[bucket] += side; |
113 | |||
114 | GNUNET_log_from(GNUNET_ERROR_TYPE_INFO, "ibf", "inserting in bucket %d \n", bucket); | ||
155 | 115 | ||
156 | GNUNET_CRYPTO_hash_xor (&key_copy, &ibf->id_sum[bucket], | 116 | GNUNET_CRYPTO_hash_xor (&key_copy, &ibf->id_sum[bucket], |
157 | &ibf->id_sum[bucket]); | 117 | &ibf->id_sum[bucket]); |
@@ -214,8 +174,6 @@ ibf_decode (struct InvertibleBloomFilter *ibf, | |||
214 | int i; | 174 | int i; |
215 | 175 | ||
216 | GNUNET_assert (NULL != ibf); | 176 | GNUNET_assert (NULL != ibf); |
217 | GNUNET_assert (NULL != ret_id); | ||
218 | GNUNET_assert (NULL != ret_side); | ||
219 | 177 | ||
220 | for (i = 0; i < ibf->size; i++) | 178 | for (i = 0; i < ibf->size; i++) |
221 | { | 179 | { |
@@ -227,8 +185,10 @@ ibf_decode (struct InvertibleBloomFilter *ibf, | |||
227 | if (0 != memcmp (&hash, &ibf->hash_sum[i], sizeof (struct GNUNET_HashCode))) | 185 | if (0 != memcmp (&hash, &ibf->hash_sum[i], sizeof (struct GNUNET_HashCode))) |
228 | continue; | 186 | continue; |
229 | 187 | ||
230 | *ret_side = ibf->count[i]; | 188 | if (NULL != ret_side) |
231 | *ret_id = ibf->id_sum[i]; | 189 | *ret_side = ibf->count[i]; |
190 | if (NULL != ret_id) | ||
191 | *ret_id = ibf->id_sum[i]; | ||
232 | 192 | ||
233 | /* insert on the opposite side, effectively removing the element */ | 193 | /* insert on the opposite side, effectively removing the element */ |
234 | ibf_insert_on_side (ibf, &ibf->id_sum[i], -ibf->count[i]); | 194 | ibf_insert_on_side (ibf, &ibf->id_sum[i], -ibf->count[i]); |
@@ -269,3 +229,36 @@ ibf_subtract (struct InvertibleBloomFilter *ibf1, struct InvertibleBloomFilter * | |||
269 | } | 229 | } |
270 | } | 230 | } |
271 | 231 | ||
232 | /** | ||
233 | * Create a copy of an IBF, the copy has to be destroyed properly. | ||
234 | * | ||
235 | * @param ibf the IBF to copy | ||
236 | */ | ||
237 | struct InvertibleBloomFilter * | ||
238 | ibf_dup (struct InvertibleBloomFilter *ibf) | ||
239 | { | ||
240 | struct InvertibleBloomFilter *copy; | ||
241 | copy = GNUNET_malloc (sizeof *copy); | ||
242 | copy->hash_num = ibf->hash_num; | ||
243 | copy->salt = ibf->salt; | ||
244 | copy->size = ibf->size; | ||
245 | copy->hash_sum = GNUNET_memdup (ibf->hash_sum, ibf->size * sizeof (struct GNUNET_HashCode)); | ||
246 | copy->id_sum = GNUNET_memdup (ibf->id_sum, ibf->size * sizeof (struct GNUNET_HashCode)); | ||
247 | copy->count = GNUNET_memdup (ibf->count, ibf->size * sizeof (uint8_t)); | ||
248 | return copy; | ||
249 | } | ||
250 | |||
251 | /** | ||
252 | * Destroy all resources associated with the invertible bloom filter. | ||
253 | * No more ibf_*-functions may be called on ibf after calling destroy. | ||
254 | * | ||
255 | * @param ibf the intertible bloom filter to destroy | ||
256 | */ | ||
257 | void | ||
258 | ibf_destroy (struct InvertibleBloomFilter *ibf) | ||
259 | { | ||
260 | GNUNET_free (ibf->hash_sum); | ||
261 | GNUNET_free (ibf->id_sum); | ||
262 | GNUNET_free (ibf->count); | ||
263 | GNUNET_free (ibf); | ||
264 | } | ||