Redis哈希对象的ziplist编码实现了O(1)复杂度吗

Redis中的哈希对象在ziplist编码下,通过遍历实现查找,而非哈希算法,导致其并非O(1)复杂度。尽管如此,ziplist仅在键值对数量少且数据小的情况下使用,实际影响有限。而hashtable编码则保证了O(1)的查找效率。
摘要由CSDN通过智能技术生成

问题描述

问题:Redis中哈希对象有两种编码方式,分别是ziplist、hashtable方式。哈希对象,总得体现哈希算法,使得基本操作达到O(1)的效率。hashtable编码方式使用字典,也即是Java中hashMap的方式,这个我可以理解。但是,ziplist方式所有元素都是紧挨的,它是怎么实现hash,并使得查询等操作有O(1)的时间效率的呢?

分析:

让我们从方法调用开始分析。我们都知道,获取哈希对象中某个元素的命令是“HGET”,当哈希对象的编码方式是ziplist时,它的执行过程如下:

  • 首先调用ziplistFind函数,在压缩列表中查找指定键对应的节点。
  • 然后调用ziplistNext函数,将指针移动到键节点旁边的值节点,最后返回值节点。

从HGET命令在ziplist编码下的执行过程可以看出,问题的关键在ziplistFind方法中。
ziplistFind方法在Redis源码的src/ziplist.c中:

/* 源码注释来自黄键宏先生的github Redis源码注释版本仓库:https://github.com/huangz1990/redis-3.0-annotated
 * Find pointer to the entry equal to the specified entry. 
 * 
 * 寻找节点值和 vstr 相等的列表节点,并返回该节点的指针。
 * 
 * Skip 'skip' entries between every comparison. 
 *
 * 每次比对之前都跳过 skip 个节点。
 *
 * Returns NULL when the field could not be found. 
 *
 * 如果找不到相应的节点,则返回 NULL 。
 *
 * T = O(N^2)
 */
unsigned char *ziplistFind(unsigned char *p, unsigned char *vstr, unsigned int vlen, unsigned int skip) {
    int skipcnt = 0;
    unsigned 
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值