END_TEST START_TEST(test_flush_close) { bloom_filter_params params = {0, 0, 1e6, 1e-4}; bf_params_for_capacity(¶ms); bloom_bitmap map; bloom_bloomfilter filter; bitmap_from_filename("/tmp/test_flush_close.mmap", params.bytes, 1, SHARED, &map); bf_from_bitmap(&map, params.k_num, 1, &filter); fail_unless(bf_flush(&filter) == 0); fail_unless(bf_close(&filter) == 0); unlink("/tmp/test_flush_close.mmap"); }
/** * Creates a new bloom filter using a given bitmap and k-value. * @arg map A bloom_bitmap pointer. * @arg k_num The number of hash functions to use. Ignored if the header value is different. * @arg new_filter 1 if new, sets the magic byte and does not check it. * @arg filter The filter to setup * @return 0 for success. Negative for error. */ int bf_from_bitmap(bloom_bitmap *map, uint32_t k_num, int new_filter, bloom_bloomfilter *filter) { // Check our args if (map == NULL or k_num < 1) { return -EINVAL; } // Check the size of the map if (map->size < sizeof(bloom_filter_header)) { return -ENOMEM; } // Setup the pointers filter->map = map; filter->header = (bloom_filter_header*)map->mmap; // Get the bitmap size filter->bitmap_size = (map->size - sizeof(bloom_filter_header)) * 8; // Setup the header if it is new if (new_filter) { filter->header->magic = MAGIC_HEADER; filter->header->k_num = k_num; filter->header->count = 0; // Since this is a new filter, force a flush of // the headers. This mainly affects bitmaps that // are in the PERSIST mode. Since no flush happens // until the first key is set, it can cause filters // to be created that have no headers, and thus cannot // be loaded. bf_flush(filter); // Check for the header if not new } else if (filter->header->magic != MAGIC_HEADER) { syslog(LOG_ERR, "Magic byte for bloom filter is wrong! Aborting load."); return -1; } // Setup the offset filter->offset = filter->bitmap_size / filter->header->k_num; // Done, return return 0; }
/** * Flushes and closes the filter. Closes the underlying bitmap, * but does not free it. * @return 0 on success, negative on failure. */ int bf_close(bloom_bloomfilter *filter) { // Make sure we have a filter if (filter == NULL or filter->map == NULL) { return -1; } // Flush first bf_flush(filter); // Clean up the map bitmap_close(filter->map); filter->map = NULL; // Clear all the fields filter->header = NULL; filter->offset = 0; filter->bitmap_size = 0; return 0; }
END_TEST START_TEST(test_bf_flush) { bloom_filter_params params = {0, 0, 1e6, 1e-4}; bf_params_for_capacity(¶ms); bloom_bitmap map; bloom_bloomfilter filter; fail_unless(bitmap_from_filename("/tmp/test_flush.mmap", params.bytes, 1, SHARED, &map) == 0); fail_unless(bf_from_bitmap(&map, params.k_num, 1, &filter) == 0); fchmod(map.fileno, 0777); // Check all the keys get added char buf[100]; int res; for (int i=0;i<1000;i++) { snprintf((char*)&buf, 100, "test%d", i); res = bf_add(&filter, (char*)&buf); fail_unless(res == 1); } fail_unless(bf_flush(&filter) == 0); bloom_bitmap map2; bloom_bloomfilter filter2; fail_unless(bitmap_from_filename("/tmp/test_flush.mmap", params.bytes, 1, SHARED, &map2) == 0); fail_unless(bf_from_bitmap(&map2, params.k_num, 1, &filter2) == 0); // Test all the keys are contained for (int i=0;i<1000;i++) { snprintf((char*)&buf, 100, "test%d", i); res = bf_contains(&filter2, (char*)&buf); fail_unless(res == 1); } unlink("/tmp/test_flush.mmap"); }