引入知識:hash table想要學習一下fast hash table,沒有找到中文資料,只能生啃**了。hash table原理
引入知識:布隆過濾器
bloom filters
布隆過濾器**
本篇部落格主要是翻譯fast hash table的一篇優秀**:song h, dharmapurikar s, turner j, et al. fast hash table lookup using extended bloom filter: an aid to network processing[j]. acm sigcomm computer communication review, 2005, 35(4): 181-192.
雜湊表是一種通用資料結構,用於執行快速關聯查詢,這需要每次查詢o(1)次平均記憶體訪問。 實際上,由於其在網路資料報處理中的廣泛適用性,一些現代網路處理器提供了內建的雜湊單元。 乙份有關網路資料報處理的最新研究文獻的調查顯示,雜湊表對於許多應用程式都是通用的,包括按流狀態管理,ip查詢和資料報分類。 這些應用程式通常出現在高速路由器的資料路徑中。 因此,它們必須能夠以線速處理資料報,這使得基礎雜湊表必須提供良好的查詢效能。
為了清楚起見,我們從樸素的雜湊表(nht)開始逐步開發演算法和雜湊表體系結構。
我們採用雜湊表演算法中的鏈位址法解決衝突,因為它比開放式定址方案具有更好的效能,並且是最流行的方法之一。
現在,我們介紹我們的快速雜湊表(fht)演算法。
首先介紹快速雜湊表的基本形式,我們稱其為基本快速雜湊表(bfht),然後對其進行改進。快速雜湊表基於布隆過濾器的一種變種,稱為計數布隆過濾器,其中過濾器的每一位都被乙個計數器代替。在插入專案後,由相應雜湊值索引的每個計數器都會增加。由於其結構,此過濾器中的計數器實質上為我們提供了其中雜湊的專案數。我們將在表中顯示如何有效地使用此資訊以最小化搜尋時間。
我們維護乙個由m個計數器組成的陣列c,其中每個計數器ci與雜湊表的儲存區(桶)i相關聯。我們在輸入項上計算雜湊函式h1(),h2()…,hk()並遞增由這些雜湊值索引的相應k個計數器。然後,我們將該專案儲存在與每個儲存桶相關的列表中。
因此,單個專案被多次儲存在片外儲存器中。下面是插入乙個專案的演算法描述。
請注意,如果有多個雜湊函式對映到同一位址,則我們只會將計數器遞增一次,並且只會在該儲存桶中儲存一項的副本。 為了檢查雜湊值是否衝突,我們將先前為該專案計算的所有雜湊值保留在暫存器中,並將新雜湊值與所有雜湊值進行比較(上述插入演算法第2行)。
如下圖所示,四個不同的專案x,y,z和w已依次插入。 每個專案都複製到k = 3個不同的儲存桶中,並且與該儲存桶關聯的計數器值反映了其中的專案數。
其次,要檢查列表的選擇至關重要,因為列表遍歷時間取決於列表長度。因此,我們選擇與計數器關聯的具有最小值的列表,以減少片外儲存器訪問。我們演算法的加速來自以下事實:它可以選擇最小的列表進行搜尋,因為nht只能跟蹤可能包含多個專案的乙個列表。
在大多數情況下,對於經過仔細選擇的儲存桶數,最小值計數器的值為1,僅需要單個儲存器即可訪問片外儲存器。在圖2所示的示例中,如果查詢專案y,則僅需要訪問列表x11,而不是長度比x11長的x3或x6。
當由輸入專案索引的多個計數器具有相同的最小值時,則必須以某種方式打破平局。我們通過簡單地選擇索引最小的最小值計數器來打破這種關係。例如,在圖2中,專案x的兩個儲存桶計數器設定為2,這也是最小值。在這種情況下,我們總是訪問儲存桶x1。
以下偽**總結了bfht上的搜尋演算法。
最後,如果輸入的專案不存在於專案列表中,則很明顯這是計數布隆過濾器指示的誤報匹配。
使用上面的資料結構,刪除專案很容易。 我們只需遞減與該專案關聯的計數器,然後從相應列表中刪除所有副本。
在bfht中,我們需要維護每個專案的k個副本,這需要比nht多k倍的記憶體。 但是,可以觀察到,在bfht中,探查表時只能訪問每個專案的乙個副本(與最小計數器值關聯的副本)。 永遠不會訪問該項目的其餘(k-1)個副本。 此觀察結果為我們提供了進行記憶體優化的第乙個機會:現在可以刪除該項目的所有其他副本,但在搜尋過程中訪問的副本除外。
因此,在此修剪過程之後,我們只有乙個副本,該副本將記憶體需求減少到與nht相同。我們將生成的雜湊表稱為修剪的快速雜湊表(pfht)。
以下偽**總結了修剪演算法。
修剪過程如圖3(a)所示。要注意,在修剪過程中,計數器值不會更改。因此,修剪完成後,計數器值不再反映列表中實際顯示的項數,通常大於該值。但是,對於給定的專案,計數器值最小的儲存桶始終包含該專案。此屬性可確保搜尋結果的正確性。修剪的另乙個特性是,它與修剪專案的順序無關,因為它僅取決於不會更改的計數器值。因此,按順序在x-y-z-w中進行修剪將產生與在z-y-x-w中進行修剪相同的結果。
修剪過程的侷限性在於,現在很難執行對錶的增量更新。由於計數器值不再反映列表中的專案數,因此如果分別為任何新插入或刪除操作增加或減少計數器,則可能會干擾與儲存桶中現有專案相對應的計數器值,從而導致錯誤的結果搜尋。例如,在圖3(a)中,項y分別對映到具有計數器值的列表。
當我們要刪除專案時,我們首先使用deleteitem bfht演算法(第2-5行)對離線資料結構執行刪除操作。然後,我們將所有受影響的bfht儲存桶(計數器遞減的儲存桶)中的所有專案收集起來以重新插入。同時,我們從pfht中刪除了與每個儲存桶關聯的專案列表,因為現在必須重新插入每個專案(第7-8行)。最後,對於收集到的專案列表中的每個專案,我們都像在insertitem中一樣重新插入(第9-12行)pfht。注意deleteitem的第6-12行與insertitem pfht的第4-10行之間的相似之處。唯一的區別是,在deleteitem pfht中,我們從bfht收集要重新插入的專案並且遞減計數器而不是遞增計數器。
在我們得出deleteitem演算法的複雜度的表示式之前,我們注意到涉及兩種型別的操作:bfht和pfht。由於bfht操作可以在後台執行而不會妨礙pfht的正常操作,因此我們僅得出pfht操作的複雜性。考慮到這一點,我們注意到bfht中每個非空桶的專案數為2nk / m,因為在最佳配置中只有一半的桶是非空的(請參閱第3節)。由於我們從k個桶中收集物品,因此我們總共需要重新調整2nk ^ 2 / m個專案(在第9行的迴圈中)。為了重新調整,我們需要讀取和寫入每個專案。因此,刪除操作的總體複雜度為o(4nk ^ 2 / m)。通過對錶進行最佳配置,它可以簡化為4kln2 = 2.8k。
(未完待續…
學習學習再學習
如果乙個技能足夠複雜 比如從零學程式設計 那就不要指望讀完一本書就可以打天下。多買幾本書同類的書 因為每個作者的出發點是不一樣的,哪怕對同乙個概念都有不同的解釋說明。理解知識的重要過程之一就如牛的反芻一樣,要嚼一遍 嚥下去 再吐出來 再嚼一遍 再嚥下去 所以,既然一本書可以讀幾遍,那麼同一話題多應該...
學習 學習 再學習
原本要使用vs2005開發乙個b s專案的,沒有想到只能先暫時停停了,居然跟不上技術的發展了,呵呵,一直使用delphi delphi也沒能跟上 沒有想到轉到vs2005上竟然有這麼多要學的東西,當然目的是了做乙個好的系統。最近一直在學習asp.net ajax,雖然專案停了,但是我覺得值得,有很多...
只是學習 學習 再學習
通過做 讓我學會了很多東西 什麼 flash div css html js as 雖然都只是皮毛 不過 算是了解那麼一點點吧 哈哈 我還突然發現 我的 數學和英語 進步了不少 而且還都是很實用的 比在學校的進步可快多了 那句話說的很不錯 在你了解了一些皮毛之後你會發現很多東西你都必須去學。因為少一...