简单动态字符串(SDS)
SDS定义:
struct sdshdr{
int len ;//记录SDS字符串的长度
int free;//记录buf数组中未使用的数量
char buf[];//用于保存字符串
}
拼接字符串时,如果数组长度不够,会进行内存的重新分配,为了减少内存的重新分配引起的系统开销,会进行空间预分配。SDS的长度小于1M时,会分配和len等长大小的未使用空间,长度大于1M时,每次多分配1MB的未使用空间。
链表:
链表节点的定义:
typedef stuct listNode{
stuct listNode *prev;//前置节点
struct listNode *next;//后置节点
void *vlaue;//节点的值
}
链表:
typedef struct list {
// 头节点
listNode *head;
// 尾节点
listNode *tail;
// 链表中的节点数
unsigned int len;
// 节点值复制函数
void *(*dup) (void *ptr);
// 节点值释放函数
void (*free) (void *ptr);
// 节点值对比函数
int (*match) (void *ptr, void *key);
} list;
字典:可称为符号表、关联数组或者映射(map),一种用于保存键值对的抽象数据结构。
dictEntry **table;//哈希表数组
unsigned long size;//哈希表大小
unsigned long sizemask;//哈希表大小掩码,用于计算索引值,总是等于size-1
unsigned long used;//hash表已有节点的数量
}

哈希表节点:
typedef struct dictEntry{
void *key;//键
//值
union{
void *val;
uint64_t u64;
int64_t s64;
} v
srtuct dictEntry *next;//指向下个哈希表节点,形成链表
}
字典结构体
dictType *type;//类型特定函数
void *privdata;//私有数据
dictht ht[2];//哈希表
int trehashidx;//rehash索引,当rehash不在进行时为-1
type属性是一个指向dictType结构的指针,每个dictType结构保存了一簇用于特定类型键值对的函数,redis为不同的字典设置不同的类型特定函数
privdata 属性保存了需要传给那些类型特定函数的可选参数。
ht属性包含两个项的数组,数组中的每一项都是一个dictht的hash表,一般情况下,字典只使用ht[0]哈希表,ht[1]哈希表只会在ht[0]哈希表进行rehash时使用

随着操作的不断执行,哈希表保存的键值对会逐渐的增加或者减少,为了让哈希表的负载因子维持在合理的范围,需要对hash表
的大小进行相应的扩展或者收缩,可以通过rehash操作来完成
1.为字段ht[1]哈希表分配空间,这个哈希表的空间大小取决于要执行的操作,以及ht[0]包含的键值对数量
2.将保存在ht[0]中的所有键值对rehash到ht[1]上
3.全部迁移完成之后,将ht[1]设置为ht[0],并在ht[1]新创建一个空白hash表
整数集合:
typedef struct intset{
//编码方式
uint32_t encoding;
//集合包含的元素数量
uint32_t length;
//保存元素的数组
int8_t contents[];
} intset
编码方式分为16位,32位,64位三种,当添加的数据大于所选编码方式的范围时,整数集合编码方式自动扩充。
列表:
每个entry的结构,其中pevious_entry_length记录前一个节点的长度,encoding字段保存节点的类型和长度
content代表节点的内容,保存pevious_entry_length可以快速的通过指针遍历列表
当插入某个节点时,由于pevious_entry_length属性的存在可能会引发连锁更新。
对象:
Redis使用对象表示数据库中的键和值,创建一个键值对时,会创建两个对象,redis的对象由一个
redisObject结构表示
typedef struct redisObject{
//类型,5种属性的其中一个
unsigned type:4
//编码
unsigned encoding:4
//指向底层实现数据结构的指针
void *ptr
} robj
字符串对象的结构: