Redis 跳跃表

原理: 在每个节点中维持多个指向其他节点的指针。达到接近二分查找的目的

大部分情况下,跳跃表的执行效率与平衡数相媲美

当LinkedHashSet 中 

1 元素数目过多  或者 2  成员是过长的字符串 

使用跳跃表作为有序集合键的底层实现。

跳表在Redis中的应用:

1实现有序集合键

2在集群节点中用作内部数据结构

涉及到两个结构体:

1 zskiplistNode   用于表示跳跃表的节点

2 zskiplist    用于保存跳跃表节点的相关信息,如节点的数量、表头节点指针、表尾节点指针

typedef struct zskiplist{
    structz skiplistNode *header,*tail;  //表头  表尾指针
    // 节点数目
    unsigned long length;
    // 表中层数最大的节点的层数
    int level;


}zskiplist;

其中length 不包含表头节点

level 层数不包含表头节点

用L1、L2、L3 标记每个层,L1代表第一层,L2代表第二层,以此类推

每个层包含两个属性:

1前进指针  用于访问表尾方向的其他节点

2跨度         记录前进指针指向节点与当前节点的距离

后退指针:指向位于当前节点的前一个节点。用于程序从表尾向表头遍历

分值:score   每个节点会被分配一个分值,用作节点排序的指标,从小到大排序

typedef struct zskiplistNode {
    struct zskiplistNode *backward;  //后退指针
    double score;  //分值
    robj *obj; //成员对象
    // 层
    struct zskiplistLevel {
        struct zskiplistNode *forward;   //前进指针
        unsigned int span;   //跨度
    } level[];    //层数组,用于加快查询速度,理论上层越多访问速度越快
}zskiplistNode;

根据幂等定律随机给一个节点生成一个介于1到32之间的值作为层数组的大小,也就是层的高度。

值越小,其层数越多,过滤效率越高

使用前进指针实现有序集合的遍历

跨度是用来计算排位的,在查找某个节点的过程中,将沿途访问的所有层的跨度相加,就可以得到目标节点score的排名

成员对象是一个指针  *obj指向一个字符串对象SDS

每个跳表节点都有一个score,节点按照score从小到大排序。节点间的score可以相同,但是成员对象必然唯一(Set特性)

当score相同时,按照成员对象在字典序中的顺序进行排序。

猜你喜欢

转载自blog.csdn.net/csdn_9527666/article/details/88677064
今日推荐