基於redis(key分段,避免一個key過大) 和db實現的 布隆過濾器(解決hash碰撞問題)

如下是簡易的代碼例子:java

package six.com.crawler.work.space;redis

import java.util.Objects;數據庫

import redis.clients.jedis.Jedis;分佈式

public class RedisAndDbBloomFilter {ui

    private String nameSpace;
    private Jedis jedis;
    private int fixSize;
    
    public RedisAndDbBloomFilter(String nameSpace,Jedis jedis,int fixSize){
        this.nameSpace=nameSpace;
        this.jedis=jedis;
        this.fixSize=fixSize;
    }
    
    private int getHash(String key){
        return key.hashCode();
    }
    
    private void addToDb(int hash,String key){
        //TODO 將記錄保存至db
    }
    
    private boolean containsFromDb(int hash,String key){
        //TODO 根據 hash key 查詢數據庫是否存在
        return false;
    }
    
    /**
     * 根據hash和fixSize 算出bitKey
     * @param hash
     * @return
     */
    private String getBitKey(int hash){
        int bitKeyIndex=hash/fixSize;
        String bitKey=nameSpace+bitKeyIndex;
        return bitKey;
    }
    /**
     * 判斷給定的key是否存在
     * @param key
     * @return
     */
    public boolean contains(String key){
        //TODO 若是是集羣模式這裏須要分佈式鎖,若是是單機這裏須要線程鎖
        Objects.requireNonNull(key, "the key must not be null");
        int hash=getHash(key);
        int offset=hash%fixSize;
        String bitKey=getBitKey(hash);
        Boolean result=jedis.getbit(bitKey,offset);
        if(result.booleanValue()&&containsFromDb(hash, key)){
            return true;
        }
        return false;
    }
    
    /**
     * 根據給定的key添加一個過濾記錄
     * @param key
     */
    public void addRecord(String key){
        //TODO 若是是集羣模式這裏須要分佈式鎖,若是是單機這裏須要線程鎖
        int hash=getHash(key);
        int offset=hash%fixSize;
        String bitKey=getBitKey(hash);
        jedis.setbit(bitKey,offset, true);
        addToDb(hash, key);
    }    
}
 this

相關文章
相關標籤/搜索