1.SDS
struct sdshdr
{
int len ;
int alloc;
int flag;
char buf[];
}
2. link list
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;
3.dict
typedef struct dictEntry {
void *key;
union {
void *val;
uint64_t u64;
int64_t s64;
double d;
} v;
struct dictEntry *next;
} dictEntry;
typedef struct dictType {
uint64_t (*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 *key);
void (*valDestructor)(void *privdata, void *obj);
} dictType;
/* 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];
long rehashidx; /* rehashing not in progress if rehashidx == -1 */
unsigned long iterators; /* number of iterators currently running */
} dict;
值得说的是,在dict里边有两个ht,redis的许多如扩展和收缩都和这个ht[2]有关系,甚至和后边叙述的策略也有关系;
ht的类似格式如以下简图所示;
privatedata是设计是为了使用dict的api函数向里边传参数的。
4.stip list
这个跳跃表是一个很有意思的结构,牺牲空间存储下一层的指针使更快的搜索到下一层,说到层次,在跳跃表产生的时候会随机分配层次。他的效率和平衡树差不多,因此有好多项目都用到了跳跃表,但redis中似乎只有有序排序结构用到了跳跃表。
/* ZSETs use a specialized version of Skiplists */
typedef struct zskiplistNode {
sds ele;
double score;
struct zskiplistNode *backward;
struct zskiplistLevel {
struct zskiplistNode *forward;
unsigned long span;
} level[];
} zskiplistNode;
typedef struct zskiplist {
struct zskiplistNode *header, *tail;
unsigned long length;
int level;
} zskiplist;
5.整数集合(intset)
整数集合为redis为了保存整数值而抽象出整数集合结构
typedef struct intset {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;
根据编码方式的不同,contents也有着不同的大小,如可以是short、int、long、long long等
升级和降级的过程比较简单就不叙述了
6.压缩列表(ziplist)
为了节省redis的内存空间而设计的。
7.对象
typedef struct redisObject {
unsigned type:4;
unsigned encoding:4;
unsigned lru:LRU_BITS; /* LRU time (relative to global lru_clock) or
* LFU data (least significant 8 bits frequency
* and most significant 16 bits access time). */
int refcount;
void *ptr;
} robj;
每生成一个redis对象就会生成两个robj。一个是key一个是value。
type可以是
SET GET APPEND INCRBFLOAT INCRBY DECRBY STRLEN SETRANGE GETRANGE 等是操作列表对象的
HSET HGET HEXISTS HDEL HLEN HGETALL 等对应的是操作hash对象的,即链表,数据原型是ziplist或者linklist
SADD SCARD(返回包含元素的数量) SISMEMBER SMEMBERS SRANDMEMBER STOP SREM等是操作集合对象的,原型是skiplist或ziplist intset或hashtable
ZADD ZCARD zcount ZRANGE ZREVRANGE ZRANK ZREVRANK ZREM ZSCORE等是操作有序集合的,原型是字典和跳跃表
对象类型检查和命令多态
内容回收 类似于智能指针 引数删除
对象共享set a 100 set b 100 两个对象会被共享
对象空转时长;redisobject/lru参数有关系,不使用lru就会变大,活跃lru就会变为0,后期的删除惰性策略是根据这里来的;