1.bloom filter算法

传说中,larbin使用bloom filter算法来进行url去重。那我们就先来了解下bloom filter算法好了。

【以下转自:http://hi.baidu.com/fengfengchang/item/050b11390ff61fbd633affac】

先解释一下什么是哈希函数。哈希函数简单来说就是一种映射,它可取值的范围(定义域)通常很大,但值域相对较小。哈希函数所作的工作就是将一个很大定义域内的值映射到一个相对较小的值域内。

传统的哈希存储

假设要哈希的集合为S,它有n个元素。传统的哈希方法是,将哈希区域组织成h(h > n)个格子的列表,每一个格子都能存储S中的一个元素。存储时将S中的每一个元素映射到{0, 1, … , h-1}的范围内,然后以这个值为索引将此元素存储到对应的格子内。由于哈希函数将一个大集合映射到一个小集合中,所以存在将大集合中的多个元素映射到同 一位置的情况,这就是所谓的碰撞(Collision)。当碰撞发生时,有多种策略可供选择,比如用链表将映射到同一位置的元素串起来,或者在碰撞发生时 再进行哈希映射直到找到空位为止等等。

传统的哈希方法不会发生错误,而且存储的元素还可以复原。如果哈希 函数选择得当,碰撞出现的情况比较少,那么查找某一个元素也很快。但是,如果你哈希某个集合只是为了判断某个元素是否在这个集合中,那么你会发现好像存储 整个集合有点浪费。按传统的哈希方法判断某个元素是否属于集合时,会把这个元素和它映射位置上的元素进行匹配,如果完全匹配则说明属于集合,如果不匹配则 不属于。在绝大部分查找都不能匹配的情况下(这常常是实际中的情况),我们会发现匹配的过程经常用不到整个元素,因为元素的一部分就可以判断不匹配了。基 于“部分信息就能判断不匹配”这个思路,Burton Bloom(Bloom Filter的发明者)提出了一种改进的方法。

改进的哈希存储

在这种改进的方法中,哈希区域和前面一样仍然被组织成格子的列表。但这次并不直接将集合元素存在格子里,而是将每一个元素编码然后将编码存在格子里。假设每个集合元素要占b位,编码后要占c(c < b)位。由于编码位数少于元素位数,不同元素的编码有可能相同,因此在查找元素时可能会出现错误。编码位数取决于你期望的错误率:编码位数越多,错误就越 少,反之则越大;当错误少到一定程度(大约2-b),编码位数就足以存下整个元素,因此就变回了传统的哈希存储。

这种方法对传统的哈希存储进行了改良,允许用户在错误率和存储空间之间作权衡。这里我们已经能够看到Bloom Filter的一点端倪。如果说这种方法已经孕育了“正确率换空间”的思想的话,那么Bloom Filter更是这个思想的大胆实践,它完全摆脱了传统的哈希存储方法,在存储空间使用和减少错误率方面又进了一步。

Bloom Filter

在Bloom Filter中,哈希区域的每一位都被当成是独立的可寻址的单元。在对集合元素进行编码时,同时使用若干个独立的哈希函数,将每一个哈希函数映射的地址都 置为1。这种编码方法可谓是另辟蹊径,摆脱了原来一个格子一个格子的存储方法。在改进的哈希存储中,编码位数是和正确率交换的筹码,而在Bloom Filter中,筹码变成了哈希函数的个数以及整个哈希区域(即位数组)的大小。如果想具体知道合适的哈希函数个数和位数组大小,请参阅第一篇Bloom Filter概念和原理

和前面两种哈希存储方法相比,Bloom Filter最大的优势自然是它的空间效率。另外,由于Bloom Filter不用处理碰撞(Collision),因此它在增加或查找集合元素时所用的时间完全恒定(哈希函数的计算时间),无论集合元素本身有多大,也 无论多少集合元素已经加入到了位数组中。由于Bloom Filter和改进的哈希存储都对集合元素进行了编码,因此想要从哈希区域中恢复集合元素并不容易。但同时,如果你不想让别人直接看到集合元素,这样的编 码处理倒可以看成是一种加密,有效保护了你的隐私。

Bloom Filter很大的一个缺点就是不能删除元素。由于Bloom Filter不处理碰撞,有可能多个哈希函数都映射到了同一位,因此不能简单地在删除时将1置为0。后面我们会看到,Counting Bloom Filter通过将每一位扩展为一个Counter来解决这一问题。

2. larbin2.3中的url去重算法

larbin的url去重算法在hashTable.cc文件中实现。其中hashTable::testSet用以测试url是否已被爬取过;并在table的相应位置上置0或1.

bool hashTable::testSet (url *U) {
unsigned int code = U->hashCode();
unsigned int pos = code / 8;
unsigned int bits = 1 << (code % 8);
int res = table[pos] & bits;
table[pos] |= bits;
return !res;
}

使用hashTable类中的私有成员char *table变量来记录url是否被访问过。在hashTable类的构造函数中,table = new char[total]。char为1个字节,占8位,pos表示code处于哪个字节上,pos表示code处于这个字节上的哪些位。如果url被访问过,则res 为真,testSet的返回值即为false;如果url未被访问过,则table[pos]字节上对应的bits的位的值应为0,所以res为假,testSet返回值为true。在结束后,在table中再将这个没有被访问过的url标记为已访问。这样,当url越来越多时,误判为已访问的概率也会越来越大。

