[1] type ====> 类型对应基本数据类型。例如Redis_String 对应字符串,Redis_List对应列表
[2] encoding ====> 编码。编码方式决定了对象的底层的数据结构,一个对象至少有两种编码方式
[3] prt ====> 指针。指向由编码决定的数据结构,数据结构中往往包含有所存的数据
[4] refcount ====> 引用计数。这个属性主要是为了实现redis中的内存回收机制
[5] lru ====> 最近最少使用。用来解决对象的空转时长,同时也会被用于当缓冲达到最大值,再向其中添加数据时,应该删除什么数据。
上述说过,一个对象的底层的数据结构是由对象的编码方式决定的,而ZSet的编码方式有两种
使用压缩连表时,要保证集合中的数据有序,会将key放在前面一位,然后将key所对应value放在key的后一位。这样就能够保证集合的有序。
使用跳跃链表时,由于跳跃链表本来就是有序的,直接使用即可。
跳表数据结构见《Redis设计与实现》P39
当有序集合对象同时满足以下两个条件时,对象使用压缩链表编码:
如果不满足上述两个条件,那么ZipList会转化为SkipList,同时,当后面的SkipList的元素数量和元素成员的长度满足要求时,也不会回退为ZipList。
当使用SkipList实现ZSet时,ptr所指向的zset数据结构中包含了一个skiplist和dict结构。其中dict结构中创建了一个从SkipList对象到score的映射。通过dict可以实现O(1)时间复杂度查找key所对应的value。
那么为什么不直接使用字典或者skipList实现Zset呢?