package bloom;

/**
* 项目名:SpiderCrawler
* 文件名:BloomFilterTest.java
* 作者:zhouyh
* 时间:2014-8-29 下午02:54:56
* 描述:TODO(用一句话描述该文件做什么)
*/
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.BitSet;
import java.util.Scanner; /**
* 描述: 布隆过滤器,传统的布隆过滤器不支持从集合中删除成员
*/
public class BloomFilterTest {
//DEFAULT_SIZE为2的29次方,即此处的左移28位
private static final int DEFAULT_SIZE = 2<<28;
/*
* 不同哈希函数的种子,一般取质数
* seeds数组共有8个值,则代表采用8种不同的哈希函数
*/
private int[] seeds = new int[]{3, 5, 7, 11, 13, 31, 37, 61};
/*
* 初始化一个给定大小的位集
* BitSet实际是由“二进制位”构成的一个Vector。
* 假如希望高效率地保存大量“开-关”信息,就应使用BitSet.
*/
private BitSet bitSets = new BitSet(DEFAULT_SIZE);
//构建hash函数对象
private SimpleHash[] hashFuns = new SimpleHash[seeds.length];
//布隆过滤器配置文件存放路径
private String path = ""; public BloomFilterTest(String path){
/**
* 给出所有的hash值,共计seeds.length个hash值。共8位。
* 通过调用SimpleHash.hash(),可以得到根据8种hash函数计算得出hash值。
* 传入DEFAULT_SIZE(最终字符串的长度),seeds[i](一个指定的质数)即可得到需要的那个hash值的位置。
*/
for(int i=0; i<seeds.length; i++){
hashFuns[i] = new SimpleHash(DEFAULT_SIZE, seeds[i]);
}
//配置文件路径地址
this.path = path;
}
/**
* 描述:将给定的字符串标记到bitSets中,即设置字符串的8个函数值的位置为1
*/
public synchronized void add(String value){
for(SimpleHash hashFun : hashFuns){
bitSets.set(hashFun.hash(value), true);
}
}
/**
* 描述:判断给定的字符串是否已经存在在bloofilter中,如果存在返回true,不存在返回false
*/
public synchronized boolean isExit(String value){
//判断传入的值是否为null
if(null == value){
return false;
} for(SimpleHash hashFun : hashFuns){
if(!bitSets.get(hashFun.hash(value))){
//如果判断8个hash函数值中有一个位置不存在即可判断为不存在Bloofilter中
return false;
}
} return true;
} /**
* 描述:读取配置文件
*/
public void init(){
File file = new File(path);
FileInputStream in = null;
try {
in = new FileInputStream(file);
long lt = System.currentTimeMillis();
read(in);
System.out.println(System.currentTimeMillis()-lt);
System.out.println(Runtime.getRuntime().totalMemory());
}catch(Exception e){
e.printStackTrace();
}finally{
try {
if(in!=null){
in.close();
in = null;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} /**
* 描述:根据传入的流,初始化bloomfilter
*/
private void read(InputStream in){
if(null == in){ //如果in为null,则返回
return;
} int i = 0;
InputStreamReader reader = null; try {
//创建输入流
reader = new InputStreamReader(in, "UTF-8");
BufferedReader buffReader = new BufferedReader(reader, 512);
String theWord = null;
do {
i++;
theWord = buffReader.readLine();
//如果theWord不为null和空,则加入Bloomfilter中
if(theWord!=null && !theWord.trim().equals("")){
add(theWord.split(" ")[1]);
// System.out.println(theWord.split(" ")[1]);
}
if(i%10000 == 0){
// System.out.println(i);
// System.out.println(theWord.split(" ")[1]);
}
if(i%1000000 == 0){
System.out.println(i);
break;
} } while (theWord != null); } catch (IOException e){
e.printStackTrace();
} finally{
//关闭流
try {
if(reader != null){
reader.close();
reader = null;
}
if(in != null){
in.close();
in = null;
}
} catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
} }
} /**
* 描述:TODO(这里用一句话描述这个方法的作用)
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
BloomFilterTest bloomFilterTest = new BloomFilterTest("D:\\学习\\实验室项目\\ImageNet图片爬取\\fall11_urls.txt");
bloomFilterTest.init(); Scanner sc = new Scanner(System.in); while(true){
System.out.println("输入网址:");
String s = sc.nextLine();
System.out.println(bloomFilterTest.isExit(s));
}
// test();
// System.out.println(Integer.toBinaryString(DEFAULT_SIZE-1));
}
public static void test(){
int tt1 = 2<<28;
int tt2 = 2<<29;
int tt3 = 2<<30;
int tt4 = 2<<1;
System.out.println(Integer.toBinaryString(tt1)+" "+Integer.toBinaryString(tt1).length());
System.out.println(Integer.toBinaryString(tt2)+" "+Integer.toBinaryString(tt2).length());
System.out.println(Integer.toBinaryString(tt3-1)+" "+Integer.toBinaryString(tt3).length());
System.out.println(Integer.toBinaryString(tt4)+" "+Integer.toBinaryString(tt4).length());
BitSet b = new BitSet(tt3);
}
public static class SimpleHash {
/*
* cap为DEFAULT_SIZE,即用于结果的最大字符串的值
* seed为计算hash值的一个key值,具体对应上文中的seeds数组
*/
private int cap;
private int seed;
/**
* 构造函数
*/
public SimpleHash(int cap, int seed){
this.cap = cap;
this.seed = seed;
}
/**
* 描述:计算hash的函数,用户可以选择其他更好的hash函数
*/
public int hash(String value){
int result = 0;
int length = value.length();
for(int i=0; i<length; i++){
result = seed*result + value.charAt(i);
}
//011..11共32位,故&运算以后可以取后31位
return (cap-1) & result;
}
} }

此处应该注意Bitset最多只有32位

根据别人的数据适当选择大小

使用bloomfilter的更多相关文章

