天天看点

[redis设计与实现][7]基本数据结构——对象

redis对基础数据类型进行了封装,构建出上层的对象系统,这个系统包含:字符串对象、列表对象、哈希对象、集合对象和有序集合对象。

redis对象结构:

[cce lang=”c”]

typedef struct redisobject {

//类型

unsigned type:4;

//编码

unsigned encoding:4;

//lru时间

unsigned lru:redis_lru_bits; /* lru time (relative to server.lruclock) */

//引用计数

int refcount;

//底层实现数据结构的指针

void *ptr;

} robj;

[/cce]

相关宏定义:

#define redis_lru_bits 24

#define redis_lru_clock_max ((1<<redis_lru_bits)-1) /* max value of obj->lru */

#define redis_lru_clock_resolution 1 /* lru clock resolution in seconds */

redis对象类型:(使用type命令查看)

/* object types */

#define redis_string 0

#define redis_list 1

#define redis_set 2

#define redis_zset 3

#define redis_hash 4

//对象编码类型:(使用object encoding命令)

#define redis_encoding_raw 0 /* raw representation */

#define redis_encoding_int 1 /* encoded as integer */

#define redis_encoding_ht 2 /* encoded as hash table */

#define redis_encoding_zipmap 3 /* encoded as zipmap */

#define redis_encoding_linkedlist 4 /* encoded as regular linked list */

#define redis_encoding_ziplist 5 /* encoded as ziplist */

#define redis_encoding_intset 6 /* encoded as intset */

#define redis_encoding_skiplist 7 /* encoded as skiplist */

<b>不同类型和编码的对象:

</b>

类型

编码

对象

redis_string

redis_encoding_int

使用整数值实现的字符串对象

redis_encoding_embstr

这货redis3.0引入的,不管

redis_encoding_raw

sds实现的字符串对象

redis_list

redis_encoding_ziplist

使用压缩列表实现的列表对象

redis_encoding_linkedlist

使用双向链表实现的列表对象

redis_hash

使用压缩列表实现的哈希对象

redis_encoding_ht

使用字典实现的哈希对象

redis_set

redis_encoding_intset

使用整数集合实现的集合对象

使用字典实现的集合对象

redis_zset

使用压缩列表实现的有序集合对象

redis_encoding_skiplist

使用跳跃表想和字典实现的有序集合对象

<b>

<b>字符串对象:</b>

整数(long)被保存为int类型

浮点保存为字符串,浮点运算(incrybyfloat)redis先转成浮点,进行运算后再转回字符串

<b>列表对象:</b>

列表对象同时满足一下两个条件时,列表对象使用ziplist编码

列表对象保存的所有字符串元素的长度都小于64个字节(list-max-ziplist-value)

列表对象保存的元素数量小于512个(list-max-ziplist-entries)

不能满足条件的都需要使用linkedlist编码。

<b>哈希对象:</b>

使用压缩列表,键和值分别作为节点按顺序放入列表

使用ziplist的条件:

哈希对象保存的所有键值对的键和值的字符串长度小于64个字节(hash-max-ziplist-value)

哈希对象保存的键值对数量小于512个(hash-max-ziplist-entries)

<b>集合对象:</b>

hashtable编码,字典的每个键都是一个字符串对象,字典的值全部设置为null

使用intset编码条件:

集合对象保存的所有元素是整数值

集合对象保存的元素数量不超过512个(set-max-intset-entries)

不满足条件的集合对象需要使用hashtable编码

<b>有序集合对象:</b>

ziplist编码的有序集合,每个集合元素使用两个紧挨在一起的压缩节点列表来保存,第一个节点保存元素的成员,第二个节点保存元素的分值。

skiplist编码的有序集合,采用一个skiplist和一个hashtable实现。

使用ziplist编码条件:

有序集合保存的元素数量小于128个(zset-max-ziplist-entries)

有序集合保存的所有元素成员的长度都小于64字节(zset-max-ziplist-value)

<b>对象共享:</b>

redis在初始化时,会创建1w个字符串对象(redis_shared_integers),包含整数0~9999,当需要使用这些对象的时候,会使用这些对象的引用(引用计数)而不新创建。

if (value &gt;= 0 &amp;&amp; value &lt; redis_shared_integers) {

incrrefcount(shared.integers[value]);

o = shared.integers[value];

}

转载自:https://coolex.info/blog/454.html

继续阅读