22#include "xorfilter.h"
33#include <assert.h>
44
5- // generic function dispatch
6-
7- bool gen_xor8_allocate (uint32_t size , void * filter ) { return xor8_allocate (size , filter ); }
8- bool gen_xor16_allocate (uint32_t size , void * filter ) { return xor16_allocate (size , filter ); }
9- bool gen_binary_fuse8_allocate (uint32_t size , void * filter ) { return binary_fuse8_allocate (size , filter ); }
10- bool gen_binary_fuse16_allocate (uint32_t size , void * filter ) { return binary_fuse16_allocate (size , filter ); }
11-
12- void gen_xor8_free (void * filter ) { xor8_free (filter ); }
13- void gen_xor16_free (void * filter ) { xor16_free (filter ); }
14- void gen_binary_fuse8_free (void * filter ) { binary_fuse8_free (filter ); }
15- void gen_binary_fuse16_free (void * filter ) { binary_fuse16_free (filter ); }
16-
17- size_t gen_xor8_size_in_bytes (const void * filter ) { return xor8_size_in_bytes (filter ); }
18- size_t gen_xor16_size_in_bytes (const void * filter ) { return xor16_size_in_bytes (filter ); }
19- size_t gen_binary_fuse8_size_in_bytes (const void * filter ) { return binary_fuse8_size_in_bytes (filter ); }
20- size_t gen_binary_fuse16_size_in_bytes (const void * filter ) { return binary_fuse16_size_in_bytes (filter ); }
21-
22- size_t gen_xor8_serialization_bytes (void * filter ) { return xor8_serialization_bytes (filter ); }
23- size_t gen_xor16_serialization_bytes (void * filter ) { return xor16_serialization_bytes (filter ); }
24- size_t gen_binary_fuse8_serialization_bytes (void * filter ) { return binary_fuse8_serialization_bytes (filter ); }
25- size_t gen_binary_fuse16_serialization_bytes (void * filter ) { return binary_fuse16_serialization_bytes (filter ); }
26-
27- void gen_xor8_serialize (void * filter , char * buffer ) { xor8_serialize (filter , buffer ); }
28- void gen_xor16_serialize (void * filter , char * buffer ) { xor16_serialize (filter , buffer ); }
29- void gen_binary_fuse8_serialize (void * filter , char * buffer ) { binary_fuse8_serialize (filter , buffer ); }
30- void gen_binary_fuse16_serialize (void * filter , char * buffer ) { binary_fuse16_serialize (filter , buffer ); }
31-
32- bool gen_xor8_deserialize (void * filter , const char * buffer ) { return xor8_deserialize (filter , buffer ); }
33- bool gen_xor16_deserialize (void * filter , const char * buffer ) { return xor16_deserialize (filter , buffer ); }
34- bool gen_binary_fuse8_deserialize (void * filter , const char * buffer ) { return binary_fuse8_deserialize (filter , buffer ); }
35- bool gen_binary_fuse16_deserialize (void * filter , const char * buffer ) { return binary_fuse16_deserialize (filter , buffer ); }
36-
37- bool gen_xor8_populate (uint64_t * keys , uint32_t size , void * filter ) { return xor8_populate (keys , size , filter ); }
38- bool gen_xor8_buffered_populate (uint64_t * keys , uint32_t size , void * filter ) { return xor8_buffered_populate (keys , size , filter ); }
39- bool gen_xor16_populate (uint64_t * keys , uint32_t size , void * filter ) { return xor16_populate (keys , size , filter ); }
40- bool gen_xor16_buffered_populate (uint64_t * keys , uint32_t size , void * filter ) { return xor16_buffered_populate (keys , size , filter ); }
41- bool gen_binary_fuse8_populate (uint64_t * keys , uint32_t size , void * filter ) { return binary_fuse8_populate (keys , size , filter ); }
42- bool gen_binary_fuse16_populate (uint64_t * keys , uint32_t size , void * filter ) { return binary_fuse16_populate (keys , size , filter ); }
43-
44- bool gen_xor8_contain (uint64_t key , const void * filter ) { return xor8_contain (key , filter ); }
45- bool gen_xor16_contain (uint64_t key , const void * filter ) { return xor16_contain (key , filter ); }
46- bool gen_binary_fuse8_contain (uint64_t key , const void * filter ) { return binary_fuse8_contain (key , filter ); }
47- bool gen_binary_fuse16_contain (uint64_t key , const void * filter ) { return binary_fuse16_contain (key , filter ); }
48-
49- typedef bool (* allocate_fpt )(uint32_t size , void * filter );
50- typedef void (* free_fpt )(void * filter );
51- typedef size_t (* size_in_bytes_fpt )(const void * filter );
52- typedef size_t (* serialization_bytes_fpt )(void * filter );
53- typedef void (* serialize_fpt )(void * filter , char * buffer );
54- typedef bool (* deserialize_fpt )(void * filter , const char * buffer );
55- typedef bool (* populate_fpt )(uint64_t * keys , uint32_t size , void * filter );
56- typedef bool (* contain_fpt )(uint64_t key , const void * filter );
5+ // generic proxy for filter, important that this is a struct, not void
6+ // as § 6.2.5..28: "All pointers to structure types shall have the
7+ // same representation and alignment requirements as each other"
8+ typedef struct { int dummy_ ; } gen_filter ;
9+
10+ typedef bool (* allocate_fpt )(uint32_t size , gen_filter * filter );
11+ typedef void (* free_fpt )(gen_filter * filter );
12+ typedef size_t (* size_in_bytes_fpt )(const gen_filter * filter );
13+ typedef size_t (* serialization_bytes_fpt )(gen_filter * filter );
14+ typedef void (* serialize_fpt )(gen_filter * filter , char * buffer );
15+ typedef bool (* deserialize_fpt )(gen_filter * filter , const char * buffer );
16+ typedef bool (* populate_fpt )(uint64_t * keys , uint32_t size , gen_filter * filter );
17+ typedef bool (* contain_fpt )(uint64_t key , const gen_filter * filter );
18+
19+ typedef void (* gfp )(void ); // generic function pointer
5720
5821// generic test runner
59-
6022bool test (size_t size , size_t repeated_size , void * filter ,
61- allocate_fpt allocate ,
62- free_fpt free_filter ,
63- size_in_bytes_fpt size_in_bytes ,
64- serialization_bytes_fpt serialization_bytes ,
65- serialize_fpt serialize ,
66- deserialize_fpt deserialize ,
67- populate_fpt populate ,
68- contain_fpt contain ) {
69- allocate ((uint32_t )size , filter );
23+ gfp allocate ,
24+ gfp free_filter ,
25+ gfp size_in_bytes ,
26+ gfp serialization_bytes ,
27+ gfp serialize ,
28+ gfp deserialize ,
29+ gfp populate ,
30+ gfp contain ) {
31+ (( allocate_fpt ) allocate ) ((uint32_t )size , filter );
7032 // we need some set of values
7133 uint64_t * big_set = (uint64_t * )malloc (sizeof (uint64_t ) * size );
7234 for (size_t i = 0 ; i < size - repeated_size ; i ++ ) {
@@ -76,22 +38,22 @@ bool test(size_t size, size_t repeated_size, void *filter,
7638 big_set [size - i - 1 ] = i ; // we use contiguous values
7739 }
7840 // we construct the filter
79- if (!populate (big_set , (uint32_t )size , filter )) { return false; }
41+ if (!(( populate_fpt ) populate ) (big_set , (uint32_t )size , filter )) { return false; }
8042 for (size_t i = 0 ; i < size ; i ++ ) {
81- if (!contain (big_set [i ], filter )) {
43+ if (!(( contain_fpt ) contain ) (big_set [i ], filter )) {
8244 printf ("bug!\n" );
8345 return false;
8446 }
8547 }
8648
87- size_t buffer_size = serialization_bytes (filter );
49+ size_t buffer_size = (( serialization_bytes_fpt ) serialization_bytes ) (filter );
8850 char * buffer = (char * )malloc (buffer_size );
89- serialize (filter , buffer );
90- free_filter (filter );
91- deserialize (filter , buffer );
51+ (( serialize_fpt ) serialize ) (filter , buffer );
52+ (( free_fpt ) free_filter ) (filter );
53+ (( deserialize_fpt ) deserialize ) (filter , buffer );
9254 free (buffer );
9355 for (size_t i = 0 ; i < size ; i ++ ) {
94- if (!contain (big_set [i ], filter )) {
56+ if (!(( contain_fpt ) contain ) (big_set [i ], filter )) {
9557 printf ("bug!\n" );
9658 return false;
9759 }
@@ -101,143 +63,110 @@ bool test(size_t size, size_t repeated_size, void *filter,
10163 size_t trials = 10000000 ;
10264 for (size_t i = 0 ; i < trials ; i ++ ) {
10365 uint64_t random_key = ((uint64_t )rand () << 32U ) + (uint64_t )rand ();
104- if (contain (random_key , filter )) {
66+ if ((( contain_fpt ) contain ) (random_key , filter )) {
10567 if (random_key >= size ) {
10668 random_matches ++ ;
10769 }
10870 }
10971 }
11072 double fpp = (double )random_matches * 1.0 / (double )trials ;
11173 printf (" fpp %3.5f (estimated) \n" , fpp );
112- double bpe = (double )size_in_bytes (filter ) * 8.0 / (double )size ;
74+ double bpe = (double )(( size_in_bytes_fpt ) size_in_bytes ) (filter ) * 8.0 / (double )size ;
11375 printf (" bits per entry %3.2f\n" , bpe );
11476 printf (" bits per entry %3.2f (theoretical lower bound)\n" , - log (fpp )/log (2 ));
11577 printf (" efficiency ratio %3.3f \n" , bpe /(- log (fpp )/log (2 )));
116- free_filter (filter );
78+ (( free_fpt ) free_filter ) (filter );
11779 free (big_set );
11880 return true;
11981}
12082
12183bool testbufferedxor8 (size_t size ) {
12284 printf ("testing buffered xor8\n" );
123- xor8_t filter = { 0 }; // zero initialisation silences unitialized warning
85+ xor8_t filter ;
12486 return test (size , 0 , & filter ,
125- gen_xor8_allocate ,
126- gen_xor8_free ,
127- gen_xor8_size_in_bytes ,
128- gen_xor8_serialization_bytes ,
129- gen_xor8_serialize ,
130- gen_xor8_deserialize ,
131- gen_xor8_buffered_populate ,
132- gen_xor8_contain );
87+ ( gfp ) xor8_allocate ,
88+ ( gfp ) xor8_free ,
89+ ( gfp ) xor8_size_in_bytes ,
90+ ( gfp ) xor8_serialization_bytes ,
91+ ( gfp ) xor8_serialize ,
92+ ( gfp ) xor8_deserialize ,
93+ ( gfp ) xor8_buffered_populate ,
94+ ( gfp ) xor8_contain );
13395}
13496
13597
13698bool testxor8 (size_t size ) {
13799 printf ("testing xor8\n" );
138-
139- xor8_t filter = {0 }; // zero initialisation silences unitialized warning
100+ xor8_t filter ;
140101 return test (size , 0 , & filter ,
141- gen_xor8_allocate ,
142- gen_xor8_free ,
143- gen_xor8_size_in_bytes ,
144- gen_xor8_serialization_bytes ,
145- gen_xor8_serialize ,
146- gen_xor8_deserialize ,
147- gen_xor8_populate ,
148- gen_xor8_contain );
102+ ( gfp ) xor8_allocate ,
103+ ( gfp ) xor8_free ,
104+ ( gfp ) xor8_size_in_bytes ,
105+ ( gfp ) xor8_serialization_bytes ,
106+ ( gfp ) xor8_serialize ,
107+ ( gfp ) xor8_deserialize ,
108+ ( gfp ) xor8_populate ,
109+ ( gfp ) xor8_contain );
149110}
150111
151112bool testxor16 (size_t size ) {
152113 printf ("testing xor16\n" );
153- xor16_t filter = { 0 }; // zero initialisation silences unitialized warning
114+ xor16_t filter ;
154115 return test (size , 0 , & filter ,
155- gen_xor16_allocate ,
156- gen_xor16_free ,
157- gen_xor16_size_in_bytes ,
158- gen_xor16_serialization_bytes ,
159- gen_xor16_serialize ,
160- gen_xor16_deserialize ,
161- gen_xor16_populate ,
162- gen_xor16_contain );
116+ ( gfp ) xor16_allocate ,
117+ ( gfp ) xor16_free ,
118+ ( gfp ) xor16_size_in_bytes ,
119+ ( gfp ) xor16_serialization_bytes ,
120+ ( gfp ) xor16_serialize ,
121+ ( gfp ) xor16_deserialize ,
122+ ( gfp ) xor16_populate ,
123+ ( gfp ) xor16_contain );
163124}
164125
165126
166127
167128bool testbufferedxor16 (size_t size ) {
168129 printf ("testing buffered xor16\n" );
169- xor16_t filter = { 0 }; // zero initialisation silences unitialized warning
130+ xor16_t filter ;
170131 return test (size , 0 , & filter ,
171- gen_xor16_allocate ,
172- gen_xor16_free ,
173- gen_xor16_size_in_bytes ,
174- gen_xor16_serialization_bytes ,
175- gen_xor16_serialize ,
176- gen_xor16_deserialize ,
177- gen_xor16_buffered_populate ,
178- gen_xor16_contain );
132+ ( gfp ) xor16_allocate ,
133+ ( gfp ) xor16_free ,
134+ ( gfp ) xor16_size_in_bytes ,
135+ ( gfp ) xor16_serialization_bytes ,
136+ ( gfp ) xor16_serialize ,
137+ ( gfp ) xor16_deserialize ,
138+ ( gfp ) xor16_buffered_populate ,
139+ ( gfp ) xor16_contain );
179140}
180141
181- bool testbinaryfuse8 (size_t size ) {
182- printf ("testing binary fuse8 with size %zu\n" , size );
183- binary_fuse8_t filter = {0 }; // zero initialisation silences unitialized warning
184- return test (size , 0 , & filter ,
185- gen_binary_fuse8_allocate ,
186- gen_binary_fuse8_free ,
187- gen_binary_fuse8_size_in_bytes ,
188- gen_binary_fuse8_serialization_bytes ,
189- gen_binary_fuse8_serialize ,
190- gen_binary_fuse8_deserialize ,
191- gen_binary_fuse8_populate ,
192- gen_binary_fuse8_contain );
193- }
194-
195-
196-
197- bool testbinaryfuse16 (size_t size ) {
198- printf ("testing binary fuse16\n" );
199- binary_fuse16_t filter = {0 }; // zero initialisation silences unitialized warning
200- return test (size , 0 , & filter ,
201- gen_binary_fuse16_allocate ,
202- gen_binary_fuse16_free ,
203- gen_binary_fuse16_size_in_bytes ,
204- gen_binary_fuse16_serialization_bytes ,
205- gen_binary_fuse16_serialize ,
206- gen_binary_fuse16_deserialize ,
207- gen_binary_fuse16_populate ,
208- gen_binary_fuse16_contain );
142+ bool testbinaryfuse8 (size_t size , size_t repeated_size ) {
143+ printf ("testing binary fuse8 with size %zu and %zu duplicates\n" , size , repeated_size );
144+ binary_fuse8_t filter ;
145+ return test (size , repeated_size , & filter ,
146+ (gfp )binary_fuse8_allocate ,
147+ (gfp )binary_fuse8_free ,
148+ (gfp )binary_fuse8_size_in_bytes ,
149+ (gfp )binary_fuse8_serialization_bytes ,
150+ (gfp )binary_fuse8_serialize ,
151+ (gfp )binary_fuse8_deserialize ,
152+ (gfp )binary_fuse8_populate ,
153+ (gfp )binary_fuse8_contain );
209154}
210155
211156
212157
213- bool testbinaryfuse8_dup (size_t size ) {
214- printf ("testing binary fuse8 with duplicates\n" );
215- binary_fuse8_t filter = {0 }; // zero initialisation silences unitialized warning
216- return test (size , 10 , & filter ,
217- gen_binary_fuse8_allocate ,
218- gen_binary_fuse8_free ,
219- gen_binary_fuse8_size_in_bytes ,
220- gen_binary_fuse8_serialization_bytes ,
221- gen_binary_fuse8_serialize ,
222- gen_binary_fuse8_deserialize ,
223- gen_binary_fuse8_populate ,
224- gen_binary_fuse8_contain );
225- }
226-
227-
228-
229- bool testbinaryfuse16_dup (size_t size ) {
230- printf ("testing binary fuse16 with duplicates\n" );
231- binary_fuse16_t filter = {0 }; // zero initialisation silences unitialized warning
232- return test (size , 10 , & filter ,
233- gen_binary_fuse16_allocate ,
234- gen_binary_fuse16_free ,
235- gen_binary_fuse16_size_in_bytes ,
236- gen_binary_fuse16_serialization_bytes ,
237- gen_binary_fuse16_serialize ,
238- gen_binary_fuse16_deserialize ,
239- gen_binary_fuse16_populate ,
240- gen_binary_fuse16_contain );
158+ bool testbinaryfuse16 (size_t size , size_t repeated_size ) {
159+ printf ("testing binary fuse16 with size %zu and %zu duplicates\n" , size , repeated_size );
160+ binary_fuse16_t filter ;
161+ return test (size , repeated_size , & filter ,
162+ (gfp )binary_fuse16_allocate ,
163+ (gfp )binary_fuse16_free ,
164+ (gfp )binary_fuse16_size_in_bytes ,
165+ (gfp )binary_fuse16_serialization_bytes ,
166+ (gfp )binary_fuse16_serialize ,
167+ (gfp )binary_fuse16_deserialize ,
168+ (gfp )binary_fuse16_populate ,
169+ (gfp )binary_fuse16_contain );
241170}
242171
243172void failure_rate_binary_fuse16 () {
@@ -267,13 +196,13 @@ int main() {
267196 failure_rate_binary_fuse16 ();
268197 for (size_t size = 1000 ; size <= 1000000 ; size *= 300 ) {
269198 printf ("== size = %zu \n" , size );
270- if (!testbinaryfuse8 (size )) { abort (); }
199+ if (!testbinaryfuse8 (size , 0 )) { abort (); }
271200 printf ("\n" );
272- if (!testbinaryfuse16 (size )) { abort (); }
201+ if (!testbinaryfuse16 (size , 0 )) { abort (); }
273202 printf ("\n" );
274- if (!testbinaryfuse8_dup (size )) { abort (); }
203+ if (!testbinaryfuse8 (size , 10 )) { abort (); }
275204 printf ("\n" );
276- if (!testbinaryfuse16_dup (size )) { abort (); }
205+ if (!testbinaryfuse16 (size , 10 )) { abort (); }
277206 printf ("\n" );
278207 if (!testbufferedxor8 (size )) { abort (); }
279208 printf ("\n" );
@@ -287,10 +216,10 @@ int main() {
287216 }
288217
289218 // test small edge-case binary fuse input sizes
290- if (!testbinaryfuse8 (0 )) { abort (); }
291- if (!testbinaryfuse8 (1 )) { abort (); }
292- if (!testbinaryfuse8 (2 )) { abort (); }
293- if (!testbinaryfuse16 (0 )) { abort (); }
294- if (!testbinaryfuse16 (1 )) { abort (); }
295- if (!testbinaryfuse16 (2 )) { abort (); }
219+ if (!testbinaryfuse8 (0 , 0 )) { abort (); }
220+ if (!testbinaryfuse8 (1 , 0 )) { abort (); }
221+ if (!testbinaryfuse8 (2 , 0 )) { abort (); }
222+ if (!testbinaryfuse16 (0 , 0 )) { abort (); }
223+ if (!testbinaryfuse16 (1 , 0 )) { abort (); }
224+ if (!testbinaryfuse16 (2 , 0 )) { abort (); }
296225}
0 commit comments