redisObject
结构
/* * Redis 对象 */ typedef struct redisObject { // 类型 4bits unsigned type:4; // 编码方式 4bits unsigned encoding:4; // LRU 时间(相对于 server.lruclock) 24bits unsigned lru:22; // 引用计数 Redis里面的数据可以通过引用计数进行共享 32bits int refcount; // 指向对象的值 64-bit void *ptr; } robj;
type 、 encoding 和 ptr 是最重要的三个属性。 type 记录了对象所保存的值的类型,它的值可能是以下常量的其中一个(定义位于 redis.h):
/* * 对象类型 */ #define REDIS_STRING 0 // 字符串 #define REDIS_LIST 1 // 列表 #define REDIS_SET 2 // 集合 #define REDIS_ZSET 3 // 有序集 #define REDIS_HASH 4 // 哈希表
encoding 记录了对象所保存的值的编码,它的值可能是以下常量的其中一个(定义位于 redis.h):
/* * 对象编码 */ #define REDIS_ENCODING_RAW 0 // 编码为字符串 #define REDIS_ENCODING_INT 1 // 编码为整数 #define REDIS_ENCODING_HT 2 // 编码为哈希表 #define REDIS_ENCODING_ZIPMAP 3 // 编码为 zipmap #define REDIS_ENCODING_LINKEDLIST 4 // 编码为双端链表 #define REDIS_ENCODING_ZIPLIST 5 // 编码为压缩列表 #define REDIS_ENCODING_INTSET 6 // 编码为整数集合 #define REDIS_ENCODING_SKIPLIST 7 // 编码为跳跃表
ptr是一个指针,指向实际保存值的数据结构,这个数据结构由type属性和encoding属性决定。
举个例子,如果一个redisObject的type属性为REDIS_LIST,encoding属性为REDIS_ENCODING_LINKEDLIST,那么这个对象就是一个Redis列表,它的值保存在一个双端链表内,而ptr指针就指向这个双端链表;
另一方面,如果一个redisObject的type属性为REDIS_HASH,encoding属性为REDIS_ENCODING_HT,那么这个对象就是一个 Redis 哈希表,它的值保存在一个哈希表里,而 ptr 指针就指向这个哈希表;诸如此类。
下图展示了 redisObject、Redis所有数据类型、以及 Redis 所有编码方式(底层实现)三者之间的关系:
命令的类型检查和多态
有了 redisObject 结构的存在, 在执行处理数据类型的命令时, 进行类型检查和对编码进行多态操作就简单得多了。
当执行一个处理数据类型的命令时, Redis 执行以下步骤:
- 根据给定 key ,在数据库字典中查找和它相对应的 redisObject ,如果没找到,就返回 NULL 。
- 检查 redisObject 的 type 属性和执行命令所需的类型是否相符,如果不相符,返回类型错误。
- 根据 redisObject 的 encoding 属性所指定的编码,选择合适的操作函数来处理底层的数据结构。
- 返回数据结构的操作结果作为命令的返回值。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通