redis数据结构

引言

从本次开始,对Redis设计与实现进行阅读及相关读书笔记的记录。Redis版本为3.0

数据结构

简单动态字符串SDS

sds数据结构位于sds.h/sdshdr

/*
 * 保存字符串对象的结构
 */
struct sdshdr {
    // buf 中已占用空间的长度
    int len;
    // buf 中剩余可用空间的长度
    int free;
    // 数据空间
    char buf[];
};

相对于C语言的字符串,SDS的优点在于

  • 常数复杂度获取字符串长度
  • 杜绝缓冲区溢出
  • 减少修改字符串所带来的内存重新分配(注意,释放空间时候,不会真的释放,而是设置free的值)

链表

链表的相关代码在adlist.h

链表节点listNode

/*
 * 双端链表节点
 */
typedef struct listNode {
    // 前置节点
    struct listNode *prev;
    // 后置节点
    struct listNode *next;
    // 节点的值
    void *value;
} listNode;

由多个listNode组成的双端链表

image-20220331111939637

链表结构list

/*
 * 双端链表结构
 */
typedef struct list {
    // 表头节点
    listNode *head;
    // 表尾节点
    listNode *tail;
    // 节点值复制函数
    void *(*dup)(void *ptr);
    // 节点值释放函数
    void (*free)(void *ptr);
    // 节点值对比函数
    int (*match)(void *ptr, void *key);
    // 链表所包含的节点数量
    unsigned long len;
} list;

image-20220331112050968

字典

redis中的字典使用哈希表实现,其代码在dict.h

哈希表结构dictht

/*
 * 哈希表
 *
 * 每个字典都使用两个哈希表,从而实现渐进式 rehash 。
 */
typedef struct dictht {
    // 哈希表数组
    dictEntry **table;
    // 哈希表大小
    unsigned long size;    
    // 哈希表大小掩码,用于计算索引值
    // 总是等于 size - 1 比如7号,当计算索引时候, 7&sizemask就可以得到
    unsigned long sizemask;
    // 该哈希表已有节点的数量
    unsigned long used;
} dictht;

其中dictEntry为一个键值对

/*
 * 哈希表节点
 */
typedef struct dictEntry {    
    // 键
    void *key
    // 值
    union {
        void *val;
        uint64_t u64;
        int64_t s64;
    } v;
    // 指向下个哈希表节点,形成链表 表明是一个链地址法解决哈希冲突
    struct dictEntry *next;
} dictEntry;

下面为了形象表示一个哈希表,给出一个例子

image-20220331112501821

下面给出一个多个dictEntry连接的哈希表

image-20220331113154852

最终Redis中的字典数据结构如下

/*
 * 字典
 */
typedef struct dict {
    // 类型特定函数
    dictType *type;
    // 私有数据
    void *privdata;
    // 哈希表
    dictht ht[2];
    // rehash 索引
    // 当 rehash 不在进行时,值为 -1
    int rehashidx; /* rehashing not in progress if rehashidx == -1 */
    // 目前正在运行的安全迭代器的数量
    int iterators; /* number of iterators currently running */
} dict;

/*
 * 字典类型特定函数
 */
typedef struct dictType {
    // 计算哈希值的函数 redis默认的函数算法为murmurhash2
    unsigned int (*hashFunction)(const void *key);
    // 复制键的函数
    void *(*keyDup)(void *privdata, const void *key);
    // 复制值的函数
    void *(*valDup)(void *privdata, const void *obj);
    // 对比键的函数
    int (*keyCompare)(void *privdata, const void *key1, const void *key2);
    // 销毁键的函数
    void (*keyDestructor)(void *privdata, void *
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值