88#define F1 (t , a , rt , t1 , p1 ) rt GFNAM(t, a)(t1 p1) { return FNAM(t, a)(p1); }
99#define F2 (t , a , rt , t1 , p1 , t2 , p2 ) rt GFNAM(t, a)(t1 p1, t2 p2) { return FNAM(t, a)(p1, p2); }
1010#define F3 (t , a , rt , t1 , p1 , t2 , p2 , t3 , p3 ) rt GFNAM(t, a)(t1 p1, t2 p2, t3 p3) { return FNAM(t, a)(p1, p2, p3); }
11+ // map 3-argument _gen to 2-argument, discarding last
12+ #define F32 (t , a , rt , t1 , p1 , t2 , p2 , t3 , p3 ) rt GFNAM(t, a)(t1 p1, t2 p2, t3 p3) { (void)p3; return FNAM(t, a)(p1, p2); }
13+ // void return, ignore return value
14+ #define F3V (t , a , rt , t1 , p1 , t2 , p2 , t3 , p3 ) rt GFNAM(t, a)(t1 p1, t2 p2, t3 p3) { (void)FNAM(t, a)(p1, p2, p3); }
1115
1216#define GEN_THUNKS (ftype ) \
1317 F2(ftype, allocate, bool, uint32_t, size, void*, filter) \
1418 F1(ftype, free, void, void*, filter) \
1519 F1(ftype, size_in_bytes, size_t, const void*, filter) \
1620 F1(ftype, serialization_bytes, size_t, void*, filter) \
17- F2 (ftype, serialize, void, void*, filter, char*, buffer) \
18- F2 (ftype, deserialize, bool, void*, filter, const char*, buffer) \
21+ F32 (ftype, serialize, void, void*, filter, char*, buffer, size_t, len) \
22+ F32 (ftype, deserialize, bool, void*, filter, const char*, buffer, size_t, len) \
1923 F3(ftype, populate, bool, uint64_t*, keys, uint32_t, size, void*, filter) \
20- F2(ftype, contain, bool, uint64_t, key, const void*, filter)
24+ F2(ftype, contain, bool, uint64_t, key, const void*, filter) \
25+ F1(ftype, pack_bytes, size_t, void*, filter) \
26+ F3V(ftype, pack, void, void*, filter, char*, buffer, size_t, len) \
27+ F3(ftype, unpack, bool, void*, filter, const char*, buffer, size_t, len)
28+
2129
2230GEN_THUNKS (xor8 )
2331GEN_THUNKS (xor16 )
@@ -32,8 +40,8 @@ bool test(size_t size, size_t repeated_size, void *filter,
3240 void (* free_filter )(void * filter ),
3341 size_t (* size_in_bytes )(const void * filter ),
3442 size_t (* serialization_bytes )(void * filter ),
35- void (* serialize )(void * filter , char * buffer ),
36- bool (* deserialize )(void * filter , const char * buffer ),
43+ void (* serialize )(void * filter , char * buffer , size_t len ),
44+ bool (* deserialize )(void * filter , const char * buffer , size_t len ),
3745 bool (* populate )(uint64_t * keys , uint32_t size , void * filter ),
3846 bool (* contain )(uint64_t key , const void * filter )) {
3947 allocate ((uint32_t )size , filter );
@@ -56,9 +64,9 @@ bool test(size_t size, size_t repeated_size, void *filter,
5664
5765 size_t buffer_size = serialization_bytes (filter );
5866 char * buffer = (char * )malloc (buffer_size );
59- serialize (filter , buffer );
67+ serialize (filter , buffer , buffer_size );
6068 free_filter (filter );
61- deserialize (filter , buffer );
69+ deserialize (filter , buffer , buffer_size );
6270 free (buffer );
6371 for (size_t i = 0 ; i < size ; i ++ ) {
6472 if (!(contain )(big_set [i ], filter )) {
@@ -79,10 +87,14 @@ bool test(size_t size, size_t repeated_size, void *filter,
7987 }
8088 double fpp = (double )random_matches * 1.0 / (double )trials ;
8189 printf (" fpp %3.5f (estimated) \n" , fpp );
82- double bpe = (double )size_in_bytes (filter ) * 8.0 / (double )size ;
83- printf (" bits per entry %3.2f\n" , bpe );
84- printf (" bits per entry %3.2f (theoretical lower bound)\n" , - log (fpp )/log (2 ));
85- printf (" efficiency ratio %3.3f \n" , bpe /(- log (fpp )/log (2 )));
90+ size_t core_size = size_in_bytes (filter );
91+ printf (" size in-core %zu wire %zu\n" , core_size , buffer_size );
92+ double cbpe = (double )core_size * 8.0 / (double )size ;
93+ double wbpe = (double )buffer_size * 8.0 / (double )size ;
94+ printf (" bits per entry in-core %3.2f wire %3.2f\n" , cbpe , wbpe );
95+ double bound = - log (fpp )/log (2 );
96+ printf (" bits per entry %3.2f (theoretical lower bound)\n" , bound );
97+ printf (" efficiency ratio in-core %3.3f wire %3.3f\n" , cbpe /bound , wbpe /bound );
8698 free_filter (filter );
8799 free (big_set );
88100 return true;
@@ -132,6 +144,35 @@ bool testxor16(size_t size) {
132144}
133145
134146
147+ bool testxor8pack (size_t size ) {
148+ printf ("testing xor8 pack/unpack\n" );
149+ xor8_t filter ;
150+ return test (size , 0 , & filter ,
151+ xor8_allocate_gen ,
152+ xor8_free_gen ,
153+ xor8_size_in_bytes_gen ,
154+ xor8_pack_bytes_gen ,
155+ xor8_pack_gen ,
156+ xor8_unpack_gen ,
157+ xor8_populate_gen ,
158+ xor8_contain_gen );
159+ }
160+
161+ bool testxor16pack (size_t size ) {
162+ printf ("testing xor16 pack/unpack\n" );
163+ xor8_t filter ;
164+ return test (size , 0 , & filter ,
165+ xor16_allocate_gen ,
166+ xor16_free_gen ,
167+ xor16_size_in_bytes_gen ,
168+ xor16_pack_bytes_gen ,
169+ xor16_pack_gen ,
170+ xor16_unpack_gen ,
171+ xor16_populate_gen ,
172+ xor16_contain_gen );
173+ }
174+
175+
135176
136177bool testbufferedxor16 (size_t size ) {
137178 printf ("testing buffered xor16\n" );
@@ -161,8 +202,6 @@ bool testbinaryfuse8(size_t size, size_t repeated_size) {
161202 binary_fuse8_contain_gen );
162203}
163204
164-
165-
166205bool testbinaryfuse16 (size_t size , size_t repeated_size ) {
167206 printf ("testing binary fuse16 with size %zu and %zu duplicates\n" , size , repeated_size );
168207 binary_fuse16_t filter ;
@@ -177,6 +216,35 @@ bool testbinaryfuse16(size_t size, size_t repeated_size) {
177216 binary_fuse16_contain_gen );
178217}
179218
219+
220+ bool testbinaryfuse8pack (size_t size , size_t repeated_size ) {
221+ printf ("testing binary fuse8 pack/unpack with size %zu and %zu duplicates\n" , size , repeated_size );
222+ binary_fuse8_t filter ;
223+ return test (size , repeated_size , & filter ,
224+ binary_fuse8_allocate_gen ,
225+ binary_fuse8_free_gen ,
226+ binary_fuse8_size_in_bytes_gen ,
227+ binary_fuse8_pack_bytes_gen ,
228+ binary_fuse8_pack_gen ,
229+ binary_fuse8_unpack_gen ,
230+ binary_fuse8_populate_gen ,
231+ binary_fuse8_contain_gen );
232+ }
233+
234+ bool testbinaryfuse16pack (size_t size , size_t repeated_size ) {
235+ printf ("testing binary fuse16 pack/unpack with size %zu and %zu duplicates\n" , size , repeated_size );
236+ binary_fuse16_t filter ;
237+ return test (size , repeated_size , & filter ,
238+ binary_fuse16_allocate_gen ,
239+ binary_fuse16_free_gen ,
240+ binary_fuse16_size_in_bytes_gen ,
241+ binary_fuse16_pack_bytes_gen ,
242+ binary_fuse16_pack_gen ,
243+ binary_fuse16_unpack_gen ,
244+ binary_fuse16_populate_gen ,
245+ binary_fuse16_contain_gen );
246+ }
247+
180248void failure_rate_binary_fuse16 () {
181249 printf ("testing binary fuse16 for failure rate\n" );
182250 // we construct many 5000-long input cases and check the probability of failure.
@@ -208,6 +276,10 @@ int main() {
208276 printf ("\n" );
209277 if (!testbinaryfuse16 (size , 0 )) { abort (); }
210278 printf ("\n" );
279+ if (!testbinaryfuse8pack (size , 0 )) { abort (); }
280+ printf ("\n" );
281+ if (!testbinaryfuse16pack (size , 0 )) { abort (); }
282+ printf ("\n" );
211283 if (!testbinaryfuse8 (size , 10 )) { abort (); }
212284 printf ("\n" );
213285 if (!testbinaryfuse16 (size , 10 )) { abort (); }
@@ -220,6 +292,10 @@ int main() {
220292 printf ("\n" );
221293 if (!testxor16 (size )) { abort (); }
222294 printf ("\n" );
295+ if (!testxor8pack (size )) { abort (); }
296+ printf ("\n" );
297+ if (!testxor16pack (size )) { abort (); }
298+ printf ("\n" );
223299 printf ("======\n" );
224300 }
225301
0 commit comments