1. 程式人生 > 其它 >Z-Blog編輯器支援ppt自動匯入

Z-Blog編輯器支援ppt自動匯入

瞭解

  1. 1970年,由Bloom 提出的
  2. 二進向量(位陣列)隨機對映函式組成對映關係
  3. BitSet 作為位容器(位陣列),位值為 0 或者 1
  4. 隨機對映函式(HashFunction),目的生成一個對應的數值,然後存入到 BitSet中。
  5. 優點:
    1. 陣列容器佔用空間小。儲存100W個數據,佔 122 KB(100W*1bit/8/1024)
    2. 如果儲存過資料,容器必定有痕跡
  6. 缺點:
    1. 容器有痕跡的,不一定儲存過資料
    2. 容器中只能新增資料,不能刪除資料。刪除元素導致位值的變化,會提高容器的錯誤率
    3. 資料量越大,錯誤率會越高。所以一般 位容器的初始位數會很大

注 : 1 M = 1024 KB = 1024 * 1024 B(byte) = 1024 * 1024 * 8 bit

原理

新增物件

被新增的物件,通過 HashFunction 會生產一個或多個對應的數值,並存儲到 BitSet 容器中。BitSet 中位值會由 0->1 ,多個物件儲存時,位值也只會儲存到 1。

判斷物件

判斷的過程中,實際是看物件通過 HashFunction 所生產的一個或多個對應的數值,在 BitSet 中的位值是否都為1
圖中,物件4 對應的所有位值裡面,存在一個值為 0,則 物件4 一定沒儲存過。

實現

/**
 * 布隆過濾器
 * 
 * @author ZZ_C
 *
 */
public class TestBloomFilter {

	/**
	 * 一個長度為10億的位
	 */
	private static int DEFAULT_SIZE = 256 << 22;

	/**
	 * 為了降低錯誤率,使用hash演算法,定義8個不同的質數
	 */
	private static final int[] seeds = { 3, 5, 7, 11, 13, 17, 19, 23 };

	/**
	 * 定義seeds.length 個 hash 函式用於雜湊計算
	 */
	private static HashFunction[] functions = new HashFunction[seeds.length];

	/**
	 * 布隆過濾器的核心容器,初始化,定義了 10 億個位
	 */
	private static BitSet bitSet = new BitSet(DEFAULT_SIZE);

	TestBloomFilter() {

		for (int i = 0; i < seeds.length; i++) {
			functions[i] = new HashFunction(DEFAULT_SIZE, seeds[i]);
		}
	}

	public void add(String value) {

		for (HashFunction function : functions) {

			bitSet.set(function.toHash(value));
		}
	}

	public boolean contains(String value) {

		for (HashFunction function : functions) {
			// 只要有一個不存在,則 value 一定不存在
			boolean result = bitSet.get(function.toHash(value));
			if (Objects.equals(result, false)) {
				return false;
			}
		}

		return true;
	}

	public static void main(String[] args) {

		TestBloomFilter bloomFilter = new TestBloomFilter();
		bloomFilter.add("斗羅大陸");
		bloomFilter.add("辰東");
		System.out.println(bloomFilter.contains("我愛吃西紅柿"));   // false
		System.out.println(bloomFilter.contains("辰東"));  // true
	}

	/**
	 * 作用就是算 hash值
	 * 靜態類,便於處理
	 * @author ZZ_C
	 *
	 */
	static class HashFunction {

		private int size;

		private int seed;

		public HashFunction(int size, int seed) {
			super();
			this.size = size;
			this.seed = seed;
		}

		public int toHash(String value) {
			int h;
			return (value == null) ? 0 : Math.abs(seed * (size - 1) & ((h = value.hashCode()) ^ (h >>> 16)));

		}

	}
}

應用場景

擊穿

使用布隆過濾器,將全部的有效資料都走一遍佈隆過濾器,這樣新來請求時,先走一遍請求的元素是否能通過布隆過濾器的驗證,若未通過就直接放棄請求,若通過再執行查詢

去重

使用者瀏覽記錄存入資料庫時,會在Filter上通過key的hash演算法儲存判斷其是否存在,類似於資料存在資料庫中,判斷該資料是否存在的資訊即元資料存放在BloomFilter中,避免了每次判斷資料是否存在都要去資料庫exist一遍;這樣推送新聞時通過布隆過濾器判斷,推送內容是否已經存在,如果存在則不推送,如果不存在則推送;