- 布隆过滤器的基本概念
布隆过滤器是由bitmap和几个hash函数实现的,主要用于检查一个元素是否存在与一个集合中。
- 布隆过滤器的优缺点
优点:查找时间和快空间效率都优于其他的算法;
缺点:有误错率。可能你要查找的元素并不存在,但是以前插入的数据刚好将你的key经过几个映射函数的bit位置为1,这就造成一种假象,你要查找的数据存在。直觉上判断这种情况发生的概率还是比较低的,能想到的就是当你的数据量很大的时候,这种错误率就明显上升了。
- 布隆过滤器的基本操作
布隆过滤器的基本操作要基于位图的基本操作来实现。
首先我们先来给定两个哈希操作函数:
hash_func.h:
#pragma once #include<stddef.h> size_t BKDRHash(const char* str); size_t SDBMHash(const char* str);
hash_func.c:
#pragma once #include<stddef.h> size_t BKDRHash(const char* str); size_t SDBMHash(const char* str); [kaikai@localhost bloom_filter]$ cat hash_func.c #include"hash_func.h" size_t BKDRHash(const char* str){ size_t hash = 0; size_t ch = 0; while(ch = (size_t)*str++){ hash = hash * 131 + ch; } return hash; } size_t SDBMHash(const char* str){ size_t hash = 0; size_t ch = 0; while(ch = (size_t)*str++){ hash = 65599 * hash + ch; } return hash; }
基于这两个操作函数,我们再来实现布隆过滤器的基本操作:
bloom_filter.h:
#pragma once #include"bitmap.h" #define BloomHashCount 2 typedef uint64_t(*BloomHash)(const char*);//此处定义了一个布隆过滤器的哈希函数,将字符串转成下标 typedef struct BloomFilter{ Bitmap bm; BloomHash bloom_hash[BloomHashCount]; }BloomFilter; void BloomFilterInit(BloomFilter* bf); void BloomFilterDestroy(BloomFilter* bf); void BloomFilterInsert(BloomFilter* bf,const char* str); int BloomFilterIsExit(BloomFilter* bf,const char* str);
bloom_filter.c:
#include"bloom_filter.h" #include"hash_func.h" #define BitmapMaxSize 10000 void BloomFilterInit(BloomFilter* bf){ if(bf == NULL) return; BitmapInit(&bf->bm,BitmapMaxSize); bf->bloom_hash[0] = SDBMHash; bf->bloom_hash[1] = BKDRHash; return; } void BloomFilterDestroy(BloomFilter* bf){ if(bf == NULL) return; bf->bloom_hash[0] = NULL; bf->bloom_hash[1] = NULL; BitmapDestroy(&bf->bm); return; } void BloomFilterInsert(BloomFilter* bf,const char* str){ if(bf == NULL || str == NULL) return; size_t i = 0; for(;i < BloomHashCount;++i){ size_t hash = bf->bloom_hash[i](str) %BitmapMaxSize; BitmapSet(&bf->bm,hash); } return; } int BloomFilterIsExit(BloomFilter* bf,const char* str){ if(bf == NULL || str == NULL) return 0; size_t i = 0; for(;i < BloomHashCount;++i){ uint64_t hash = bf->bloom_hash[i](str) % BitmapMaxSize; int ret = BitmapTest(&bf->bm,hash); if(ret == 0) return 0; } return 1; }
最后编写测试函数验证功能:
#include"bloom_filter.h" #include"hash_func.h" #define PRINT_HEAD printf("\n============%s============\n",__FUNCTION__); void TestInit(){ PRINT_HEAD; BloomFilter bf; BloomFilterInit(&bf); printf("bloom_hash[0] expect %p,actual %p\n",SDBMHash,bf.bloom_hash[0]); printf("bloom_hash[1] expect %p,actual %p\n",BKDRHash,bf.bloom_hash[1]); return; } void TestDestroy(){ PRINT_HEAD; BloomFilter bf; BloomFilterInit(&bf); BloomFilterDestroy(&bf); printf("bloom_hash[0] expect NULL,actual %p\n",bf.bloom_hash[0]); printf("bloom_hash[1] expect NULL,actual %p\n",bf.bloom_hash[1]); return; } void TestInsertAndIsExit(){ PRINT_HEAD; BloomFilter bf; BloomFilterInit(&bf); BloomFilterInsert(&bf,"haha"); BloomFilterInsert(&bf,"hehe"); int ret = BloomFilterIsExit(&bf,"haha"); printf("ret expect 1,actual %d\n",ret); ret = BloomFilterIsExit(&bf,"hehe"); printf("ret expect 1,actual %d\n",ret); ret = BloomFilterIsExit(&bf,"hello"); printf("ret expect 0,actual %d\n",ret); return; } int main(){ TestInit(); TestDestroy(); TestInsertAndIsExit(); return 0; }
结果演示:
扫描二维码关注公众号,回复:
1084753 查看本文章