redis radix tree的簡單解釋

2021-09-28 14:37:40 字數 2380 閱讀 1528

所有例子均出自原始碼。

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...

存在的就是合理的,發生的即是必然的。

筆者有時候會想,什麼是對,什麼是錯?對於追求某一件事情之前首先會考慮,為什麼我要做這件事情。所以經過自我分析和生活周邊環境的總結。我認為,對於乙個人來,這是在站在個體的角度上說。什麼是對的?就是你自己覺得是對的,它就是對的。不過這個只是你自己的想法。主觀上的正確,不代表客觀上也受到了別人的認可。就拿...