@@ -10799,7 +10799,7 @@ SDS 通过未使用空间解除了字符串长度和底层数组长度之间的
1079910799
1080010800内存重分配涉及复杂的算法,需要执行**系统调用**,是一个比较耗时的操作,SDS 的两种优化策略:
1080110801
10802- * 空间预分配:当 SDS 的 API 进行修改并且需要进行空间扩展时 ,程序不仅会为 SDS 分配修改所必需的空间, 还会为 SDS 分配额外的未使用空间
10802+ * 空间预分配:当 SDS需要进行空间扩展时 ,程序不仅会为 SDS 分配修改所必需的空间, 还会为 SDS 分配额外的未使用空间
1080310803
1080410804 * 对 SDS 修改之后,SDS 的长度(len 属性)小于 1MB,程序分配和 len 属性同样大小的未使用空间,此时 len 和 free 相等
1080510805
@@ -10811,7 +10811,7 @@ SDS 通过未使用空间解除了字符串长度和底层数组长度之间的
1081110811
1081210812 在扩展 SDS 空间前,API 会先检查 free 空间是否足够,如果足够就无需执行内存重分配,所以通过预分配策略,SDS 将连续增长 N 次字符串所需内存的重分配次数从**必定 N 次降低为最多 N 次**
1081310813
10814- * 惰性空间释放:当 SDS 的 API 需要缩短字符串时 ,程序并不立即使用内存重分配来回收缩短后多出来的字节,而是使用 free 属性将这些字节的数量记录起来,并等待将来使用
10814+ * 惰性空间释放:当 SDS 缩短字符串时 ,程序并不立即使用内存重分配来回收缩短后多出来的字节,而是使用 free 属性将这些字节的数量记录起来,并等待将来复用
1081510815
1081610816 SDS 提供了相应的 API 来真正释放 SDS 的未使用空间,所以不用担心空间惰性释放策略造成的内存浪费问题
1081710817
@@ -11035,7 +11035,7 @@ Redis 对 rehash 做了优化,使 rehash 的动作并不是一次性、集中
1103511035* 为 ht[1] 分配空间,此时字典同时持有 ht[0] 和 ht[1] 两个哈希表
1103611036* 在字典中维护了一个索引计数器变量 rehashidx,并将变量的值设为 0,表示 rehash 正式开始
1103711037* 在 rehash 进行期间,每次对字典执行增删改查操作时,程序除了执行指定的操作以外,还会顺带将 ht[0] 哈希表在 rehashidx 索引上的所有键值对 rehash 到 ht[1],rehash 完成之后**将 rehashidx 属性的值增一**
11038- * 随着字典操作的不断执行,最终在某个时间点上 ht[0] 的所有键值对都被 rehash 至 ht[1],这时程序将 rehashidx 属性的值设为 -1,表示 rehash 操作已完成
11038+ * 随着字典操作的不断执行,最终在某个时间点 ht[0] 的所有键值对都被 rehash 至 ht[1],将 rehashidx 属性的值设为 -1
1103911039
1104011040渐进式 rehash 采用**分而治之**的方式,将 rehash 键值对所需的计算工作均摊到对字典的每个添加、删除、查找和更新操作上,从而避免了集中式 rehash 带来的庞大计算量
1104111041
@@ -11110,21 +11110,21 @@ typedef struct zskiplistNode {
1111011110
1111111111前进指针:forward 用于从表头到表尾方向**正序(升序)遍历节点**,遇到 NULL 停止遍历
1111211112
11113- 跨度:span 用于记录两个节点之间的距离,用来**计算排位 (rank)** :
11113+ 跨度:span 用于记录两个节点之间的距离,用来计算排位 (rank):
1111411114
1111511115* 两个节点之间的跨度越大相距的就越远,指向 NULL 的所有前进指针的跨度都为 0
1111611116
11117- * 在查找某个节点的过程中,将沿途访问过的所有层的跨度累计起来,结果就是目标节点在跳跃表中的排位,按照上图所示:
11117+ * 在查找某个节点的过程中,** 将沿途访问过的所有层的跨度累计起来,结果就是目标节点在跳跃表中的排位** ,按照上图所示:
1111811118
1111911119 查找分值为 3.0 的节点,沿途经历的层:查找的过程只经过了一个层,并且层的跨度为 3,所以目标节点在跳跃表中的排位为 3
1112011120
1112111121 查找分值为 2.0 的节点,沿途经历的层:经过了两个跨度为 1 的节点,因此可以计算出目标节点在跳跃表中的排位为 2
1112211122
1112311123后退指针:backward 用于从表尾到表头方向**逆序(降序)遍历节点**
1112411124
11125- 分值:score 属性一个 double 类型的浮点数,跳跃表中的所有节点都**按分值从小到大来排序**
11125+ 分值:score 属性一个 double 类型的浮点数,跳跃表中的所有节点都按分值从小到大来排序
1112611126
11127- 成员对象:obj 属性是一个指针,指向一个 SDS 字符串对象。同一个跳跃表中,各个节点保存的成员对象必须是唯一的 ,但是多个节点保存的分值可以是相同的,分值相同的节点将按照成员对象在字典序中的大小来进行排序(从小到大)
11127+ 成员对象:obj 属性是一个指针,指向一个 SDS 字符串对象。同一个跳跃表中,各个节点保存的**成员对象必须是唯一的** ,但是多个节点保存的分值可以是相同的,分值相同的节点将按照成员对象在字典序中的大小来进行排序(从小到大)
1112811128
1112911129
1113011130
@@ -11169,7 +11169,7 @@ encoding 取值为三种:INTSET_ENC_INT16、INTSET_ENC_INT32、INTSET_ENC_INT6
1116911169
1117011170
1117111171
11172- #### 升级降级
11172+ #### 类型升级
1117311173
1117411174整数集合添加的新元素的类型比集合现有所有元素的类型都要长时,需要先进行升级(upgrade),升级流程:
1117511175
@@ -11243,7 +11243,7 @@ previous_entry_length:以字节为单位记录了压缩列表中前一个节
1124311243
1124411244encoding:记录了节点的 content 属性所保存的数据类型和长度
1124511245
11246- * 长度为 1 字节、2 字节或者 5 字节,值的最高位为 00、01 或者 10 的是字节数组编码,数组的长度由编码除去最高两位之后的其他位记录,下划线 `_` 表示留空,而 `b`、`x` 等变量则代表实际的二进制数据
11246+ * ** 长度为 1 字节、2 字节或者 5 字节** ,值的最高位为 00、01 或者 10 的是字节数组编码,数组的长度由编码除去最高两位之后的其他位记录,下划线 `_` 表示留空,而 `b`、`x` 等变量则代表实际的二进制数据
1124711247
1124811248 
1124911249
@@ -12090,8 +12090,8 @@ set 类型:与 hash 存储结构哈希表完全相同,只是仅存储键不
1209012090
1209112091使用字典加跳跃表的优势:
1209212092
12093- * 字典为有序集合创建了一个从成员到分值的映射 ,用 O(1) 复杂度查找给定成员的分值
12094- * 排序操作使用跳跃表完成,节省每次重新排序带来的时间成本和空间成本
12093+ * 字典为有序集合创建了一个**从成员到分值的映射** ,用 O(1) 复杂度查找给定成员的分值
12094+ * ** 排序操作使用跳跃表完成** ,节省每次重新排序带来的时间成本和空间成本
1209512095
1209612096使用 ziplist 格式存储需要满足以下两个条件:
1209712097
0 commit comments