redis底层数据结构——跳跃表

定义

跳肤表(skiplist)是一种有序数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的自的。

跳跃表支持平均O(1ogN、最坏ON复杂度的节点查找,还可以通过顺序性操作来批量处理节点。

在大部分情况下,跳肤表的效率可以和平衡树相美,并且因为跳肤表的实现比平衡树要来得更为简单,所以有不少程序都使用跳肤表来代替平衡树。

Redis使用跳跃表作为有序集合键的底层实现之一,如果一个有序集合包含的元素数量比较多,又或者有序集合中元素的成员(member)是比较长的字符串时,Redis就会使用跳跃表来作为有序集合键的底层实现。

内部实现

Redis的跳跃表由redis.h/zskiplistNode和redis.h/zskiplist两个结构定义,其中zskiplistNode结构用于表示跳跃表节点,而zskiplist结构则用于保存跳跃表节点的相关信息。

跳跃表节点

``

typedef struct zskiplistNode{
//层
struct zskiplistLevel {
// 前进指针
struct zskiplistNode *forward ;
// 跨度
unsigned int span ;
}level[] ;
// 后退指针
struct zskiplistNode backward ;
//分值
doublescore
/成员对象
robj
obj&#x

### Redis 数据结构底层实现详解 #### 字符串类型 (String) Redis 的字符串能够存储多种类型的数据,包括但不限于二进制数据、文本数据以及数值型数据。对于这种类型的对象,在设计上采用了简单动态字符串(SDS, Simple Dynamic String),以确保高效的操作与管理[^3]。 ```c struct sdshdr { int len; /* 已使用的字节数 */ int free; /* 剩余可用空间数 */ char buf[]; /* 存储实际字符数组 */ } ``` 通过这种方式,不仅实现了对字符串长度的有效追踪,同时也简化了追加操作并减少了频繁分配/释放带来的开销。 #### 列类型 (List) 列键的底层可以通过两种不同的形式来示:当元素数量较少且单个元素较短时采用压缩列;反之,则会转为双向链的形式。前者旨在优化小型集合场景下的资源利用率,后者则更适用于处理较大规模或复杂度较高的情况[^4]。 ```c // 双向链节点定义 typedef struct listNode { void *value; struct listNode *prev; struct listNode *next; } listNode; // 压缩列项头文件部分展示 typedef struct zlentry { unsigned int prevrawlensize; unsigned int prevrawlen; unsigned int lensize; unsigned int len; // ...其他成员... } zlentry; ``` #### 集合类型 (Set) 为了提供高效的去重功能,集合通常基于整数集或是哈希这两种结构之一构建而成。具体选择取决于所含元素的数量及其特性——少量的小范围整数适合用紧凑的方式保存,而一般情形下则利用哈希映射达到快速查找的目的。 #### 散列类型 (Hash) 散列同样存在两种可能的内部现形态:如果字段名和值都比较简短的话,那么就会被封装在一个专门定制化的ziplist里边;否则便会被拆分成多个独立的对象,并借助hashtable来进行关联维护。 #### 有序集合类型 (Sorted Set) 该类别的核心在于维持一个按分数排序的成员序列。为此目的,选择了跳跃作为主要支撑技术,允许O(logN)级别的插入删除效率的同时还便于迭代访问整个区间内的条目。 综上所述,通过对不同应用场景需求的理解和技术手段的选择,使得每一种基础组件都能发挥出最佳效能,从而构成了Redis强大而又灵活的数据管理系统。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值