以後都在 github 更新,請戳 rax(redis 實現的字首樹)
rax是 redis 自己實現的基數樹, 它是一種基於儲存空間優化的字首樹資料結構, 在 redis 的許多地方都有使用到, 比如streams
這個型別裡面的consumer group
(消費者組) 的名稱還有集群名稱
ok通常來講, 乙個基數樹(字首樹) 看起來如下所示
* 這是最基本的表示方式:
* * (f) ""
* \
* (o) "f"
* \
* (o) "fo"
* \
* [t b] "foo"
* / \
* "foot" (e) (a) "foob"
* / \
* "foote" (r) (r) "fooba"
* / \
* "footer" "foobar"
*
翻譯自redis/src/rax.h
然而, 當前的**實現使用了一種非常常見的優化策略, 把只有單個子的節點連續幾個節點壓縮成乙個節點, 這個節點有乙個字串, 不再是只儲存單個字元, 上述的結構可以優化成如下結構
*
* ["foo"] ""
* |
* [t b] "foo"
* / \
* "foot" ("er") ("ar") "foob"
* / \
* "footer" "foobar"
字串mygroup1
在 rax 中也是以壓縮節點的方式儲存的, 可以用如下表示
*
* ["mygroup1"] ""
* |
* "mygroup1"
第乙個節點儲存了壓縮過的整個字串mygroup1
, 第二個節點是乙個空的葉子節點, 他是乙個 key 值, 表示到這個節點之前合起來的字串儲存在了當前的rax
結構中
下圖是字串mygroup1
當前所在的rax
的實際圖示, 並且 key 節點中的 data 字段儲存了乙個指標, 這個指標指向了和mygroup1
相對應的consumer group
物件
iskey
表示當前的節點是否為 key 節點
isnull
表示當前節點是否有儲存額外的值(比如上面的consumer group
物件)
iscompr
表示當前節點是否為壓縮的節點
size
是子節點數量或者壓縮的字串長度
第乙個節點的iscompr
值為 1, 並且整個字串mygroup1
儲存在了當前這乙個節點中,size
為 8 表示當前節點儲存了 8 個char
字元,iskey
為 0, 表示當前的節點不是 key 節點, 我們需要繼續往下搜尋
第二個節點的iskey
為 1, 表示當前的節點為 key 節點, 它表示在到這個節點之前的所有字串連起來(也就是mygroup1
) 存在當前的字首樹中, 也就是說當前的字首樹有包含mygroup1
這個字串,isnull
為 0 表示在當前這個 key 節點的 data 尾部儲存了乙個指標, 這個指標是函式呼叫者進行儲存的, 在當前的情況它是乙個指向streamcg
的指標, 但是實際上他可以是指向任意物件的指標, 比如集群名稱或者其他物件
我們再來插入乙個consumer group
名稱到當前的字首樹中
從上圖可知, 第乙個節點被裁剪了, 並且它後面插入了乙個新的節點, 左下角的節點是原先存在的節點, 右下角的節點也是乙個新插入的節點
*
* ["mygroup"] ""
* |
* [1 2] "mygroup"
* / \
* "mygroup1" "mygroup2"
中間的節點未被壓縮(iscompr
這個位沒有被設定), data 欄位中儲存了size
個字元, 在這些字元之後, 同樣會儲存size
個指向與之前字元一一對應的raxnode
的結構的指標
底下兩個節點的iskey = 1
並isnull = 0
, 表示當到達任意乙個這樣的節點時, 當前的字串是儲存在這個字首樹中的, 並且在 data 欄位最尾部儲存了乙個輔助的指標, 這個指標具體指向什麼物件取決於呼叫者
如果你對rax
的插入或者刪除演算法感興趣, 請閱讀以下**
redis/src/rax.c
中的raxgenericinsert
和redis/src/rax.c
中的raxremove
基數樹(wikipedia)
rax, an ansi c radix tree implementation
字首樹 java實現)
package class 07 字首樹 例子 乙個字串型別的陣列arr1,另乙個字串型別的陣列arr2。arr2中有哪些字元,是arr1中出現的?請列印 arr2中有哪些字元,是作為arr1中某個字串字首出現的?請列印 arr2中有哪些字元,是作為arr1中某個字串字首出現的?請列印arr2中出現...
字首樹python實現
file name 字首樹.py class trienode object def init self self.path 0 路過此節點幾個 self.end 0 以此為結尾的幾個 self.map none for i in range 26 每乙個節點有26條路 class trie obj...
字首樹 字典樹
trie 樹是乙個有根的樹,其結點具有以下字段 最多 rr 個指向子結點的鏈結,其中每個鏈結對應字母表資料集中的乙個字母。本文中假定 rr 為 26,小寫拉丁字母的數量。布林字段,以指定節點是對應鍵的結尾還是只是鍵字首。trie 發音為 try 或字首樹是一種樹資料結構,用於檢索字串資料集中的鍵。這...