Redis底层有SDS、链表、五种数据结构。
1、SDS
Redis中是String类型是基于简单动态字符串(SDS)实现的,SDS的结构定义为:
struct sdshdr{// 字节数组,用于保存字符串char buf[];// 记录buf数组中已使用的字节数量,也是字符串的长度int len;
// 记录buf数组未使用的字节数量int free;}
SDS与C字符串的区别:
1)SDS可以O(1)常数复杂度获取字符串长度
2)不会产生内存溢出;
SDS进行字符串修改时,会先检查空间是否满足修改需求,如果不满足就会自动进行空间扩展,故不会出现缓冲溢出的情况。SDS空间扩展时,会有空间预分配策略:简单来讲,如果修改字符串空间不足时,会首先给SDS分配相应空间,然后完成对SDS的修改,修改后如果SDS的长度小于1M,会预分配与当前SDS长度相同的空间,即这是SDS结构中的已使用长度== free长度;如果修改后SDS的长度大于等于1M,就会给SDS预分配1M长度的未使用空间。同时这种预分配机制也减少了对于内存重分配的次数。
3)SDS惰性空间释放
当SDS字符串缩短时,不会立即回收多出的内存空间,而是将这部分空间划分到free未使用空间部分。
4)SDS是二进制安全的,可以保存二进制数据,可以用于保存图片、音视频等,而C只能保存文件数据。
2、链表
链表节点定义:
typedef strcut listNode{ //前置节点 strcut listNode *pre; //后置节点 strcut listNode *pre; //节点的值 void *value;}listNode
链表定义:
typedef struct list{ //表头结点 listNode *head; //表尾节点 listNode *tail; //链表长度 unsigned long len; //节点值复制函数 void *(*dup) (viod *ptr); //节点值释放函数 void (*free) (viod *ptr); //节点值对比函数 int (*match) (void *ptr,void *key);}list
链表特点:
1)无环双向链表结构
2)获取头尾节点、以及链表长度的时间复杂度为O(1)
3)链表节点使用void*指针保存节点值
3 字典
该部分可以参考下面链接介绍:
未完待续。。。