Redis数据结构——跳跃表

1,跳跃表是一种有序数据结构,它可以通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的。跳跃表支持平均O(logN)、最坏O(N)复杂度的节点查找,还可以通过顺序性操作来批处理节点。在大部门情况下,跳跃表的效率可以和平衡树相媲美。
2,Redis中只有两个地方用到了跳跃表,一个是实现有序集合,另一个是在集群节点中用作内部数据结构。
3,跳跃表由redis.h/zskiplistNode和redis.h/zskiplist两个结构定义,其中zskiplistNode结构用于表示跳跃表节点,而zskiplist结构则用于保存跳跃表节点的相关信息,比如节点的数量,以及指向表头节点和表尾节点的指针等。下面分别对zskiplistNode和zskiplist两个结构进行分析。
4,redis.h/zskiplistNode结构定义:

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

  • 跳跃表节点的level数组可以包含多个元素,每个元素都包含一个指向其他节点的指针,程序可以通过这些层来加快访问其他节点的速度。每次创建一个新跳跃表节点的时候,程序就会根据幂次定律随机生成一个介于1和32之间的值作为level数组的大小。
  • 前进指针
    用于表头向表尾方向访问节点。
  • 跨度
    用来记录两个节点之间的距离;指向NULL的所有前进指针的跨度都是0,因为它们没有连向任何节点。可以用它来计算要查找的节点是链表中的第几个节点。
  • 后退指针
    每次只能后退至前一个节点
  • 分值和成员
    节点的分值是一个double类型的浮点数,跳跃表中的所有节点都按分值从小到大来排序。
    节点的成员对象是一个指针,它指向一个字符串对象。而字符串对象则保存着一个SDS值。分值相同的节点将按照成员对象在字典序中的大小进行排序。
    5,zskiplist结构的定义如下:
typedef struct zskiplist{
    
    
	//表头节点和表尾节点
	struct zskiplistNode *header, *tail;
	//表中节点的数量
	unsigned long length;
	//表中层数最大的节点的层数
	int level;
}zskiplist;

猜你喜欢

转载自blog.csdn.net/xiaoan08133192/article/details/115174175