redis源码系列-数据结构(adlist/ziplist/dict)
该系列基于redis-2.8.18,主要记录自己的理解或者想法。redis以自己支持存储的数据结构丰富吸引了大批人,把memcached比了下去。本文就从简单基本的数据结构入手。
双向链表-adlist
typedef struct listNode {
struct listNode *prev;
struct listNode *next;
void *value;
} listNode;
typedef struct listIter {
listNode *next;
int direction;
} listIter;
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;
压缩链表-ziplist
encoding=00,strlen<=63,entry-len占6bit
encoding=01, strlen <= 16383,entry-len占14bit
encoding=10, strlen>=16384, entry-len占38bit
11 010000代表int32_t,
11 100000代表int64_t,
11 110000代表int24
11 111110代表int8
11 11xxxx:0001 <= xxxx <= 1101(从上面看0000/11110不能用),xxxx就是存储的整数值,虽然实际存储的是1到13,解释成0到12。
散列表-dict
typedef struct dictEntry {
void *key;
union {
void *val;
uint64_t u64;
int64_t s64;
double d;
} v;
struct dictEntry *next;
} dictEntry;
/* This is our hash table structure. Every dictionary has two of this as we
* implement incremental rehashing, for the old to the new table. */
typedef struct dictht {
dictEntry **table;
unsigned long size;
unsigned long sizemask;
unsigned long used;
} dictht;
typedef struct dict {
dictType *type;
void *privdata;
dictht ht[2];//ht[0]为默认使用,resize时将ht[0]中的元素逐一rehash到ht[1],最后ht[1]复制给后台[0]
long rehashidx; /* rehashing not in progress if rehashidx == -1 */
int iterators; /* number of iterators currently running,记录safe iterator个数,如果非0,就暂停rehash*/
} dict;
/* If safe is set to 1 this is a safe iterator, that means, you can call
* dictAdd, dictFind, and other functions against the dictionary even while
* iterating. Otherwise it is a non safe iterator, and only dictNext()
* should be called while iterating. */
typedef struct dictIterator {
dict *d;
long index;
int table, safe;//0非安全,1安全
dictEntry *entry, *nextEntry;
/* unsafe iterator fingerprint for misuse detection. */
long long fingerprint;//是散列表各属性的异或
} dictIterator;
//dictType,散列表实现操作,如key比较/hash函数
typedef struct dictType {
unsigned int (*hashFunction)(const void *key);//hash function
void *(*keyDup)(void *privdata, const void *key);//duplicate key
void *(*valDup)(void *privdata, const void *obj);//duplicate value
int (*keyCompare)(void *privdata, const void *key1, const void *key2);//key compare
void (*keyDestructor)(void *privdata, void *key);
void (*valDestructor)(void *privdata, void *obj);
} dictType;
函数指针挺好的,与面向对象编程中的继承有异曲同工的效果,实现了多态。下图是散列表结构:
redis源码系列-数据结构(adlist/ziplist/dict)的更多相关文章
- Redis 源码简洁剖析 05 - ziplist 压缩列表
ziplist 是什么 Redis 哪些数据结构使用了 ziplist? ziplist 特点 优点 缺点 ziplist 数据结构 ziplist 节点 pre_entry_length encod ...
- Redis源码分析(adlist)
源码版本:redis-4.0.1 源码位置: adlist.h : listNode.list数据结构定义. adlist.c:函数功能实现. 一.adlist简介 Redis中的链表叫adlist( ...
- redis源码之压缩列表ziplist
压缩列表ziplist1.简介连续,无序的数据结构.压缩列表是 Redis 为了节约内存而开发的, 由一系列特殊编码的连续内存块组成的顺序型(sequential)数据结构. 2.组成 属性 类型 长 ...
- Redis 源码简洁剖析 07 - main 函数启动
前言 问题 阶段 1:基本初始化 阶段 2:检查哨兵模式,执行 RDB 或 AOF 检测 阶段 3:运行参数解析 阶段 4:初始化 server 资源管理 初始化数据库 创建事件驱动框架 阶段 5:执 ...
- 曹工说Redis源码(2)-- redis server 启动过程解析及简单c语言基础知识补充
文章导航 Redis源码系列的初衷,是帮助我们更好地理解Redis,更懂Redis,而怎么才能懂,光看是不够的,建议跟着下面的这一篇,把环境搭建起来,后续可以自己阅读源码,或者跟着我这边一起阅读.由于 ...
- 曹工说Redis源码(3)-- redis server 启动过程完整解析(中)
文章导航 Redis源码系列的初衷,是帮助我们更好地理解Redis,更懂Redis,而怎么才能懂,光看是不够的,建议跟着下面的这一篇,把环境搭建起来,后续可以自己阅读源码,或者跟着我这边一起阅读.由于 ...
- Redis 源码简洁剖析 06 - quicklist 和 listpack
quicklist 为什么要设计 quicklist 特点 数据结构 quicklistCreate quicklistDelIndex quicklistDelEntry quicklistInse ...
- 曹工说Redis源码(8)--面试时,redis 内存淘汰总被问,但是总答不好
文章导航 Redis源码系列的初衷,是帮助我们更好地理解Redis,更懂Redis,而怎么才能懂,光看是不够的,建议跟着下面的这一篇,把环境搭建起来,后续可以自己阅读源码,或者跟着我这边一起阅读.由于 ...
- 曹工说Redis源码(4)-- 通过redis server源码来理解 listen 函数中的 backlog 参数
文章导航 Redis源码系列的初衷,是帮助我们更好地理解Redis,更懂Redis,而怎么才能懂,光看是不够的,建议跟着下面的这一篇,把环境搭建起来,后续可以自己阅读源码,或者跟着我这边一起阅读.由于 ...
随机推荐
- iOS多线程 GCD常见用法
Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法. dispatch queue分成以下三种: 1)运行在主线程的Main queue,通过dispat ...
- Spring mvc 中使用ftl引用共通文件出错 FreeMarker template error: Error reading included file "/WEB-INF/ftl/common/errormessage.ftl"
初次接触spring mvc,想做一个小的练习项目,结果在ftl文件中引用其它的共通ftl文件时出错.
- C++回顾map的用法
map<T, T>是C++的STL中存储key-value键值对数据结构的最基础的模板类,相对于multimap可以重复的key值,map的key是非重复的. C++的reference这 ...
- eclipse js 引用跳转
引用 http://stackoverflow.com/questions/24505993/the-resource-is-not-on-the-build-path-of-a-javascript ...
- gulp 配置自动化前端开发
有的人说,grunt已经廉颇老矣,尚能饭否.gulp已经成为了未来的趋势,或许将撼动grunt的地位. 那么就得看看gulp到底优势在哪里,在我最近的使用中发现,我的到了一个结论:“grunt廉颇老矣 ...
- 了解及使用IPV6
1. 什么是 IPv6 IPv6指互联网协议(IP)第6版.目前大家上网主要使用互联网协议第四版,即IPv4. 在全球互联网高度发展的今天,IPv4 地址资源已经枯竭,互联网正在经历从IPv4网络向I ...
- iOS 字符串转son json转字符串
+ (NSString*)dictionaryToJson:(NSDictionary *)dic { NSError *parseError = nil; NSData *jsonDa ...
- sacc scss less
CSS 预处理器技术已经非常的成熟,而且也涌现出了越来越多的 CSS 的预处理器框架.本文向你介绍使用最为普遍的三款 CSS 预处理器框架,分别是 Sass.Less CSS.Stylus. 首先我们 ...
- 使用OFBIZ 时,使用的键入提示。
对商品的键入提示 ,效果如图(当输入关键字时,会提示出相应的数据) 首先要引入相应的插件 页面字段 js方法
- mentohust 你让我如何说你是好呢?
最近换了ubuntu系统结果热了不少的麻烦, 借此机会唠叨一下, 首先是你这个ubuntu16.4 你这个bug 太让人郁闷了吧,或许主要是应该怪我菜,装个看家的软件eclipse.还热除了一堆的麻 ...