W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
列表對(duì)象的編碼可以是 ziplist
或者 linkedlist
。
ziplist
編碼的列表對(duì)象使用壓縮列表作為底層實(shí)現(xiàn), 每個(gè)壓縮列表節(jié)點(diǎn)(entry)保存了一個(gè)列表元素。
舉個(gè)例子, 如果我們執(zhí)行以下 RPUSH 命令, 那么服務(wù)器將創(chuàng)建一個(gè)列表對(duì)象作為 numbers
鍵的值:
redis> RPUSH numbers 1 "three" 5
(integer) 3
如果 numbers
鍵的值對(duì)象使用的是 ziplist
編碼, 這個(gè)這個(gè)值對(duì)象將會(huì)是圖 8-5 所展示的樣子。
另一方面, linkedlist
編碼的列表對(duì)象使用雙端鏈表作為底層實(shí)現(xiàn), 每個(gè)雙端鏈表節(jié)點(diǎn)(node)都保存了一個(gè)字符串對(duì)象, 而每個(gè)字符串對(duì)象都保存了一個(gè)列表元素。
舉個(gè)例子, 如果前面所說的 numbers
鍵創(chuàng)建的列表對(duì)象使用的不是 ziplist
編碼, 而是 linkedlist
編碼, 那么 numbers
鍵的值對(duì)象將是圖 8-6 所示的樣子。
注意, linkedlist
編碼的列表對(duì)象在底層的雙端鏈表結(jié)構(gòu)中包含了多個(gè)字符串對(duì)象, 這種嵌套字符串對(duì)象的行為在稍后介紹的哈希對(duì)象、集合對(duì)象和有序集合對(duì)象中都會(huì)出現(xiàn), 字符串對(duì)象是 Redis 五種類型的對(duì)象中唯一一種會(huì)被其他四種類型對(duì)象嵌套的對(duì)象。
注意
為了簡(jiǎn)化字符串對(duì)象的表示, 我們?cè)趫D 8-6 使用了一個(gè)帶有 StringObject
字樣的格子來表示一個(gè)字符串對(duì)象, 而 StringObject
字樣下面的是字符串對(duì)象所保存的值。
比如說, 圖 8-7 代表的就是一個(gè)包含了字符串值 "three"
的字符串對(duì)象, 它是 8-8 的簡(jiǎn)化表示。
本書接下來的內(nèi)容將繼續(xù)沿用這一簡(jiǎn)化表示。
當(dāng)列表對(duì)象可以同時(shí)滿足以下兩個(gè)條件時(shí), 列表對(duì)象使用 ziplist
編碼:
64
字節(jié);512
個(gè);不能滿足這兩個(gè)條件的列表對(duì)象需要使用 linkedlist
編碼。
注意
以上兩個(gè)條件的上限值是可以修改的, 具體請(qǐng)看配置文件中關(guān)于 list-max-ziplist-value
選項(xiàng)和 list-max-ziplist-entries
選項(xiàng)的說明。
對(duì)于使用 ziplist
編碼的列表對(duì)象來說, 當(dāng)使用 ziplist
編碼所需的兩個(gè)條件的任意一個(gè)不能被滿足時(shí), 對(duì)象的編碼轉(zhuǎn)換操作就會(huì)被執(zhí)行: 原本保存在壓縮列表里的所有列表元素都會(huì)被轉(zhuǎn)移并保存到雙端鏈表里面, 對(duì)象的編碼也會(huì)從 ziplist
變?yōu)?nbsp;linkedlist
。
以下代碼展示了列表對(duì)象因?yàn)楸4媪碎L(zhǎng)度太大的元素而進(jìn)行編碼轉(zhuǎn)換的情況:
# 所有元素的長(zhǎng)度都小于 64 字節(jié)
redis> RPUSH blah "hello" "world" "again"
(integer) 3
redis> OBJECT ENCODING blah
"ziplist"
# 將一個(gè) 65 字節(jié)長(zhǎng)的元素推入列表對(duì)象中
redis> RPUSH blah "wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww"
(integer) 4
# 編碼已改變
redis> OBJECT ENCODING blah
"linkedlist"
除此之外, 以下代碼展示了列表對(duì)象因?yàn)楸4娴脑財(cái)?shù)量過多而進(jìn)行編碼轉(zhuǎn)換的情況:
# 列表對(duì)象包含 512 個(gè)元素
redis> EVAL "for i=1,512 do redis.call('RPUSH', KEYS[1], i) end" 1 "integers"
(nil)
redis> LLEN integers
(integer) 512
redis> OBJECT ENCODING integers
"ziplist"
# 再向列表對(duì)象推入一個(gè)新元素,使得對(duì)象保存的元素?cái)?shù)量達(dá)到 513 個(gè)
redis> RPUSH integers 513
(integer) 513
# 編碼已改變
redis> OBJECT ENCODING integers
"linkedlist"
因?yàn)榱斜礞I的值為列表對(duì)象, 所以用于列表鍵的所有命令都是針對(duì)列表對(duì)象來構(gòu)建的, 表 8-8 列出了其中一部分列表鍵命令, 以及這些命令在不同編碼的列表對(duì)象下的實(shí)現(xiàn)方法。
表 8-8 列表命令的實(shí)現(xiàn)
命令 | ziplist 編碼的實(shí)現(xiàn)方法 |
linkedlist 編碼的實(shí)現(xiàn)方法 |
---|---|---|
LPUSH | 調(diào)用 ziplistPush 函數(shù), 將新元素推入到壓縮列表的表頭。 |
調(diào)用 listAddNodeHead 函數(shù), 將新元素推入到雙端鏈表的表頭。 |
RPUSH | 調(diào)用 ziplistPush 函數(shù), 將新元素推入到壓縮列表的表尾。 |
調(diào)用 listAddNodeTail 函數(shù), 將新元素推入到雙端鏈表的表尾。 |
LPOP | 調(diào)用 ziplistIndex 函數(shù)定位壓縮列表的表頭節(jié)點(diǎn), 在向用戶返回節(jié)點(diǎn)所保存的元素之后, 調(diào)用ziplistDelete 函數(shù)刪除表頭節(jié)點(diǎn)。 |
調(diào)用 listFirst 函數(shù)定位雙端鏈表的表頭節(jié)點(diǎn), 在向用戶返回節(jié)點(diǎn)所保存的元素之后, 調(diào)用 listDelNode 函數(shù)刪除表頭節(jié)點(diǎn)。 |
RPOP | 調(diào)用 ziplistIndex 函數(shù)定位壓縮列表的表尾節(jié)點(diǎn), 在向用戶返回節(jié)點(diǎn)所保存的元素之后, 調(diào)用ziplistDelete 函數(shù)刪除表尾節(jié)點(diǎn)。 |
調(diào)用 listLast 函數(shù)定位雙端鏈表的表尾節(jié)點(diǎn), 在向用戶返回節(jié)點(diǎn)所保存的元素之后, 調(diào)用 listDelNode 函數(shù)刪除表尾節(jié)點(diǎn)。 |
LINDEX | 調(diào)用 ziplistIndex 函數(shù)定位壓縮列表中的指定節(jié)點(diǎn), 然后返回節(jié)點(diǎn)所保存的元素。 |
調(diào)用 listIndex 函數(shù)定位雙端鏈表中的指定節(jié)點(diǎn), 然后返回節(jié)點(diǎn)所保存的元素。 |
LLEN | 調(diào)用 ziplistLen 函數(shù)返回壓縮列表的長(zhǎng)度。 |
調(diào)用 listLength 函數(shù)返回雙端鏈表的長(zhǎng)度。 |
LINSERT | 插入新節(jié)點(diǎn)到壓縮列表的表頭或者表尾時(shí), 使用ziplistPush 函數(shù); 插入新節(jié)點(diǎn)到壓縮列表的其他位置時(shí), 使用 ziplistInsert 函數(shù)。 |
調(diào)用 listInsertNode 函數(shù), 將新節(jié)點(diǎn)插入到雙端鏈表的指定位置。 |
LREM | 遍歷壓縮列表節(jié)點(diǎn), 并調(diào)用 ziplistDelete 函數(shù)刪除包含了給定元素的節(jié)點(diǎn)。 |
遍歷雙端鏈表節(jié)點(diǎn), 并調(diào)用 listDelNode 函數(shù)刪除包含了給定元素的節(jié)點(diǎn)。 |
LTRIM | 調(diào)用 ziplistDeleteRange 函數(shù), 刪除壓縮列表中所有不在指定索引范圍內(nèi)的節(jié)點(diǎn)。 |
遍歷雙端鏈表節(jié)點(diǎn), 并調(diào)用 listDelNode 函數(shù)刪除鏈表中所有不在指定索引范圍內(nèi)的節(jié)點(diǎn)。 |
LSET | 調(diào)用 ziplistDelete 函數(shù), 先刪除壓縮列表指定索引上的現(xiàn)有節(jié)點(diǎn), 然后調(diào)用 ziplistInsert 函數(shù), 將一個(gè)包含給定元素的新節(jié)點(diǎn)插入到相同索引上面。 |
調(diào)用 listIndex 函數(shù), 定位到雙端鏈表指定索引上的節(jié)點(diǎn), 然后通過賦值操作更新節(jié)點(diǎn)的值。 |
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: