有序集合zset的内部数据结构分析

2024-05-03 15:58

本文主要是介绍有序集合zset的内部数据结构分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  • 有序集合zset在内部可以使用压缩列表ziplist或者跳跃表skiplist来实现。
压缩列表
  • 如果使用压缩列表ziplist来实现,则键和分值紧凑相邻保存在压缩列表中,同时分值小的排在列表前面,分值大的排在列表后面。使用压缩列表ziplist来保存需要满足以下两个条件,否则使用跳跃表skiplist:
    • 集合元素少于128个;
    • 集合每个元素的键和分值都少于64个字节;
  • 即在集合元素较少,元素类型较小时,使用压缩列表,这样由于数据元素较少,故虽然压缩列表效率较低,但是基本不会有多大影响,而且可以充分利用压缩列表的连续内存和紧凑的数据结构实现来节省内存。
  • 以上两个条件可以在配置文件中分别通过zset-max-ziplist-entries和zset-max-ziplist-value这两个参数来修改。
跳跃表
  • 源码定义如下:

    // 有序集合
    typedef struct zset {dict *dict;zskiplist *zsl;
    } zset;
    
  • 如果是使用跳跃表skiplist,则会结合一个哈希字典dict来实现:

    • 即使用哈希字典dict来保存键和分值的映射,实现O(1)复杂度获取某个键的分值;通过跳跃表skiplist来根据分值排序来排序该集合,从而实现按分值排序,其中跳跃表的每个节点都同时包含分值和键。
    • 在内存使用方面,哈希字典dict和跳跃表skiplist是通过指针来共享键和分值的,故不会存在两份数据,节省了内存。
    • 如果只使用哈希字典来实现,则获取给定键对应的分值复杂度为O(1),但是如果每次获取有序集合,则需要获取整个集合然后排序,需要O(NlogN)的时间复杂度和O(N)的空间复杂度。
    • 如果只使用跳跃表skiplist来实现,则每次获取某个键的分值都需要在跳跃表来查找,时间复杂度为O(logN)。

这篇关于有序集合zset的内部数据结构分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/957099

相关文章

基于Go语言实现Base62编码的三种方式以及对比分析

《基于Go语言实现Base62编码的三种方式以及对比分析》Base62编码是一种在字符编码中使用62个字符的编码方式,在计算机科学中,,Go语言是一种静态类型、编译型语言,它由Google开发并开源,... 目录一、标准库现状与解决方案1. 标准库对比表2. 解决方案完整实现代码(含边界处理)二、关键实现细

PostgreSQL 序列(Sequence) 与 Oracle 序列对比差异分析

《PostgreSQL序列(Sequence)与Oracle序列对比差异分析》PostgreSQL和Oracle都提供了序列(Sequence)功能,但在实现细节和使用方式上存在一些重要差异,... 目录PostgreSQL 序列(Sequence) 与 oracle 序列对比一 基本语法对比1.1 创建序

Java中的内部类和常用类用法解读

《Java中的内部类和常用类用法解读》:本文主要介绍Java中的内部类和常用类用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录内部类和常用类内部类成员内部类静态内部类局部内部类匿名内部类常用类Object类包装类String类StringBuffer和Stri

慢sql提前分析预警和动态sql替换-Mybatis-SQL

《慢sql提前分析预警和动态sql替换-Mybatis-SQL》为防止慢SQL问题而开发的MyBatis组件,该组件能够在开发、测试阶段自动分析SQL语句,并在出现慢SQL问题时通过Ducc配置实现动... 目录背景解决思路开源方案调研设计方案详细设计使用方法1、引入依赖jar包2、配置组件XML3、核心配

Java NoClassDefFoundError运行时错误分析解决

《JavaNoClassDefFoundError运行时错误分析解决》在Java开发中,NoClassDefFoundError是一种常见的运行时错误,它通常表明Java虚拟机在尝试加载一个类时未能... 目录前言一、问题分析二、报错原因三、解决思路检查类路径配置检查依赖库检查类文件调试类加载器问题四、常见

Python中的Walrus运算符分析示例详解

《Python中的Walrus运算符分析示例详解》Python中的Walrus运算符(:=)是Python3.8引入的一个新特性,允许在表达式中同时赋值和返回值,它的核心作用是减少重复计算,提升代码简... 目录1. 在循环中避免重复计算2. 在条件判断中同时赋值变量3. 在列表推导式或字典推导式中简化逻辑

Java程序进程起来了但是不打印日志的原因分析

《Java程序进程起来了但是不打印日志的原因分析》:本文主要介绍Java程序进程起来了但是不打印日志的原因分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java程序进程起来了但是不打印日志的原因1、日志配置问题2、日志文件权限问题3、日志文件路径问题4、程序

Java字符串操作技巧之语法、示例与应用场景分析

《Java字符串操作技巧之语法、示例与应用场景分析》在Java算法题和日常开发中,字符串处理是必备的核心技能,本文全面梳理Java中字符串的常用操作语法,结合代码示例、应用场景和避坑指南,可快速掌握字... 目录引言1. 基础操作1.1 创建字符串1.2 获取长度1.3 访问字符2. 字符串处理2.1 子字

Python 迭代器和生成器概念及场景分析

《Python迭代器和生成器概念及场景分析》yield是Python中实现惰性计算和协程的核心工具,结合send()、throw()、close()等方法,能够构建高效、灵活的数据流和控制流模型,这... 目录迭代器的介绍自定义迭代器省略的迭代器生产器的介绍yield的普通用法yield的高级用法yidle

C++ Sort函数使用场景分析

《C++Sort函数使用场景分析》sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变,如果某些场景需要保持相同元素间的相对顺序,可使... 目录C++ Sort函数详解一、sort函数调用的两种方式二、sort函数使用场景三、sort函数排序