redis底层数据结构

1.动态字符串

用的是c语言,自己写的简单动态字符串sds,分为

struct sdshdr{
     //记录buf数组中已使用字节的数量
     int len;
     //记录 buf 数组中未使用字节的数量
     int free;
     //字节数组,用于保存字符串
     char buf[];
}

为什么设计呢

  • 1.常熟复杂度获取字符串的长度,c语言是要遍历一遍计数的,空间换时间,直接读len就行了
  • 2.防止缓存溢出,字符串strcat时,可能由于分配的空间不够导致 内存溢出,现在设置了sds,修改时判断len会不会溢出,溢出就扩展,不会溢出。
  • 3.减少分配内存的次数,c语言每次的长度变化都会导致内存分配,但是sds有len,free,有两个策略:
    • 空间预分配:拓展时,由于有预留的空间,减少了空间间的变动,
    • 惰性空间释放 :在缩小长度时,不会立即的会及回收
  • 4.二进制安全,因为C字符串以空字符作为字符串结束的标识,而对于一些二进制文件(如图片等),内容可能包括空字符串,因此C字符串无法正确存取;而所有 SDS 的API 都是以处理二进制的方式来处理 buf 里面的元素,并且 SDS 不是以空字符串来判断是否结束,而是以 len 属性表示的长度来判断字符串是否结束。

2.链表list

C 语言内部是没有内置这种数据结构的实现,所以Redis自己构建了链表的实现。
Redis链表特性:

①、双端:链表具有前置节点和后置节点的引用,获取这两个节点时间复杂度都为O(1)。

②、无环:表头节点的 prev 指针和表尾节点的 next 指针都指向 NULL,对链表的访问都是以 NULL 结束。

③、带链表长度计数器:通过 len 属性获取链表长度的时间复杂度为 O(1)。

④、多态:链表节点使用 void* 指针来保存节点值,可以保存各种不同类型的值。

3.Map

字典又称为符号表或者关联数组、或映射(map),是一种用于保存键值对的抽象数据结构。字典中的每一个键 key 都是唯一的,通过 key 可以对值来进行查找或修改。C 语言中没有内置这种数据结构的实现,所以字典依然是 Redis自己构建的。

4.zset

zset是Redis提供的一个非常特别的数据结构,常用作排行榜,微信点赞等功能,以用户id为value,关注时间或者分数作为score进行排序。与其他数据结构相似,zset也有两种不同的实现,分别是zipList和skipList。z具体使用哪种结构进行存储,规则如下:

  • zipList:满足以下两个条件
    • [score,value]键值对数量少于128个
    • 每个元素的长度小于64字节
  • skipList:不满足以上两个条件时使用跳表、组合了hash和skipList
    • hash用来存储value到score的映射,这样就可以在O(1)时间内找到value对应的分数;
    • skipList按照从小到大的顺序存储分数
    • skipList每个元素的值都是[socre,value]对
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值