重慶分公司,新征程啟航
為企業(yè)提供網站建設、域名注冊、服務器等服務
為企業(yè)提供網站建設、域名注冊、服務器等服務
這篇文章將為大家詳細講解有關怎么進行redis radix tree源碼解析,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
成都創(chuàng)新互聯公司是一家集網站建設,葫蘆島企業(yè)網站建設,葫蘆島品牌網站建設,網站定制,葫蘆島網站建設報價,網絡營銷,網絡優(yōu)化,葫蘆島網站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強企業(yè)競爭力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯網需求。同時我們時刻保持專業(yè)、時尚、前沿,時刻以成就客戶成長自我,堅持不斷學習、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實用型網站。
Redis實現了不定長壓縮前綴的radix tree,用在集群模式下存儲slot對應的的所有key信息。本文將詳述在Redis中如何實現radix tree。
raxNode是radix tree的核心數據結構,其結構體如下代碼所示:
typedef struct raxNode { uint32_t iskey:1; uint32_t isnull:1; uint32_t iscompr:1; uint32_t size:29; unsigned char data[]; } raxNode;
iskey:表示這個節(jié)點是否包含key
0:沒有key
1:表示從頭部到其父節(jié)點的路徑完整的存儲了key,查找的時候按子節(jié)點iskey=1來判斷key是否存在
isnull:是否有存儲value值,比如存儲元數據就只有key,沒有value值。value值也是存儲在data中
iscompr:是否有前綴壓縮,決定了data存儲的數據結構
size:該節(jié)點存儲的字符個數
data:存儲子節(jié)點的信息
iscompr=1:壓縮模式下,數據格式是:[header strlen=3][xyz][z-ptr](value-ptr?)
,只有一個指針,指向下一個節(jié)點。size個字符是壓縮字符片段
iscompr=0:非壓縮模式下,數據格式是:[header strlen=0][abc][a-ptr][b-ptr][c-ptr](value-ptr?)
,有size個字符,緊跟著是size個指針,指向每個字符對應的下一個節(jié)點。size個字符之間互相沒有路徑聯系。
以下用幾個示例來詳解rax tree插入的流程。假設j是遍歷已有節(jié)點的游標,i是遍歷新增節(jié)點的游標。
z-ptr指向的葉子節(jié)點iskey=1,使用了壓縮前綴。
從abcd父節(jié)點的每個壓縮前綴字符比較,遍歷完所有abcd節(jié)點后指向了其空子節(jié)點,j = 0, i < len(abcded)。
查找到abcd的空子節(jié)點,直接將ef賦值到子節(jié)點上,成為abcd的子節(jié)點。ef節(jié)點被標記為iskey=1,用來標識abcd這個key。ef節(jié)點下再創(chuàng)建一個空子節(jié)點,iskey=1來表示abcdef這個key。
ab在abcd能找到前兩位的前綴,也就是i=len(ab),j < len(abcd)。
將abcd分割成ab和cd兩個子節(jié)點,cd也是一個壓縮前綴節(jié)點,cd同時被標記為iskey=1,來表示ab這個key。
cd下掛著一個空子節(jié)點,來標記abcd這個key。
abcABC在abcd中只找到了ab這個前綴,即i < len(abcABC),j < len(abcd)。這個步驟有點復雜,分解一下:
step 1:將abcd從ab之后拆分,拆分成ab、c、d 三個節(jié)點。
step 2:c節(jié)點是一個非壓縮的節(jié)點,c掛在ab子節(jié)點上。
step 3:d節(jié)點只有一個字符,所以也是一個非壓縮節(jié)點,掛在c子節(jié)點上。
step 4:將ABC 拆分成了A和BC, A掛在ab子節(jié)點上,和c節(jié)點屬于同一個節(jié)點,這樣A就和c同屬于父節(jié)點ab。
step 5:將BC作為一個壓縮前綴的節(jié)點,掛在A子節(jié)點下。
step 6:d節(jié)點和BC節(jié)點都掛一個空子節(jié)點分別標識abcd和abcABC這兩個key。
abcd和Aabc沒有前綴匹配,i = 0,j = 0。
將abcd拆分成a、bcd兩個節(jié)點,a節(jié)點是一個非壓縮前綴節(jié)點。
將Aabc拆分成A、abc兩個節(jié)點,A節(jié)點也是一個非壓縮前綴節(jié)點。
將A節(jié)點掛在和a相同的父節(jié)點上。
同上,在bcd和abc這兩個節(jié)點下掛空子節(jié)點來分別表示兩個key。
刪除一個key的流程比較簡單,找到iskey的節(jié)點后,向上遍歷父節(jié)點刪除非iskey的節(jié)點。如果是非壓縮的父節(jié)點并且size > 1,表示還有其他非相關的路徑存在,則需要按刪除子節(jié)點的模式去處理這個父節(jié)點,主要是做memove和realloc。
刪除一個key之后需要嘗試做一些合并,以收斂樹的高度。
合并的條件是:
iskey=1的節(jié)點不能合并
子節(jié)點只有一個字符
父節(jié)點只有一個子節(jié)點(如果父節(jié)點是壓縮前綴的節(jié)點,那么只有一個子節(jié)點,滿足條件。如果父節(jié)點是非壓縮前綴的節(jié)點,那么只能有一個字符路徑才能滿足條件)
關于怎么進行Redis radix tree源碼解析就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。