Redis5.0原始碼解析(七)----------字串物件
阿新 • • 發佈:2018-12-11
基於Redis5.0
字串物件
字串物件的編碼可以是 int
、 raw
或者 embstr
- 如果一個字串物件儲存的是整數值, 並且這個整數值可以用
long
型別來表示, 那麼字串物件會將整數值儲存在字串物件結構的ptr
屬性裡面(將void*
轉換成long
), 並將字串物件的編碼設定為int
- 如果字串物件儲存的是一個字串值, 並且這個字串值的長度大於
44
位元組(#define OBJ_ENCODING_EMBSTR_SIZE_LIMIT 44
), 那麼字串物件將使用一個簡單動態字串(SDS)來儲存這個字串值, 並將物件的編碼設定為raw
- 如果字串物件儲存的是一個字串值, 並且這個字串值的長度小於等於
44
位元組, 那麼字串物件將使用embstr
編碼的方式來儲存這個字串值
embstr
編碼是專門用於儲存短字串的一種優化編碼方式, 這種編碼和 raw
編碼一樣, 都使用 redisObject
結構和 sdshdr
結構來表示字串物件, 但 raw
編碼會呼叫兩次記憶體分配函式來分別建立 redisObject
結構和 sdshdr
結構, 而 embstr
編碼則通過呼叫一次記憶體分配函式來分配一塊連續的空間, 空間中依次包含 redisObject
和 sdshdr
兩個結構
以下命令建立了一個 embstr
msg
鍵的值
redis> SET msg "hello"
OK
redis> OBJECT ENCODING msg
"embstr"
編碼的轉換
對於 int
編碼的字串物件來說, 如果我們向物件執行了一些命令, 使得這個物件儲存的不再是整數值, 而是一個字串值, 那麼字串物件的編碼將從 int
變為 raw
redis> SET number 10086
OK
redis> OBJECT ENCODING number
"int"
redis> APPEND number " is a good number!"
(integer) 23
redis> GET number
"10086 is a good number!"
redis> OBJECT ENCODING number
"raw"
Redis 沒有為 embstr
編碼的字串物件編寫任何相應的修改程式 (只有 int
編碼的字串物件和 raw
編碼的字串物件有這些程式), 所以 embstr
編碼的字串物件實際上是隻讀的: 當我們對 embstr
編碼的字串物件執行任何修改命令時, 程式會先將物件的編碼從 embstr
轉換成 raw
, 然後再執行修改命令; 因為這個原因, embstr
編碼的字串物件在執行修改命令之後, 總會變成一個 raw
編碼的字串物件
redis> SET msg "hello world"
OK
redis> OBJECT ENCODING msg
"embstr"
redis> APPEND msg " again!"
(integer) 18
redis> OBJECT ENCODING msg
"raw"
字串命令的實現
因為字串鍵的值為字串物件, 所以用於字串鍵的所有命令都是針對字串物件來構建的,下表列舉了其中一部分字串命令, 以及這些命令在不同編碼的字串物件下的實現方法
命令 | int 編碼的實現方法 | embstr 編碼的實現方法 | raw 編碼的實現方法 |
---|---|---|---|
SET | 使用 int 編碼儲存值。 | 使用 embstr 編碼儲存值。 | 使用 raw 編碼儲存值。 |
GET | 拷貝物件所儲存的整數值, 將這個拷貝轉換成字串值, 然後向客戶端返回這個字串值。 | 直接向客戶端返回字串值。 | 直接向客戶端返回字串值。 |
APPEND | 將物件轉換成 raw 編碼, 然後按 raw 編碼的方式執行此操作。 | 將物件轉換成 raw 編碼, 然後按 raw 編碼的方式執行此操作。 | 呼叫 sdscatlen 函式, 將給定字串追加到現有字串的末尾。 |
INCRBYFLOAT | 取出整數值並將其轉換成 long double 型別的浮點數, 對這個浮點數進行加法計算, 然後將得出的浮點數結果儲存起來。 | 取出字串值並嘗試將其轉換成 long double 型別的浮點數, 對這個浮點數進行加法計算, 然後將得出的浮點數結果儲存起來。 如果字串值不能被轉換成浮點數, 那麼向客戶端返回一個錯誤。 | 取出字串值並嘗試將其轉換成 long double 型別的浮點數, 對這個浮點數進行加法計算, 然後將得出的浮點數結果儲存起來。 如果字串值不能被轉換成浮點數, 那麼向客戶端返回一個錯誤。 |
INCRBY | 對整數值進行加法計算, 得出的計算結果會作為整數被儲存起來。 | embstr 編碼不能執行此命令, 向客戶端返回一個錯誤。 | raw 編碼不能執行此命令, 向客戶端返回一個錯誤。 |
DECRBY | 對整數值進行減法計算, 得出的計算結果會作為整數被儲存起來。 | embstr 編碼不能執行此命令, 向客戶端返回一個錯誤。 | raw 編碼不能執行此命令, 向客戶端返回一個錯誤。 |
STRLEN | 拷貝物件所儲存的整數值, 將這個拷貝轉換成字串值, 計算並返回這個字串值的長度。 | 呼叫 sdslen 函式, 返回字串的長度。 | 呼叫 sdslen 函式, 返回字串的長度。 |
SETRANGE | 將物件轉換成 raw 編碼, 然後按 raw 編碼的方式執行此命令。 | 將物件轉換成 raw 編碼, 然後按 raw 編碼的方式執行此命令。 | 將字串特定索引上的值設定為給定的字元。 |
GETRANGE | 拷貝物件所儲存的整數值, 將這個拷貝轉換成字串值, 然後取出並返回字串指定索引上的字元。 | 直接取出並返回字串指定索引上的字元。 | 直接取出並返回字串指定索引上的字元。 |