所有例子均出自原始碼。
radix tree壓縮字首樹,是redis在5.0新加入的用來儲存key的資料結構。
字首樹的節點結構如下。
typedef struct raxnode raxnode;
簡單來看乙個radix樹中的節點共分為五部分,前三者分別是三個標誌量,iskey代表從根節點到該節點的父節點是否是乙個key,注意,這裡的iskey代表的是根節點到父節點位置的字串,並不包含iskey所在的節點。isnull代表當前key所包含的value是否為null。iscompr代表當前節點是否是壓縮節點。
在字首樹中,分為壓縮節點和非壓縮節點。
在一棵具體的樹中,具體是這樣構成的。
* ["foo"] ""
* |
* [t b] "foo"
* / \
* "foot" ("er") ("ar") "foob"
* / \
* "footer" "foobar"
其中,樹中的節點結構會有以下兩種情況。
* [header iscompr=0][abc][a-ptr][b-ptr][c-ptr](value-ptr?)
* [header iscompr=1][xyz][z-ptr](value-ptr?)
在上面的結構中第乙個便是非壓縮節點,第二個則是壓縮節點。
在這顆樹里,第二層便是非壓縮節點,其他都是壓縮節點,具體的非壓縮節點出現在字首相同但是下乙個字元出現分歧的地方。而壓縮節點是一段正常的字串,但如果這是乙個key,將會在子節點的iskey子段中表示出來。
size在壓縮節點中表示該節點的字串長度,壓縮節點的大小必定大於等於2,在非壓縮節點中表示在父節點的字首下分歧的數量。
data則是具體的字元資訊。
在radix樹的插入中,原始碼中的注釋給出了各種情況的解釋。
* "annibale" -> "sco" ->
以上是當前樹的初始情況,共存在兩個key,乙個是annibale,和annibalesco。
當插入annientare時,在乙個節點的anni後邊發生了分歧,此時保留前四個字元作為共有的字首父節點,並生成乙個非壓縮子節點表示字首的分歧,如下。
* |b| -> "ale" -> "sco" ->
* "anni" -> |-|
* |e| -> (... continue algo ...) "ntare" ->
當插入ago的時候分歧在第乙個字元後便產生,總體情況似乎後第一種情況相似,但由於該場景的分歧發生在第二字元,由此,在生成非壓縮子節點的同時,其根節點也變成了非壓縮節點。
* |n| -> "nibale" -> "sco" ->
* |a| -> |-|
* |g| -> (... continue algo ...) |o| ->
當插入ciao的時候,相對於上一中情況,從第乙個字元便發生了分歧,根節點直接變成多成員的非壓縮節點。
* |a| -> "nnibale" -> "sco" ->
* |-|
* |c| -> (... continue algo ...) "iao" ->
當插入anni的時候,由於其字元完全匹配當前已經存在的字首節點,只需要在當前的壓縮節點中進行拆分出其存在即可。
* "anni" -> "bale" -> "sco" ->
以上是radix樹插入時各種可能會出現的情況。
當刪除時,原始碼也給出了各種情況的解釋。
* "foo" -> "bar" -> (2)
* (1)
以上是當前樹的情況,存在兩個鍵值對,foo->1,foobar->2。
當需要刪除foo這個key的時候,其實只需要把父節點和子節點合併即可,保留子節點的value。
* "foobar" -> (2)
還有一種情況如下。
* |b| -> "ar" -> (1)
* "foo" -> |-|
* |t| -> "er" -> (2)
以上存在兩個key,foobar->1,footer->2。
當刪除footer這個key的時候,結果如下。
* "foo" -> |b| -> "ar" -> (1)
此時可以考慮進行壓縮,壓縮結果如下。
* "foobar" -> (1)
Redis radix tree原始碼解析
redis實現了不定長壓縮字首的radix tree,用在集群模式下儲存slot對應的的所有key資訊。本文將詳述在redis中如何實現radix tree。raxnode是radix tree的核心資料結構,其結構體如下 所示 typedef struct raxnode raxnode isnu...
container of 的的的原理
另外一篇,同樣精彩,揭開linux核心中container of的神秘面紗 華清遠見嵌入式學院講師。在linux 核心中有乙個大名鼎鼎的巨集container of 這個巨集是用來幹嘛的呢?我們先來看看它在核心中是怎樣定義的。呵呵,乍一看不知道是什麼東東。我們先來分析一下container of p...
存在的就是合理的,發生的即是必然的。
筆者有時候會想,什麼是對,什麼是錯?對於追求某一件事情之前首先會考慮,為什麼我要做這件事情。所以經過自我分析和生活周邊環境的總結。我認為,對於乙個人來,這是在站在個體的角度上說。什麼是對的?就是你自己覺得是對的,它就是對的。不過這個只是你自己的想法。主觀上的正確,不代表客觀上也受到了別人的認可。就拿...