布隆过滤器的原理、应用场景和源码分析实现

原理

布隆过滤器数据结构
布隆过滤器是一个 bit 向量或者说 bit 数组,长这样:
在这里插入图片描述
如果我们要映射一个值到布隆过滤器中,我们需要使用多个不同的哈希函数生成多个哈希值,并对每个生成的哈希值指向的 bit 位置 1。
例如针对值 “baidu” 和三个不同的哈希函数分别生成了哈希值 1、4、7,则上图转变为:
在这里插入图片描述
Ok,我们现在再存一个值 “tencent”,如果哈希函数返回 3、4、8 的话,图继续变为:
在这里插入图片描述
值得注意的是,4 这个 bit 位由于两个值的哈希函数都返回了这个 bit 位,因此它被覆盖了。

现在我们如果想查询 “dianping” 这个值是否存在,哈希函数返回了 1、5、8三个值,结果我们发现 5 这个 bit 位上的值为 0,说明没有任何一个值映射到这个 bit 位上,因此我们可以很确定地说 “dianping” 这个值不存在。

而当我们需要查询 “baidu” 这个值是否存在的话,那么哈希函数必然会返回 1、4、7,然后我们检查发现这三个 bit 位上的值均为 1,那么我们可以说 “baidu” 存在了么?答案是不可以,只能是 “baidu” 这个值可能存在。

这是为什么呢?答案跟简单,因为随着增加的值越来越多,被置为 1 的 bit 位也会越来越多,这样某个值 “taobao” 即使没有被存储过,但是万一哈希函数返回的三个 bit 位都被其他值置位了 1 ,那么程序还是会判断 “taobao” 这个值存在。

作者:YoungChen__
链接:https://zhuanlan.zhihu.com/p/43263751

特点

  • 可以判断某一个数一定不存在
  • 不可以判断某一个数一定存在

应用场景

  • 海量URL的去重

源码实现

  • 三个哈希函数
