Redis跳表
深入理解Redis跳跃表的基本实现和特性
https://blog.csdn.net/qq_38545713/article/details/105439688
核心思想是“剪枝”
zset
有序列表:支持随机插入和删除,唯一且有序。
- 单链表:查找O(N)
- 跳表: 加多级索引实现二分查找,查找、插入、删除O(logN)
- 每个跳跃表节点的层高都是 1 至 32 之间的随机数。
动态更新
当不停往跳表中插入数据时,如果不更新索引,就可能出现某 2 个索引结点之间数据非常多的情况。极端情况下,跳表会退化成单链表。
跳表是通过随机函数来维护前面提到的 平衡性。 往跳表中插入数据时,可以选择同时将这个数据插入到第几级索引中,比如随机函数生成了值 K,那我们就将这个结点添加到第一级到第 K 级这 K 级索引中。
redis string
为了避免为字符串频繁的申请或释放空间,redis中使用了空间预分配、惰性空间释放这两种方式来优化。
- 空间预分配:当字符串长度增加,buf长度已经不满足要求的时候,如果字符串长度在1M以下,以2倍的速度扩容。假如当前buf长度为10,字符串长度为13,那么会分配26+1字节长度,的buf数组,若字符串长度在1M以上,那么每次会预分配1M的空间,此时buf实际长度为 字符串长度+1M+1byte(空字符)。通过这种方式减少频繁为字符串分配空间的次数。同时会修改len和free的长度。
- 惰性空间回收:当字符串长度变小时,并不真正的将空间回收,而是修改free和len字段。通过惰性空间释放策略, SDS 避免了缩短字符串时所需的内存重分配操作, 并为将来可能有的增长操作提供了优化。
struct sdshdr {
int len;
int free;
char buf[];
}