作者:taobao
链接:https://www.jianshu.com/p/bda05077ca88
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
数据类型
- string
- hash
- list
- set
- zset
数据结构
string
string其实是一个数组,但是使用了sds(simple dynamic string)
struct sdshdr {
int len; //buf中已占用空间的长度
int free; //buf中剩余空间的长度
char buf[]; //数据空间
}
hash
hash底层用的是字典
typedef struct dictht {
dictEntry ** table; //哈希表数组
unsigned long size; //哈希表大小
unsigned long sizemask //哈希表大小掩码,用于计算索引值 总是等于 size - 1
unsigned logn used; //该哈希表已有节点的数量
}
typedef struct dictEntry{
void *key; //键
union { //不同键对饮的值得类型可能不同,使用union来处理这个问题
void *val;
uint64_tu64;
int64_ts64;
}
struct dictEntry *next;
}
list
双向链表
typedef struct listNode {
struct listNode * pre; //前置节点
struct listNode * next; //后置节点
void * value; //节点的值
}
typedef struct list {
listNode *head; //表头节点
listNode tail; //表尾节点
unsigned long len; //链表所包含的节点数量
void (dup) (void ptr); //节点值赋值函数 这里有问题
void (free) (void ptr); //节点值释放函数
int (match) (void *ptr, void *key) //节点值对比函数
}
zset
1:跳表
2:整数集合(intset)是集合键的底层实现之一: 当一个集合只包含整数值元素, 并且这个集合的元素数量不多时, Redis 就会使用整数集合作为集合键的底层实现。
3:数据少是,使用ziplist(压缩列表),占用连续内存,每项元素都是(数据+score)的方式连续存储,按照score从小到大排序。ziplist为了节省内存,每个元素占用的空间可以不同,对于大数据(long long),就多用一些字节存储,而对于小的数据(short),就少用一些字节来存储。因此查找的时候需要按顺序遍历。ziplist省内存但是查找效率低。
// 跳跃表
typedef struct zskiplistNode {
//层
struct zskiplistLevel {
//前进指针
struct zskiplistNode * forward;
//跨度
unsigned int span;
} level[];
//后退指针
struct zskiplistNode * backward;
//分值
double score;
//成员对象
robj *obj;
} zskiplistNode
// 整数集
typedef struct intset {
//编码方式
uint32_t encoding;
//集合包含的元素数量
uint32_t length;
//保存元素的数组
int8_t contents[];
}
set
字典 或 整数集