  1. BloomFilter 与 Cuckoo Filter

    BloomFilter 与 CuckooFilter Bloom Filter 原理 Bloom Filter是一种空间效率很高的随机数据结构,它的原理是,当一个元素被加入集合时,通过K个相互独立的H ...

  2. Hbase中的BloomFilter(布隆过滤器)

    (1)     Bloomfilter在hbase中的作用 Hbase利用bloomfilter来提高随机读(get)的性能,对于顺序读(scan)而言,设置Bloomfilter是没有作用的(0.9 ...

  3. [转]BloomFilter——大规模数据处理利器

    Bloom Filter是由Bloom在1970年提出的一种多哈希函数映射的快速查找算法.通常应用在一些需要快速判断某个元素是否属于集合,但是并不严格要求100%正确的场合. 一. 实例 为了说明Bl ...

  4. 基于Redis的BloomFilter算法去重

    BloomFilter算法及其适用场景 BloomFilter是利用类似位图或者位集合数据结构来存储数据,利用位数组来简洁的表示一个集合,并且能够快速的判断一个元素是不是已经存在于这个集合.因为基于H ...

  5. BloomFilter–大规模数据处理利器(转)

    BloomFilter–大规模数据处理利器 Bloom Filter是由Bloom在1970年提出的一种多哈希函数映射的快速查找算法.通常应用在一些需要快速判断某个元素是否属于集合,但是并不严格要求1 ...

  6. BloomFilter——读数学之美札记

    之前接触过bitmap,读吴军先生的数学之美,看到了一个更强大的数据结构,布隆过滤器(Bloomfilter),赶紧记下来吧,忘了怪可惜的. bitmap的使用是很有局限性的,往往只能用于海量数值型数 ...

  7. BloomFilter算法

    Bloom filter 是由 Howard Bloom 在 1970 年提出的二进制向量数据结构,它具有很好的空间和时间效率,被用来检测一个元素是不是集合中的一个成员.如果检测结果为是,该元素不一定 ...

  8. 关于在Python下安装布隆过滤器(bloomfilter)的方法

    由于在爬虫代码中需要实现信息的去重功能,所以需借助bloomfilter,在看完各种博客后发现没有安装,这就尴尬了,不会连门都找不到吧.那就安装呗,各种错误,查看官方文档:http://axiak.g ...

  9. 布隆过滤器(BloomFilter)持久化

    摘要 Bloomfilter运行在一台机器的内存上,不方便持久化(机器down掉就什么都没啦),也不方便分布式程序的统一去重.我们可以将数据进行持久化,这样就克服了down机的问题,常见的持久化方法包 ...

  10. BloomFilter(布隆过滤器)

    原文链接:http://blog.csdn.net/qq_38646470/article/details/79431659 1.概念: 如果想判断一个元素是不是在一个集合里,一般想到的是将所有元素保 ...

随机推荐

  1. jquery ready load

    jq 加载三种写法 $(document).ready(function() { // ...代码... }) //document ready 简写 $(function() { // ...代码. ...

  2. Storm项目开发纪要

    1.POM引用storm-core和javax.servlet-api这两个组件,如果本地模式跑拓扑,要把<scope>provided</scope>去掉:如果远程发布运行, ...

  3. Java构造二叉树、树形结构先序遍历、中序遍历、后序遍历

    package com.example.demo; public class BTree { public int data; public BTree left; public BTree rigt ...

  4. Mac下安装配置NMP环境

    第一次在Mac上安装NMP,记录下 因为下面环境的安装都是基于homebrew的,所以如果没有安装他的话,要先安装他(官网:https://brew.sh/index_zh-cn.html) 安装ho ...

  5. 《Maven 实战》笔记之setting.xml介绍

    maven是什么?有什么用? Maven是一个跨平台的项目管理工具,主要服务于Java平台的项目构建,依赖管理和项目信息管理.项目构建包括创建项目框架.清理.编译.测试.到生成报告,再到打包和部署,项 ...

  6. 【转载】Stanford CoreNLP Typed Dependencies

    总结自Stanford typed dependencies manual 原文链接:http://www.jianshu.com/p/5c461cf096c4 依存关系描述句子中词与词之间的各种语法 ...

  7. Summer training round2 #3

    A!:                    GTY系列题 B!:莫队加分块  GTY系列题 C!:线段树模拟拓扑排序(把普通的拓扑排序的栈操作改成线段树区间减一,查询区间最右侧的0的位置即可.注意一 ...

  8. 树形DP Choosing Capital for Treeland

    给你一棵有向树,需要选定一个点为capital,满足翻转边数最小 思路:先求出1为capital 的答案,然后向下更新孩子节点 dp[i]=dp[i-1]+judge(i); #include< ...

  9. echarts-all.js:1 Uncaught TypeError: Cannot read property 'getAttribute' of null

    转载:https://blog.csdn.net/you23hai45/article/details/51595108 由于echarts图形ID是由后台传输过来的,并且是根据图形数据一起传过来,出 ...

  10. Android Studio 创建项目后“Cannot resolve symbol” 解决办法

    报错位置显示 “Cannot resolve symbol XXX”, 解决方法如下: 点击菜单中的 “File” -> “Invalidate Caches / Restart”,然后点击对话 ...