首页 > 编程知识 正文

列举铁道车辆基本结构,财富能量的六大核心秘密

时间:2023-05-05 08:49:56 阅读:18750 作者:4360

前言有序集(set )可以视为基于集集合,为集合中的每个元素维护顺序值: score。 这样,可以在score中对集合中的元素进行排序。 其典型实用场景有:考生分数排名、某游戏玩家分数排名、网站首页数据排名、最新评论时间排名等。

Redis是一个内存数据库,在保证读写速度的同时还必须考虑内存开销。 对于有序集规则集合,必须保持顺序值。 对于顺序集合的基础实现,可以选择数组、链表、平衡树和红黑树等结构,但SortedSet不选择这些结构。 插入和删除数组中的元素性能较差,链表查询速度较慢。 虽然平衡树或红黑树具有很高的查询效率,但由于在插入和删除元素时必须保持树的平衡,因此性能会下降,实现非常复杂。

因此,SortedSet的基础采用了一种新的数据结构——跳表

skiplist跳表原理跳表的性能与红黑树相当,而且实现起来比红黑树简单得多。 什么是跳跃表? 要了解跳转表之间的关系,首先看看下面的链表。

如果要查询值为13的节点,则上面的单向链表需要从前到后遍历节点。 进行10次搜索后,性能会非常差。 如何加快查询速度? 我知道即使做了有序的链表,只要不把这张链表做成红黑树一样的结构,也不会奇怪地进行二分搜索,但是红黑树实现起来太麻烦了。 所以,如果我这样处理这个链表呢?

我提取第一层链表的元素,每隔两层向上提取一个元素,做第二层链表。 如上图所示,查找元素时先从最上层查找13,找到18时大于13时返回10,返回下层查找后再找到13。 这次的搜索次数几乎是到目前为止单向链表的一半,可以大幅节省搜索时间。 那么,我再往上一层提取怎么样?

按照刚才的规律,我们再往上抽出一层,这次找的次数不是又少了吗? 实际上,这个数据结构是“跳转表”的存储结构。 其实我知道他的搜索性能和红黑树相当,但实现起来比红黑树容易多了。

SortedSet的基础实现SortedSet的基础实现使用两种存储结构: Ziplist压缩列表和“跳转表”。 Redis配置文件有两种配置:

zset-max-zip list-entries 128:zset采用压缩列表时,元素数的最大值。 默认值为128。 zset-max-ziplist-value 64:zset采用压缩列表时,各元素字符串长度的最大值。 默认值为64。 当zset插入第一个元素时,它会确定以下两个条件: zset-max-ziplist-entries的值是否为0 : zset-max-ziplist-value短于要插入元素的字符串的长度,满足其中一个条件的Redis采用基于跳转表的实现,否则采用基于压缩列表的实现。 源代码参考: t_zset.c

voidzaddgenericcommand (客户端* c,int flags )…省略. if ) zobj==null ) ) if ) xx ) goto reply_to_client;/* nokeyxxoption : nothing todo.*/if (server.zset _ max _ zip list _ entries==0||server.zset _ max _ zip lip/*创建压缩列表*/}数据库添加(c-db、key、zobj ); }由于zset-max-ziplist-entries通常不设置为0,元素的字符串长度也不是很长,因此创建规则集合时,缺省情况下将使用压缩列表中较低级别的实现。 当zset插入新元素时,将确定以下两个条件: zset的元素数大于zset_max_ziplist_entries; 插入的元素的字符串长度大于zset_max_ziplist_value。 如果满足其中一个条件,Redis会将zset的基本实现从压缩列表转换为跳转表。 请参阅t_zset.c中的zsetAdd函数

if(zzllength(zobj-ptr ) server.zset _ max _ zip list _ entries|| sdslen (ele ) server.zset _ max _ zip list _ entr

skiplist的结构跳转表主要由跳转表节点、头节点、尾节点、节点数、节点最大层数组成,如下所示。 源代码见server.h

类型def struct zsk iplist { ST

ruct zskiplistNode *header, *tail;//跳表节点 ,头节点 , 尾节点 unsigned long length;//节点数量 int level;//目前表内节点的最大层数} zskiplist;typedef struct zset { dict *dict; zskiplist *zsl;} zset;

解释:

header: 指向跳跃表头节点,头节点是跳跃表的一个特殊节点,它的level数组元素个数为64。头节点在有序集合中不存储任何member和score值,ele值为NULL,score值为0;也不计入跳跃表的总长度。头节点在初始化时,64个元素的forward都指向NULL,span值都为0。tail:指向跳跃表尾节点length:跳跃表长度,表示除头节点之外的节点总数level:跳跃表的最大的节点的高度。

zskiplist 结构如图:

zskiplistNode 结构 //跳表节点typedef struct zskiplistNode { sds ele;//用于存储字符串类型的数据 double score;//分值 struct zskiplistNode *backward;//后向指针 struct zskiplistLevel {//节点所在的层 struct zskiplistNode *forward;//前向指针 unsigned int span;//该层向前跨越的节点数量 } level[]; //节点层结构 数组,每次创建一个跳表节点时,都会随机生成一个[1,32]之间的值作为level数组的大小。} zskiplistNode;

解释:

ele : 用于存储字符串类型的数据

backward:后退指针,只能指向当前节点最底层的前一个节点,头节点和第一个节点——backward指向NULL,从后向前遍历跳跃表时使用。

score:用于存储排序的分值

level:为柔性数组。每个节点的数组长度不一样,在生成跳跃表节点时,随机生成一个1~64的值,值越大出现的概率越低。

forward:指向本层下一个节点,尾节点的forward指向NULL。span:forward指向的节点与本节点之间的元素个数。span值越大,跳过的节点个数越多

跳跃表的每个节点的ele存储有序集合的成员member值,score存储成员score值。所有节点的分值是按从小到大的方式排序的,当有序集合的成员分值相同时,节点会按member的字典序进行排序。

文章结束,希望对你有所帮助,如果喜欢请给个好评吧!!!

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。