bloomer.c (2754B)
1 #include <errno.h> 2 #include <flint.h> 3 #include <fmpz.h> 4 #include <fmpz_vec.h> 5 #include <stdint.h> 6 #include <stdio.h> 7 #include <stdlib.h> 8 9 #include "bloom.h" 10 11 #define BIT_SIZE 4096 12 13 static inline void 14 print_usage(char *prog) 15 { 16 printf("Usage: %s k m n\n" 17 " k: number of hash functions\n" 18 " m: size of bit vector\n" 19 " n: number of entries to insert\n"); 20 } 21 22 int 23 main(int argc, char *argv[]) 24 { 25 uint64_t k, m, n; 26 size_t i; 27 char *ep; 28 bloom_t bloom; 29 30 if (argc != 4) { 31 print_usage(argv[0]); 32 return 1; 33 } 34 35 errno = 0; 36 k = strtoull(argv[1], &ep, 10); 37 if (argv[1][0] == '\0' || *ep != '\0' || 38 (k == ULLONG_MAX && errno == ERANGE)) { 39 fprintf(stderr, 40 "Could not interpret k as a 64 bit integer in base 10."); 41 return 1; 42 } 43 44 errno = 0; 45 m = strtoull(argv[2], &ep, 10); 46 if (argv[2][0] == '\0' || *ep != '\0' || 47 (m == ULLONG_MAX && errno == ERANGE)) { 48 fprintf(stderr, 49 "Could not interpret m as a 64 bit integer in base 10."); 50 return 1; 51 } 52 53 errno = 0; 54 n = strtoull(argv[3], &ep, 10); 55 if (argv[3][0] == '\0' || *ep != '\0' || 56 (n == ULLONG_MAX && errno == ERANGE)) { 57 fprintf(stderr, 58 "Could not interpret n as a 64 bit integer in base 10."); 59 return 1; 60 } 61 62 printf("[+] Running, with\n"); 63 printf(" k = %llu, m = %llu, n = %llu\n", k, m, n); 64 65 bloom_init(&bloom, k, m); 66 67 printf("[+] Generating n random %lld bit integers...\n", BIT_SIZE); 68 flint_rand_t state; 69 flint_randinit(state); 70 71 fmpz *v = _fmpz_vec_init(n); 72 for (i = 0; i < n; i++) { 73 fmpz_randtest_unsigned(&v[i], state, BIT_SIZE); 74 } 75 76 printf("[+] Inserting the numbers in the Bloom filter...\n"); 77 for (i = 0; i < n; i++) { 78 bloom_insert(&bloom, &v[i]); 79 } 80 81 printf("[+] Testing for the inserted numbers...\n"); 82 for (i = 0; i < n; i++) { 83 if (!bloom_prob_contains(&bloom, &v[i])) { 84 fprintf(stderr, "This is not a bloom filter, %zu\n", i); 85 return 1; 86 } 87 } 88 89 fmpz_t t; 90 fmpz_init(t); 91 92 printf("[+] Testing the rate of false positives...\n"); 93 size_t loops = 0; 94 size_t false_pos = 0; 95 int inlist; 96 while (1) { 97 fmpz_randtest_unsigned(t, state, BIT_SIZE); 98 inlist = 0; 99 for (i = 0; i < n; i++) { 100 if (fmpz_cmp(t, &v[i]) == 0) { 101 inlist = 1; 102 break; 103 } 104 } 105 106 if (inlist) { 107 continue; 108 } 109 110 if (bloom_prob_contains(&bloom, t)) { 111 false_pos++; 112 } 113 114 loops++; 115 if (loops % 100000 == 0) { 116 double x = (double)false_pos / (double)loops; 117 printf("%zu out of %zu (%llf per cent) false positive\n", 118 false_pos, loops, x * 100.0); 119 } 120 } 121 122 fmpz_clear(t); 123 flint_randclear(state); 124 125 bloom_clear(&bloom); 126 _fmpz_vec_clear(v, n); 127 128 return 0; 129 }