1. 程式人生 > >Redis5.0原始碼解析(七)----------字串物件

Redis5.0原始碼解析(七)----------字串物件

基於Redis5.0

字串物件

字串物件的編碼可以是 intraw 或者 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 編碼則通過呼叫一次記憶體分配函式來分配一塊連續的空間, 空間中依次包含 redisObjectsdshdr 兩個結構
在這裡插入圖片描述

以下命令建立了一個 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 拷貝物件所儲存的整數值, 將這個拷貝轉換成字串值, 然後取出並返回字串指定索引上的字元。 直接取出並返回字串指定索引上的字元。 直接取出並返回字串指定索引上的字元。