test_purga.c revision a74702c6
1/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */ 2#include <assert.h> 3#include <stdlib.h> 4#include <string.h> 5#ifndef WIN32 6#include <unistd.h> 7#else 8#include "getopt.h" 9#endif 10 11#include <openssl/rand.h> 12 13#include "lsquic.h" 14#include "lsquic_int_types.h" 15#include "lsquic_logger.h" 16#include "lsquic_purga.h" 17 18#define MIN_CID_LEN 4 19 20static int s_eight; 21 22static void 23bloom_test (unsigned count, unsigned miss_searches, unsigned hit_searches) 24{ 25#ifndef NDEBUG 26 struct purga_bloom_stats *stats; 27#endif 28 struct lsquic_purga *purga; 29 struct purga_el *puel; 30 lsquic_cid_t *cids, cid; 31 unsigned i, j; 32 33 cids = malloc(count * sizeof(cids[0])); 34 assert(cids); 35 36 for (i = 0; i < count; ++i) 37 { 38 cids[i].len = s_eight ? 8 : MIN_CID_LEN + rand() % (MAX_CID_LEN - MIN_CID_LEN); 39 RAND_bytes(cids[i].idbuf, cids[i].len); 40 } 41 42 purga = lsquic_purga_new(~0, NULL, NULL); 43 44 /* Add CIDs */ 45 for (i = 0; i < count; ++i) 46 lsquic_purga_add(purga, &cids[i], NULL, 0, 0); 47 48 /* Check that they are all there */ 49 for (i = 0; i < count; ++i) 50 { 51 puel = lsquic_purga_contains(purga, &cids[i]); 52 assert(puel); 53 } 54 55 /* Run hit searches */ 56 for (i = 0; i < hit_searches; ++i) 57 { 58 j = rand() % count; 59 puel = lsquic_purga_contains(purga, &cids[j]); 60 assert(puel); 61 } 62 63 /* Generate random CIDs and check that they are not found: */ 64 for (i = 0; i < miss_searches; ++i) 65 { 66 cid.len = s_eight ? 8 : MIN_CID_LEN + rand() % (MAX_CID_LEN - MIN_CID_LEN); 67 RAND_bytes(cid.idbuf, cid.len); 68 puel = lsquic_purga_contains(purga, &cid); 69 if (puel) 70 { 71 for (j = 0; j < count; ++j) 72 if (LSQUIC_CIDS_EQ(&cids[j], &cid)) 73 break; 74 assert(j < count); 75 } 76 } 77 78#ifndef NDEBUG 79 stats = lsquic_purga_get_bloom_stats(purga); 80 LSQ_NOTICE("searches: %lu, false hits: %lu, false hit ratio: %lf", 81 stats->searches, stats->false_hits, 82 (double) stats->false_hits / (double) stats->searches); 83#endif 84 85 lsquic_purga_destroy(purga); 86 free(cids); 87} 88 89 90int 91main (int argc, char **argv) 92{ 93 int opt; 94 unsigned i, per_page, bloom_ins = 0, bloom_miss_sea = 0, bloom_hit_sea = 0; 95 lsquic_cid_t cid; 96 struct lsquic_purga *purga; 97 struct purga_el *puel; 98 99 while (-1 != (opt = getopt(argc, argv, "b:h:l:s:v8"))) 100 { 101 switch (opt) 102 { 103 case '8': 104 s_eight = 1; 105 break; 106 case 'b': 107 bloom_ins = atoi(optarg); 108 break; 109 case 's': 110 bloom_miss_sea = atoi(optarg); 111 break; 112 case 'h': 113 bloom_hit_sea = atoi(optarg); 114 break; 115 case 'l': 116 lsquic_log_to_fstream(stderr, 0); 117 lsquic_logger_lopt(optarg); 118 break; 119 case 'v': 120 lsquic_log_to_fstream(stderr, 0); 121 lsquic_logger_lopt("purga=debug"); 122 break; 123 default: 124 exit(EXIT_FAILURE); 125 } 126 } 127 128 if (bloom_ins) 129 { 130 LSQ_NOTICE("bloom test: will insert %u and search for %u missing " 131 "and %u extant CIDs", bloom_ins, bloom_miss_sea, bloom_hit_sea); 132 bloom_test(bloom_ins, bloom_miss_sea, bloom_hit_sea); 133 exit(EXIT_SUCCESS); 134 } 135 136 per_page = lsquic_purga_cids_per_page(); 137 purga = lsquic_purga_new(10, NULL, NULL); 138 assert(purga); 139 140 cid.len = 3; 141 for (i = 0; i < per_page; ++i) 142 { 143 cid.idbuf[0] = i >> 16; 144 cid.idbuf[1] = i >> 8; 145 cid.idbuf[2] = i; 146 puel = lsquic_purga_add(purga, &cid, NULL, PUTY_CONN_DELETED, 20); 147 assert(puel); 148 puel->puel_time = ~i; 149 } 150 151 for (i = 0; i < per_page; ++i) 152 { 153 cid.idbuf[0] = i >> 16; 154 cid.idbuf[1] = i >> 8; 155 cid.idbuf[2] = i; 156 puel = lsquic_purga_contains(purga, &cid); 157 assert(puel && PUTY_CONN_DELETED == puel->puel_type); 158 assert(~i == puel->puel_time); 159 } 160 161 ++cid.idbuf[1]; 162 lsquic_purga_add(purga, &cid, NULL, PUTY_CONN_DELETED, 31); 163 164 for (i = 0; i < per_page; ++i) 165 { 166 cid.idbuf[0] = i >> 16; 167 cid.idbuf[1] = i >> 8; 168 cid.idbuf[2] = i; 169 puel = lsquic_purga_contains(purga, &cid); 170 assert(!puel); 171 } 172 173 ++cid.idbuf[1]; 174 puel = lsquic_purga_contains(purga, &cid); 175 assert(puel && PUTY_CONN_DELETED == puel->puel_type); 176 177 lsquic_purga_destroy(purga); 178 179 bloom_test(20000, 200000, 2000); 180 181 exit(EXIT_SUCCESS); 182} 183