这个是bloom filter算法么?

【转】larbin中的url去重算法的更多相关文章

  1. [爬虫学习笔记]基于Bloom Filter的url去重模块UrlSeen

            Url Seen用来做url去重.对于一个大的爬虫系统,它可能已经有百亿或者千亿的url,新来一个url如何能快速的判断url是否已经出现过非常关键.因为大的爬虫系统可能一秒钟就会下载 ...

  2. [原创]手把手教你写网络爬虫(7):URL去重

    手把手教你写网络爬虫(7) 作者:拓海 摘要:从零开始写爬虫,初学者的速成指南! 封面: 本期我们来聊聊URL去重那些事儿.以前我们曾使用Python的字典来保存抓取过的URL,目的是将重复抓取的UR ...

  3. 爬虫URL去重

    这个要看你想抓取的网页数量是哪种规模的.如果是千万以下用hash表, set, 布隆过滤器基本可以解决,如果是海量的......嗯我也没做过海量的,不过hash表之类的就别想了,内存根本不够,分割线下 ...

  4. 大数据排序算法:外部排序,bitmap算法;大数据去重算法:hash算法,bitmap算法

    外部排序算法相关:主要用到归并排序,堆排序,桶排序,重点是先分成不同的块,然后从每个块中找到最小值写入磁盘,分析过程可以看看http://blog.csdn.net/jeason29/article/ ...

  5. URL去重与文章去重的一些基本方法

    一.url去重url存到数据库所有url放到set中(一亿条占用9G内存)md5之后放到set中(一亿条占用2,3G的内存)scrapy采用的就是类似方法bitmap方法(url经过hash后映射到b ...

  6. URL 去重的 6 种方案!(附详细实现代码)

    URL 去重在我们日常工作中和面试中很常遇到,比如这些: 可以看出,包括阿里,网易云.优酷.作业帮等知名互联网公司都出现过类似的面试题,而且和 URL 去重比较类似的,如 IP 黑/白名单判断等也经常 ...

  7. CodeIgniter框架中关于URL(index.php)的那些事

    最近,在做自己的个人网站时,采用了轻量级的php框架CodeIgniter.乍一看上去,代码清晰简洁,MVC模型非常容易维护.开发时我采用的工具是Netbeans IDE 8.0,当然,本文的内容和开 ...

  8. javascript数组去重算法-----3

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. javascript中数组的常用算法深入分析

    Array数组是Javascript构成的一个重要的部分,它可以用来存储字符串.对象.函数.Number,它是非常强大的.因此深入了解Array是前端必修的功课.本文将给大家详细介绍了javascri ...

随机推荐

  1. memcachedd基础

    系列文章导航: memcached完全剖析–1. memcached的基础 memcached全面剖析–2. 理解memcached的内存存储 memcached全面剖析–3. memcached的删 ...

  2. svn强制提交备注信息

    当我们用tortoisesvn,提交代码时,有很多人不喜欢写注释的,代码版本多了,根本搞不清,哪个版本改了什么东西?所以如果加一些注释的话,我们看起来,也方便很多.所以在提交的时候,我会强制要求,写注 ...

  3. Android 调用系统的邮箱app发送邮件

    第一种: String[] email = { "3802**92@qq.com" }; // 需要注意,email必须以数组形式传入 Intent intent = new In ...

  4. hdu 2544最短路——最短路的初次总结 UESTC 6th Programming Contest Online

    这是一道标准的模板题,所以拿来作为这一段时间学习最短路的总结题目. 题意很简单: 有多组输入数据,每组的第一行为两个整数n, m.表示共有n个节点,m条边. 接下来有m行,每行三个整数a, b, c. ...

  5. logback.xml配置

    一:根节点<configuration>包含的属性: scan: 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true. scanPeriod: 设置监测配置文 ...

  6. 【剑指offer 面试题22】栈的压入、弹出序列

    思路: 不停地压栈,直到栈头元素与弹出序列的首元素相等则出栈,同时弹出序列后移:若不相等则一直保持压栈,直到压入所有元素后弹出序列仍不为空,则说明无法匹配. C++: #include <ios ...

  7. Selenium2Library系列 keywords 之 _SelectElementKeywords 之 list_should_have_no_selections(self, locator)

    def list_should_have_no_selections(self, locator): """Verifies select list identified ...

  8. 新版本ubuntu13.10软件安装

    问题1:如何解决ubunt13.04不能和主机共享文件的问题 . 安装VMware Tools 网上有很多的资料,这里没有给出. . 设置共享文件夹目录 ) 在VMware虚拟机窗口,选择VM-> ...

  9. linux-制作linux启动U盘

    1. 使用的制作工具 Ø 下载需要制作启动盘的linux的iso文件 Ø 制作启动盘的软件linux usb creater Ø U盘(大小差不多需要4G的空间) 软件可以的下载的地址:http:// ...

  10. Hadoop 2.2 YARN分布式集群搭建配置流程

    搭建环境准备:JDK1.6,SSH免密码通信 系统:CentOS 6.3 集群配置:NameNode和ResourceManager在一台服务器上,三个数据节点 搭建用户:YARN Hadoop2.2 ...