unsigned int SDBMHash(char *str, unsigned int size)
{unsigned int hash = 0;while (*str){// equivalent to: hash = 65599*hash + (*str++);hash = (*str++) + (hash << 6) + (hash << 16) - hash;}return (hash & 0x7FFFFFFF) % size;
}// RS Hash Function
unsigned int RSHash(char *str, unsigned int size)
{unsigned int b = 378551;unsigned int a = 63689;unsigned int hash = 0;while (*str){hash = hash * a + (*str++);a *= b;}return (hash & 0x7FFFFFFF) % size;
}// JS Hash Function
unsigned int JSHash(char *str, unsigned int size)
{unsigned int hash = 1315423911;while (*str){hash ^= ((hash << 5) + (*str++) + (hash >> 2));}return (hash & 0x7FFFFFFF) % size;
}
  • 插入并给指定位置置1
void BFInsert(BloomFilter *pBF, const char *str)
{unsigned int i1 = pBF->func1(str, pBF->bm.size);unsigned int i2 = pBF->func2(str, pBF->bm.size);unsigned int i3 = pBF->func3(str, pBF->bm.size);BMSetOne(&(pBF->bm), i1);BMSetOne(&(pBF->bm), i2);BMSetOne(&(pBF->bm), i3);
}

优质参考文献

https://www.jianshu.com/p/2104d11ee0a2

https://blog.csdn.net/championhengyi/article/details/72885500

https://baike.baidu.com/item/布隆过滤器/5384697?fr=aladdin

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/382404.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis运维和开发学习笔记(1) Redis简介

文章目录Redis的特性速度快持久化多种数据结构主从复制高可用和分布式典型的应用场景Redis启动和可执行文件Redis可执行文件说明启动方式验证redisredis常用配置redis数据结构和内部编码Redis是单线程&#xff0c;不会同时执行两条命令哈希慢查询pipelineRedis的特性 速度快 …

Redis运维和开发学习笔记(5) 主从复制和sentinel哨兵模式

Redis运维和开发学习笔记(5) 主从复制和sentinel哨兵模式 主从复制 将主节点的数据改变同步给从节点 作用 备份数据读写分离 存在的问题&#xff1a; 手动干预切主等操作主节点的写能力受到单机限制主节点的存储能力受到单机限制 主从模式的故障恢复 当主节点发生故障时&am…

Redis运维和开发学习笔记(7) 内存管理和过期策略

Redis运维和开发学习笔记(7) 内存管理和过期策略 文章目录Redis运维和开发学习笔记(7) 内存管理和过期策略内存回收策略惰性删除定时任务删除maxmemory过期策略allkeys-lru主从搭建测试搭建完毕主从测试结果volatile-lru测试结果volatile-ttl测试结果allkeys-lru内存回收策略 …

Effective C++学习第十二天

条款47&#xff1a;请使用traits classes表现类型信息STL有五类迭代器分类&#xff0c;input迭代器&#xff08;只读&#xff0c;一次&#xff0c;向前&#xff09;、output迭代器&#xff08;可写&#xff0c;一次&#xff0c;向前&#xff09;、forward迭代器&#xff08;读/…

Linux 学习

1.linux文本命令行语言环境设置命令 查看当前语言环境&#xff1a; echo &#xffe5;LANG 修改&#xff1a; LANG选择的语言环境’ 引申&#xff1a;https://blog.csdn.net/huoyunshen88/article/details/41113633 2.linux中的硬链接和软连接 linux中文件的储存方式&#xf…

redis源码剖析(四)跳表

文章目录整数集合跳跃表压缩列表总结整数集合 当一个集合只包含整数&#xff0c;且这个集合的元素不多的时候&#xff0c;Redis 就会使用整数集合 intset 。首先看 intset 的数据结构&#xff1a; typedef struct intset {// 编码方式uint32_t encoding;// 集合包含的元素数量…

在Redis客户端设置连接密码 并演示密码登录

我们先连接到Redis服务 然后 我们要输入 CONFIG SET requirepass “新密码” 例如 CONFIG SET requirepass "A15167"这样 密码就被设置成立 A15167 我们 输入 AUTH 密码 例如 AUTH A15167这里 返回OK说明成功了 然后 我们退出在登录就真的需要 redis-cli -h IP地…

redis源码剖析(五)—— 字符串,列表,哈希,集合,有序集合

文章目录对象REDIS_STRING &#xff08;字符串&#xff09;REDIS_LIST 列表REDIS_SET &#xff08;集合&#xff09;REDIS_ZSET &#xff08;有序集合&#xff09;REDIS_HASH (hash表)int refcount&#xff08;引用计数器&#xff09;unsigned lru:REDIS_LRU_BITS对象 对于 Re…

redis源码剖析(六)—— Redis 数据库、键过期的实现

文章目录数据库的实现数据库读写操作键的过期实现数据库的实现 我们先看代码 server.h/redisServer struct redisServer{...//保存 db 的数组redisDb *db;//db 的数量int dbnum;... }再看redisDb的代码&#xff1a; typedef struct redisDb {dict *dict; /*…

linux中错误总结归纳

1.使用gcc编译C文件&#xff0c;C文件在for循环语句中出现变量定义 编译器提示错误&#xff1a;“for”loop initial declarations are only allowed in C99 mode. note:use option -stdc99or-stdgnu99 to compile; 原因&#xff1a;gcc的标准是基于c89的&#xff0c;c89不能在…

makefile内容小结

makefile中每个功能主要分为三部分&#xff1a;目标&#xff0c;依赖条件和命令语句 1.支持对比更新的Makefile写法&#xff08;只会编译文件时.o文件和.c文件时间不一致的文件&#xff09; 2.使用makefile自动变量和自定义变量的makefile写法 其中&#xff1a;这三个符号为ma…

事务隔离级别动图演示

事务的基本要素&#xff08;ACID&#xff09; 原子性&#xff08;Atomicity&#xff09; 事务开始后所有操作&#xff0c;要么全部做完&#xff0c;要么全部不做&#xff0c;不可能停滞在中间环节。事务执行过程中出错&#xff0c;会回滚到事务开始前的状态&#xff0c;所有的…

linux中的man文档结构

使用命令 man chapter章节号查找的内容

linux文件操作相关函数

&#xff08;1&#xff09;stat函数&#xff1a;显示文件的相关信息&#xff08;类似于 ls -l的感觉&#xff09; 头文件及函数原型&#xff1a; 函数参数:path:文件的路径&#xff0c;buf是指待写入的文件信息&#xff0c;fd:表示文件描述符&#xff1b; stat,fstat,lstat三者…

linux目录操作函数

&#xff08;1&#xff09;chdir函数&#xff1a;修改当前进程的路径 函数头文件及原型&#xff1a; 参数&#xff1a;要修改的文件路径或文件描述符&#xff08;一般是当前空闲最小的&#xff09; 返回值&#xff1a;成功&#xff08;0&#xff09;&#xff0c;失败&#xff0…

linux中的dup和fcntl的用法

&#xff08;1&#xff09;dup函数&#xff1a;文件描述符的拷贝 函数头文件及函数原型&#xff1a; 参数&#xff1a;原来的文件描述符&#xff0c;新的文件描述符&#xff0c;标志位&#xff1b; 返回值&#xff1a;成功&#xff08;返回新的文件描述符&#xff09;失败&…

使用dup2实现重定向到屏幕终端遇到问题

参考博客&#xff1a;https://blog.csdn.net/qq_26093511/article/details/53255970 参考博客&#xff1a;https://blog.csdn.net/db199410/article/details/52335450#commentBox 1.要解决的问题 通过复制文件描述符来实现文件重定向问题。 2.实现代码 2.代码输出 按照原来的…

linux操作系统之exec函数族

当我们想在进程中执行另外一个函数或程序时&#xff0c;可以使用exec函数。进程调用exec函数&#xff0c;则该进程中用户空间所有代码和数据会完全被新程序替换&#xff0c;但是不会创建新进程&#xff0c;因此进程id不会发生改变。 函数族的头文件&#xff1a;unistd.h l:li…

linux操作系统之子进程回收函数wait和waitpid函数小结

一个进程在终止时会关闭所有的文件描述符&#xff0c;释放用户空间分配的内存&#xff0c;但是它的PCB还保留着&#xff0c;内核在其中还保留着进程的一些信息&#xff1a;如果正常终止&#xff0c;则保留着退出状态&#xff1b;如果异常终止则保存着导致进程种植的信号。 在父…

linux操作系统进程间通信IPC之管道pipe及FIFO

linux环境下,各进程相互独立&#xff0c;如果想要交换两个进程之间的数据&#xff0c;需要通过内核&#xff0c;在内存中提供一个缓存区&#xff0c;一个进程往缓存区中写数据&#xff0c;一个往缓存区读数据&#xff0c;内核提供的这种机制称为进程间通信&#xff08;IPC&…