首先来看几个例子
例1:保存一个long类型的整数值
例2:保存一个长度大于32bit的字符串
例3:保存一个长度小于等于32bit的字符串
以上3个例子,value对象都是string对象,但是它们所对应的encoding各不相同,分别是 “int” 、“raw ”、“embstr”。
它们对应的redisOject存储也不相同。下面分别来看看。(这里是看value的存储)
例1:
redisObject |
type OBJ_STRING |
encoding OBJ_ENCODING_INT |
ptr |
其中,ptr->1
例2:
redisObject |
type OBJ_STRING |
encoding OBJ_ENCODING_RAW |
ptr |
其中,ptr指向一个sds结构:
sdshdr |
len 69 |
alloc 0 |
flags |
buf |
其中,buf数组指向字符串,并以“\0”结尾。
例3:
和例2不同之处在于,例2是调用两次空间分配函数来分配两个不连续的内存空间;而例3使用embstr编码的SDS来存储较短的字符串时,只调用一次空间分配函数,redisObject和sdshdr是在一块连续的空间,结构图如下(图片来自《redis设计与实现》一书):ptr指向buf数组的第一个字节
当value是浮点数或者整数,需要做加减操作时,程序会先取出value,将它转换成浮点数或者整数,加减操作之后再转换成字符串保存到string对象中去。如下:
当value是浮点数或者整数,使用append命令向value追加一个字符串,程序会将它转换成字符串,然后追加,最后保存,此时encoding就会变成raw。如下:
当value的编码是embstr时,由于程序没有对embstr的修改操作,embstr是只读的。需要对embstr进行任何修改操作时,会先将value转换成raw,然后进行操作,最后value会变成一个raw编码的SDS。如下: