1.簡單動態(tài)字符串
每個sds.h/sdshdr結(jié)構(gòu)表示一個SDS值,Redis是C語言寫的。
與C字符串的區(qū)別:
常數(shù)復(fù)雜度獲取字符串長度
杜絕緩沖區(qū)溢出
C字符串不記錄長度勺三,如果兩個C字符串前后緊挨在一起,這時候擴展前字符串時,后字符串就會被覆蓋。
- 減少修改字符串時內(nèi)存重分配的次數(shù)
結(jié)構(gòu)體的free狰闪,就是處理分配的空間大小,如果你要擴展的話濒生,可以探索是否有足夠空間埋泵,夠的話直接修改free,不夠再重分配罪治,縮短一定不用重分配了丽声,直接縮短就行了。
二進制安全
兼容部分C字符串函數(shù)
2.鏈表
鏈表廣泛運用與Redis的各個功能觉义,例如:列表鍵雁社、發(fā)布與訂閱、慢查詢晒骇、監(jiān)視器等霉撵。
3.字典
(1) 結(jié)構(gòu)體
字典所使用的的哈希表結(jié)構(gòu):
我們存進去的hash鍵值對是哈希表的節(jié)點
字典的結(jié)構(gòu)體:
整個關(guān)系是:字典>哈希表>鍵值對
(2)存入過程
先計算鍵值對的哈希值滋饲,根據(jù)哈希值模哈希表的節(jié)點數(shù),得出鍵值對存入哪個節(jié)點中喊巍。解決哈希沖突的方法是拉鏈法
當(dāng)鍵值對越來越多的時候,為了維持負載因子在一定量箍鼓,會進行rehash操作崭参。rehash過程采用的是漸進式rehash
4.跳躍表
一種有序數(shù)據(jù)結(jié)構(gòu),它通過在每個節(jié)點中維持多個指向其他結(jié)點的指針款咖,從而達到快速訪問節(jié)點的目的何暮。
跳躍表支持平均Ologn,最壞On復(fù)雜度的查找復(fù)雜度铐殃,跳表實現(xiàn)比平衡二叉樹簡單海洼。
跳表只在有序集合鍵使用到了
(1)跳表的實現(xiàn)
跳表用了兩個結(jié)構(gòu)體定義穆役,相對復(fù)雜的是節(jié)點的結(jié)構(gòu)體定義匕坯。
跳躍表節(jié)點
每個節(jié)點都有一個數(shù)組常摧,我們稱作層样悟,每一層都可以直接指向其他節(jié)點劲适,只要層越多碾篡,訪問節(jié)點速度越快铡羡。
每層都有一個前進指針拭嫁,還有個跨度民假,前進指針用來指向下一個節(jié)點浮入,跨度記錄前進指針跨了幾個節(jié)點。
5.整數(shù)集合
數(shù)據(jù)結(jié)構(gòu)如圖:
整數(shù)集合是個集合羊异,所以不會有重復(fù)值事秀,只存放整數(shù)int8、int32野舶、int64易迹;
整數(shù)集合底層實現(xiàn)是個數(shù)組contents,而且排好序的
contents的類型不是int8平道,真正的類型是由encoding的值決定的赴蝇。
升級與降級
升級過程:
1)根據(jù)新元素的類型,擴展數(shù)組底層的空間大小巢掺,并為新元素分配空間句伶;
2)將底層數(shù)組的所有元素換成對應(yīng)的類型,并保證有序性的情況下放在正確的位置上陆淀;
3)將新元素放入底層數(shù)組中考余;
升級的好處:
提升靈活性
節(jié)約內(nèi)存
降級:整數(shù)集合不支持降級操作,一旦升級就不會降級轧苫。
6.壓縮列表
壓縮列表是列表鍵與哈希鍵的底層實現(xiàn)之一楚堤;
壓縮列表的結(jié)構(gòu)包括:zlbytes疫蔓、zltail、zllen身冬、entrys衅胀;其中entrys是個列表,zlbyte表示整個壓縮列表的大小酥筝,zltail是從壓縮列表首地址到最后一個entry的地址偏移量滚躯;
-
entry由previous_entry_length、encoding嘿歌、content組成掸掏,其中:
- previous_entry_length保存上一個entry的長度,大小有1字節(jié)或者5字節(jié)宙帝,可用這個值來計算上一個節(jié)點的首地址
encoding記錄了content的類型以及長度
連鎖更新:我們往一個壓縮列表的首節(jié)點插入一個大于254字節(jié)的節(jié)點丧凤,這時,后面的那個節(jié)點的previous_entry_length就要從1字節(jié)編程5字節(jié)步脓,這時就需要重分配內(nèi)存愿待,而重分配后,該節(jié)點后一個結(jié)點的previous_entry_length也要從1字節(jié)變成5字節(jié)靴患,會導(dǎo)致連鎖更新呼盆。