structsdshdr{//等于SDS保存字符串的长度intlen;//记录buf数组中未使用字节的数量intfree;//字节数组,用于保存字符串charbuf[];}而对于SDS,由于len属性和free属性的存在,对于修改字符串SDS实现了空间预分配和惰性空间释放两种策略:
1、空间预分配:对字符串进行空间扩展的时候,扩展的内存比实际需要的多,这样可以减少连续执行字符串增长操作所需的内存重分配次数。
2、惰性空间释放:对字符串进行缩短操作时,程序不立即使用内存重新分配来回收缩短后多余的字节,而是使用free属性将这些字节的数量记录下来,等待后续使用。(当然SDS也提供了相应的API,当我们有需要时,也可以手动释放这些未使用的空间。)
typedefstructlistNode{//前置节点structlistNode*prev;//后置节点structlistNode*next;//节点的值void*value;}listNodetypedefstructlist{//表头节点listNode*head;//表尾节点listNode*tail;//链表所包含的节点数量unsignedlonglen;//节点值复制函数void(*free)(void*ptr);//节点值释放函数void(*free)(void*ptr);//节点值对比函数int(*match)(void*ptr,void*key);}list;字典(hash)typedefstructdictht{//哈希表数组dictEntry**table;//哈希表大小unsignedlongsize;//哈希表大小掩码,用于计算索引值//总是等于size-1unsignedlongsizemask;//该哈希表已有节点的数量unsignedlongused;}dicthttypedefstructdictEntry{//键void*key;//值union{void*val;uint64_tu64;int64_ts64;}v;//指向下一个哈希表节点,形成链表structdictEntry*next;}dictEntry注意这里还有一个指向下一个哈希表节点的指针,我们知道哈希表最大的问题是存在哈希冲突,如何解决哈希冲突,有开放地址法和链地址法。这里采用的便是链地址法,通过next这个指针可以将多个哈希值相同的键值对连接在一起,用来解决哈希冲突。
Redis中跳跃表节点定义如下:
typedefstructzskiplistNode{//层structzskiplistLevel{//前进指针structzskiplistNode*forward;//跨度unsignedintspan;}level[];//后退指针structzskiplistNode*backward;//分值doublescore;//成员对象robj*obj;}zskiplistNode