喝酒I創做I分享算法
生活中總有些東西值得分享數據結構
兩週以前——ide
爬蟲的原理就不細說了,無非是經過種子URL來順藤摸瓜,爬取出網站關聯的全部的子網頁,存入本身的網頁庫當中。網站
可是,這其中涉及到一個小小的問題......spa
URL去重方案初版:HashSet3d
建立一個HashSet集合,把每個URL字符串做爲HashSet的key插入到集合當中,利用HashSet的Key惟一性來對URL作去重。code
這個方案看似沒毛病,可是通過幾輪壓測以後......
orm
每個URL按照20字節來算,一億個URL就是20億字節,也就是大約佔了1.8G以上的空間。這麼大的HashSet集合顯然是不可取的。blog
因而小灰又思考了一番......內存
URL去重方案第二版:Bitmap
Bitmap是一種節省空間的數據結構,不太瞭解的朋友能夠看看往期的相關文章:
具體怎麼作呢?獲取每個URL的HashCode,根據HashCode的值來插入到Bitmap的對應位置。若是要插入位置的值已是1,說明該URL已重複。
使用Bitmap之後,每個Url只佔了1個Bit,一億個Url佔約12MB。假設整個Bitmap的空隙比較多,額外空間佔90%,總空間也不過是120MB,相比HashSet來講大大節省了內存空間。
這個方案貌似好了不少,但是......
String的Hashcode方法雖然儘量作到均勻分佈,但仍然免不了會有衝突的狀況。HashCode的衝突意味着什麼呢?意味着兩個本來並不相同的Url被誤判爲重複Url。
———————————————
聽起來有點繞,咱們來詳細描述一下:
1.把第一個URL按照三種Hash算法,分別生成三個不一樣的Hash值。
2.把第二個URL也按照三種Hash算法,分別生成三個不一樣的Hash值。
3.依次比較每個Hash結果,只有當所有結果都相等時,才斷定兩個URL相同。
具體怎樣映射呢?流程以下:
1.建立一個空的Bitmap集合。
2.把第一個URL按照三種Hash算法,分別生成三個不一樣的Hash值。
3.分別判斷5,17, 9 在Bitmap的對應位置是否爲1,只要不一樣時爲1,就認爲該Url沒有重複,因而把5,17,9的對應位置設置爲1。
4.把第二個URL按照三種Hash算法,分別生成三個不一樣的Hash值。
5.分別判斷10,12, 9 在Bitmap的對應位置是否爲1,只要不一樣時爲1,就認爲該Url沒有重複,因而把10,12, 9 的對應位置設置爲1。
6.把第三個URL按照三種Hash算法,分別生成三個不一樣的Hash值。
7.分別判斷4,16, 11 在Bitmap的對應位置是否爲1,只要不一樣時爲1,就認爲該Url沒有重複,因而把4,16, 11 的對應位置設置爲1。
8.把第四個URL按照三種Hash算法,分別生成三個不一樣的Hash值。
9.分別判斷5,17, 9 在Bitmap的對應位置是否爲1。判斷的結果是 5,17, 9 在Bitmap對應位置的值都是1,因此斷定該Url是一個重複的Url。
1.URL按照三個Hash算法獲得三個結果。
2.分別判斷10,12, 17 在Bitmap的對應位置是否爲1。判斷的結果是 10,12, 17 在Bitmap對應位置的值都是1,因此斷定該Url是一個重複的Url。