Redis 数据结构底层实现:intset、ziplist、skiplist 深度剖析
作者按:本文基于 Redis 7.2 源码进行深度剖析,结合源码实例和实战代码,带您深入理解 Redis 核心数据结构的底层实现原理。
目录
- [前言:为什么需要理解 Redis 底层数据结构](#前言:为什么需要理解 Redis 底层数据结构)
- 一、intset:整数集合的紧凑实现
- 二、ziplist:紧凑列表的极致压缩
- 三、skiplist:跳跃表的平衡艺术
- 四、实战应用与性能对比
- 五、最佳实践与调优建议
- 总结
前言:为什么需要理解 Redis 底层数据结构
Redis 之所以快,不仅因为它是内存数据库,更因为它对数据结构的极致优化。Redis 的作者 antirez 在设计时,针对不同场景选择了最合适的数据结构:
- intset:当集合只包含整数且数量不多时,使用紧凑的整数数组
- ziplist:当列表/哈希的元素较少且较小时,使用连续内存块
- skiplist:在有序集合中提供 O(log n) 的查找性能
这些优化让 Redis 在内存占用和 CPU 性能之间找到了最佳平衡点。本文将深入源码,解析这些数据结构的实现细节。
一、intset:整数集合的紧凑实现
1.1 intset 概述
intset (integer set)是 Redis 用于存储整数值的集合抽象数据结构。它是 Redis 中 SET 数据类型的底层实现之一(当集合满足以下条件时):
-
集合中所有元素都是整数值
-
集合中元素数量不超过 512 个(默认配置)
#// Redis 7.2 源码:src/intset.h
typedef struct intset {
uint32_t encoding; // 编码方式:int16_t/int32_t/int64_t
uint32_t length; // 元素个数
int8_t contents[]; // 柔性数组,实际存储元素
} intset;// Redis 7.2 源码:src/intset.h
#// Redis 7.2 源码:src/intset.h
typedef struct intset {
uint32_t encoding; // 编码方式:int16_t/int32_t/int64_t
uint32_t length; // 元素个数
int8_t contents[]; // 柔性数组,实际存储元素
} intset;typedef struct intset {
#// Redis 7.2 源码:src/intset.h
typedef struct intset {
uint32_t encoding; // 编码方式:int16_t/int32_t/int64_t
uint32_t length; // 元素个数
int8_t contents[]; // 柔性数组,实际存储元素
} intset; uint32_t encoding; // 编码方式:int16_t/int32_t/int64_t
#// Redis 7.2 源码:src/intset.h
typedef struct intset {
uint32_t encoding; // 编码方式:int16_t/int32_t/int64_t
uint32_t length; // 元素个数
int8_t contents[]; // 柔性数组,实际存储元素
} intset; uint32_t length; // 元素个数
#// Redis 7.2 源码:src/intset.h
typedef struct intset {
uint32_t encoding; // 编码方式:int16_t/int32_t/int64_t
uint32_t length; // 元素个数
int8_t contents[]; // 柔性数组,实际存储元素
} intset; int8_t contents[]; // 柔性数组,实际存储元素
#// Redis 7.2 源码:src/intset.h
typedef struct intset {
uint32_t encoding; // 编码方式:int16_t/int32_t/int64_t
uint32_t length; // 元素个数
int8_t contents[]; // 柔性数组,实际存储元素
} intset;} intset;
1.2 intset 的编码升级机制
intset 最大的特点是支持自动升级。当新元素的值超出当前编码范围时,intset 会自动升级到更大的编码类型。
graph TD
A[插入新元素] --> B{新元素值是否超出当前编码范围?}
B -->|否| C[直接插入]
B -->|是| D[升级编码类型]
D --> E[重新分配内存]
E --> F[将旧数据转换为新编码]
F --> G[插入新元素]
style D fill:#f9f,stroke:#333,stroke-width:2px
style E fill:#bbf,stroke:#333,stroke-width:2px
升级过程源码分析(Redis 7.2):
#// src/intset.c - intsetUpgradeAndAdd 函数
static intset *intsetUpgradeAndAdd(intset *is, int64_t value) {
uint8_t curenc = intrev32(if(is->encoding)); // 当前编码
uint8_t newenc = _intsetValueEncoding(value); // 新编码
int length = intrev32(if(is->length));
int prepend = value < 0 ? 1 : 0; // 是否需要向前插入(负数情况)
// 重新分配内存空间
is->encoding = intrev32(newenc);
is = intsetResize(is, intrev32(if(is->length)) + 1);
// 从后向前迁移数据,防止覆盖
while(length--)
_intsetSet(is, length + prepend,
_intsetGetEncoded(is, length, curenc));
// 插入新元素
if (prepend)
_intsetSet(is, 0, value);
else
_intsetSet(is, intrev32(if(is->length)), value);
is->length = intrev32(if(is->length) + 1);
return is;
}// src/intset.c - intsetUpgradeAndAdd 函数
#// src/intset.c - intsetUpgradeAndAdd 函数
static intset *intsetUpgradeAndAdd(intset *is, int64_t value) {
uint8_t curenc = intrev32(if(is->encoding)); // 当前编码
uint8_t newenc = _intsetValueEncoding(value); // 新编码
int length = intrev32(if(is->length));
int prepend = value < 0 ? 1 : 0; // 是否需要向前插入(负数情况)
// 重新分配内存空间
is->encoding = intrev32(newenc);
is = intsetResize(is, intrev32(if(is->length)) + 1);
// 从后向前迁移数据,防止覆盖
while(length--)
_intsetSet(is, length + prepend,
_intsetGetEncoded(is, length, curenc));
// 插入新元素
if (prepend)
_intsetSet(is, 0, value);
else
_intsetSet(is, intrev32(if(is->length)), value);
is->length = intrev32(if(is->length) + 1);
return is;
}static intset *intsetUpgradeAndAdd(intset *is, int64_t value) {
#// src/intset.c - intsetUpgradeAndAdd 函数
static intset *intsetUpgradeAndAdd(intset *is, int64_t value) {
uint8_t curenc = intrev32(if(is->encoding)); // 当前编码
uint8_t newenc = _intsetValueEncoding(value); // 新编码
int length = intrev32(if(is->length));
int prepend = value < 0 ? 1 : 0; // 是否需要向前插入(负数情况)
// 重新分配内存空间
is->encoding = intrev32(newenc);
is = intsetResize(is, intrev32(if(is->length)) + 1);
// 从后向前迁移数据,防止覆盖
while(length--)
_intsetSet(is, length + prepend,
_intsetGetEncoded(is, length, curenc));
// 插入新元素
if (prepend)
_intsetSet(is, 0, value);
else
_intsetSet(is, intrev32(if(is->length)), value);
is->length = intrev32(if(is->length) + 1);
return is;
} uint8_t curenc = intrev32(if(is->encoding)); // 当前编码
#// src/intset.c - intsetUpgradeAndAdd 函数
static intset *intsetUpgradeAndAdd(intset *is, int64_t value) {
uint8_t curenc = intrev32(if(is->encoding)); // 当前编码
uint8_t newenc = _intsetValueEncoding(value); // 新编码
int length = intrev32(if(is->length));
int prepend = value < 0 ? 1 : 0; // 是否需要向前插入(负数情况)
// 重新分配内存空间
is->encoding = intrev32(newenc);
is = intsetResize(is, intrev32(if(is->length)) + 1);
// 从后向前迁移数据,防止覆盖
while(length--)
_intsetSet(is, length + prepend,
_intsetGetEncoded(is, length, curenc));
// 插入新元素
if (prepend)
_intsetSet(is, 0, value);
else
_intsetSet(is, intrev32(if(is->length)), value);
is->length = intrev32(if(is->length) + 1);
return is;
} uint8_t newenc = _intsetValueEncoding(value); // 新编码
#// src/intset.c - intsetUpgradeAndAdd 函数
static intset *intsetUpgradeAndAdd(intset *is, int64_t value) {
uint8_t curenc = intrev32(if(is->encoding)); // 当前编码
uint8_t newenc = _intsetValueEncoding(value); // 新编码
int length = intrev32(if(is->length));
int prepend = value < 0 ? 1 : 0; // 是否需要向前插入(负数情况)
// 重新分配内存空间
is->encoding = intrev32(newenc);
is = intsetResize(is, intrev32(if(is->length)) + 1);
// 从后向前迁移数据,防止覆盖
while(length--)
_intsetSet(is, length + prepend,
_intsetGetEncoded(is, length, curenc));
// 插入新元素
if (prepend)
_intsetSet(is, 0, value);
else
_intsetSet(is, intrev32(if(is->length)), value);
is->length = intrev32(if(is->length) + 1);
return is;
} int length = intrev32(if(is->length));
#// src/intset.c - intsetUpgradeAndAdd 函数
static intset *intsetUpgradeAndAdd(intset *is, int64_t value) {
uint8_t curenc = intrev32(if(is->encoding)); // 当前编码
uint8_t newenc = _intsetValueEncoding(value); // 新编码
int length = intrev32(if(is->length));
int prepend = value < 0 ? 1 : 0; // 是否需要向前插入(负数情况)
// 重新分配内存空间
is->encoding = intrev32(newenc);
is = intsetResize(is, intrev32(if(is->length)) + 1);
// 从后向前迁移数据,防止覆盖
while(length--)
_intsetSet(is, length + prepend,
_intsetGetEncoded(is, length, curenc));
// 插入新元素
if (prepend)
_intsetSet(is, 0, value);
else
_intsetSet(is, intrev32(if(is->length)), value);
is->length = intrev32(if(is->length) + 1);
return is;
} int prepend = value < 0 ? 1 : 0; // 是否需要向前插入(负数情况)
#// src/intset.c - intsetUpgradeAndAdd 函数
static intset *intsetUpgradeAndAdd(intset *is, int64_t value) {
uint8_t curenc = intrev32(if(is->encoding)); // 当前编码
uint8_t newenc = _intsetValueEncoding(value); // 新编码
int length = intrev32(if(is->length));
int prepend = value < 0 ? 1 : 0; // 是否需要向前插入(负数情况)
// 重新分配内存空间
is->encoding = intrev32(newenc);
is = intsetResize(is, intrev32(if(is->length)) + 1);
// 从后向前迁移数据,防止覆盖
while(length--)
_intsetSet(is, length + prepend,
_intsetGetEncoded(is, length, curenc));
// 插入新元素
if (prepend)
_intsetSet(is, 0, value);
else
_intsetSet(is, intrev32(if(is->length)), value);
is->length = intrev32(if(is->length) + 1);
return is;
}
#// src/intset.c - intsetUpgradeAndAdd 函数
static intset *intsetUpgradeAndAdd(intset *is, int64_t value) {
uint8_t curenc = intrev32(if(is->encoding)); // 当前编码
uint8_t newenc = _intsetValueEncoding(value); // 新编码
int length = intrev32(if(is->length));
int prepend = value < 0 ? 1 : 0; // 是否需要向前插入(负数情况)
// 重新分配内存空间
is->encoding = intrev32(newenc);
is = intsetResize(is, intrev32(if(is->length)) + 1);
// 从后向前迁移数据,防止覆盖
while(length--)
_intsetSet(is, length + prepend,
_intsetGetEncoded(is, length, curenc));
// 插入新元素
if (prepend)
_intsetSet(is, 0, value);
else
_intsetSet(is, intrev32(if(is->length)), value);
is->length = intrev32(if(is->length) + 1);
return is;
} // 重新分配内存空间
#// src/intset.c - intsetUpgradeAndAdd 函数
static intset *intsetUpgradeAndAdd(intset *is, int64_t value) {
uint8_t curenc = intrev32(if(is->encoding)); // 当前编码
uint8_t newenc = _intsetValueEncoding(value); // 新编码
int length = intrev32(if(is->length));
int prepend = value < 0 ? 1 : 0; // 是否需要向前插入(负数情况)
// 重新分配内存空间
is->encoding = intrev32(newenc);
is = intsetResize(is, intrev32(if(is->length)) + 1);
// 从后向前迁移数据,防止覆盖
while(length--)
_intsetSet(is, length + prepend,
_intsetGetEncoded(is, length, curenc));
// 插入新元素
if (prepend)
_intsetSet(is, 0, value);
else
_intsetSet(is, intrev32(if(is->length)), value);
is->length = intrev32(if(is->length) + 1);
return is;
} is->encoding = intrev32(newenc);
#// src/intset.c - intsetUpgradeAndAdd 函数
static intset *intsetUpgradeAndAdd(intset *is, int64_t value) {
uint8_t curenc = intrev32(if(is->encoding)); // 当前编码
uint8_t newenc = _intsetValueEncoding(value); // 新编码
int length = intrev32(if(is->length));
int prepend = value < 0 ? 1 : 0; // 是否需要向前插入(负数情况)
// 重新分配内存空间
is->encoding = intrev32(newenc);
is = intsetResize(is, intrev32(if(is->length)) + 1);
// 从后向前迁移数据,防止覆盖
while(length--)
_intsetSet(is, length + prepend,
_intsetGetEncoded(is, length, curenc));
// 插入新元素
if (prepend)
_intsetSet(is, 0, value);
else
_intsetSet(is, intrev32(if(is->length)), value);
is->length = intrev32(if(is->length) + 1);
return is;
} is = intsetResize(is, intrev32(if(is->length)) + 1);
#// src/intset.c - intsetUpgradeAndAdd 函数
static intset *intsetUpgradeAndAdd(intset *is, int64_t value) {
uint8_t curenc = intrev32(if(is->encoding)); // 当前编码
uint8_t newenc = _intsetValueEncoding(value); // 新编码
int length = intrev32(if(is->length));
int prepend = value < 0 ? 1 : 0; // 是否需要向前插入(负数情况)
// 重新分配内存空间
is->encoding = intrev32(newenc);
is = intsetResize(is, intrev32(if(is->length)) + 1);
// 从后向前迁移数据,防止覆盖
while(length--)
_intsetSet(is, length + prepend,
_intsetGetEncoded(is, length, curenc));
// 插入新元素
if (prepend)
_intsetSet(is, 0, value);
else
_intsetSet(is, intrev32(if(is->length)), value);
is->length = intrev32(if(is->length) + 1);
return is;
}
#// src/intset.c - intsetUpgradeAndAdd 函数
static intset *intsetUpgradeAndAdd(intset *is, int64_t value) {
uint8_t curenc = intrev32(if(is->encoding)); // 当前编码
uint8_t newenc = _intsetValueEncoding(value); // 新编码
int length = intrev32(if(is->length));
int prepend = value < 0 ? 1 : 0; // 是否需要向前插入(负数情况)
// 重新分配内存空间
is->encoding = intrev32(newenc);
is = intsetResize(is, intrev32(if(is->length)) + 1);
// 从后向前迁移数据,防止覆盖
while(length--)
_intsetSet(is, length + prepend,
_intsetGetEncoded(is, length, curenc));
// 插入新元素
if (prepend)
_intsetSet(is, 0, value);
else
_intsetSet(is, intrev32(if(is->length)), value);
is->length = intrev32(if(is->length) + 1);
return is;
} // 从后向前迁移数据,防止覆盖
#// src/intset.c - intsetUpgradeAndAdd 函数
static intset *intsetUpgradeAndAdd(intset *is, int64_t value) {
uint8_t curenc = intrev32(if(is->encoding)); // 当前编码
uint8_t newenc = _intsetValueEncoding(value); // 新编码
int length = intrev32(if(is->length));
int prepend = value < 0 ? 1 : 0; // 是否需要向前插入(负数情况)
// 重新分配内存空间
is->encoding = intrev32(newenc);
is = intsetResize(is, intrev32(if(is->length)) + 1);
// 从后向前迁移数据,防止覆盖
while(length--)
_intsetSet(is, length + prepend,
_intsetGetEncoded(is, length, curenc));
// 插入新元素
if (prepend)
_intsetSet(is, 0, value);
else
_intsetSet(is, intrev32(if(is->length)), value);
is->length = intrev32(if(is->length) + 1);
return is;
} while(length--)
#// src/intset.c - intsetUpgradeAndAdd 函数
static intset *intsetUpgradeAndAdd(intset *is, int64_t value) {
uint8_t curenc = intrev32(if(is->encoding)); // 当前编码
uint8_t newenc = _intsetValueEncoding(value); // 新编码
int length = intrev32(if(is->length));
int prepend = value < 0 ? 1 : 0; // 是否需要向前插入(负数情况)
// 重新分配内存空间
is->encoding = intrev32(newenc);
is = intsetResize(is, intrev32(if(is->length)) + 1);
// 从后向前迁移数据,防止覆盖
while(length--)
_intsetSet(is, length + prepend,
_intsetGetEncoded(is, length, curenc));
// 插入新元素
if (prepend)
_intsetSet(is, 0, value);
else
_intsetSet(is, intrev32(if(is->length)), value);
is->length = intrev32(if(is->length) + 1);
return is;
} _intsetSet(is, length + prepend,
#// src/intset.c - intsetUpgradeAndAdd 函数
static intset *intsetUpgradeAndAdd(intset *is, int64_t value) {
uint8_t curenc = intrev32(if(is->encoding)); // 当前编码
uint8_t newenc = _intsetValueEncoding(value); // 新编码
int length = intrev32(if(is->length));
int prepend = value < 0 ? 1 : 0; // 是否需要向前插入(负数情况)
// 重新分配内存空间
is->encoding = intrev32(newenc);
is = intsetResize(is, intrev32(if(is->length)) + 1);
// 从后向前迁移数据,防止覆盖
while(length--)
_intsetSet(is, length + prepend,
_intsetGetEncoded(is, length, curenc));
// 插入新元素
if (prepend)
_intsetSet(is, 0, value);
else
_intsetSet(is, intrev32(if(is->length)), value);
is->length = intrev32(if(is->length) + 1);
return is;
} _intsetGetEncoded(is, length, curenc));
#// src/intset.c - intsetUpgradeAndAdd 函数
static intset *intsetUpgradeAndAdd(intset *is, int64_t value) {
uint8_t curenc = intrev32(if(is->encoding)); // 当前编码
uint8_t newenc = _intsetValueEncoding(value); // 新编码
int length = intrev32(if(is->length));
int prepend = value < 0 ? 1 : 0; // 是否需要向前插入(负数情况)
// 重新分配内存空间
is->encoding = intrev32(newenc);
is = intsetResize(is, intrev32(if(is->length)) + 1);
// 从后向前迁移数据,防止覆盖
while(length--)
_intsetSet(is, length + prepend,
_intsetGetEncoded(is, length, curenc));
// 插入新元素
if (prepend)
_intsetSet(is, 0, value);
else
_intsetSet(is, intrev32(if(is->length)), value);
is->length = intrev32(if(is->length) + 1);
return is;
}
#// src/intset.c - intsetUpgradeAndAdd 函数
static intset *intsetUpgradeAndAdd(intset *is, int64_t value) {
uint8_t curenc = intrev32(if(is->encoding)); // 当前编码
uint8_t newenc = _intsetValueEncoding(value); // 新编码
int length = intrev32(if(is->length));
int prepend = value < 0 ? 1 : 0; // 是否需要向前插入(负数情况)
// 重新分配内存空间
is->encoding = intrev32(newenc);
is = intsetResize(is, intrev32(if(is->length)) + 1);
// 从后向前迁移数据,防止覆盖
while(length--)
_intsetSet(is, length + prepend,
_intsetGetEncoded(is, length, curenc));
// 插入新元素
if (prepend)
_intsetSet(is, 0, value);
else
_intsetSet(is, intrev32(if(is->length)), value);
is->length = intrev32(if(is->length) + 1);
return is;
} // 插入新元素
#// src/intset.c - intsetUpgradeAndAdd 函数
static intset *intsetUpgradeAndAdd(intset *is, int64_t value) {
uint8_t curenc = intrev32(if(is->encoding)); // 当前编码
uint8_t newenc = _intsetValueEncoding(value); // 新编码
int length = intrev32(if(is->length));
int prepend = value < 0 ? 1 : 0; // 是否需要向前插入(负数情况)
// 重新分配内存空间
is->encoding = intrev32(newenc);
is = intsetResize(is, intrev32(if(is->length)) + 1);
// 从后向前迁移数据,防止覆盖
while(length--)
_intsetSet(is, length + prepend,
_intsetGetEncoded(is, length, curenc));
// 插入新元素
if (prepend)
_intsetSet(is, 0, value);
else
_intsetSet(is, intrev32(if(is->length)), value);
is->length = intrev32(if(is->length) + 1);
return is;
} if (prepend)
#// src/intset.c - intsetUpgradeAndAdd 函数
static intset *intsetUpgradeAndAdd(intset *is, int64_t value) {
uint8_t curenc = intrev32(if(is->encoding)); // 当前编码
uint8_t newenc = _intsetValueEncoding(value); // 新编码
int length = intrev32(if(is->length));
int prepend = value < 0 ? 1 : 0; // 是否需要向前插入(负数情况)
// 重新分配内存空间
is->encoding = intrev32(newenc);
is = intsetResize(is, intrev32(if(is->length)) + 1);
// 从后向前迁移数据,防止覆盖
while(length--)
_intsetSet(is, length + prepend,
_intsetGetEncoded(is, length, curenc));
// 插入新元素
if (prepend)
_intsetSet(is, 0, value);
else
_intsetSet(is, intrev32(if(is->length)), value);
is->length = intrev32(if(is->length) + 1);
return is;
} _intsetSet(is, 0, value);
#// src/intset.c - intsetUpgradeAndAdd 函数
static intset *intsetUpgradeAndAdd(intset *is, int64_t value) {
uint8_t curenc = intrev32(if(is->encoding)); // 当前编码
uint8_t newenc = _intsetValueEncoding(value); // 新编码
int length = intrev32(if(is->length));
int prepend = value < 0 ? 1 : 0; // 是否需要向前插入(负数情况)
// 重新分配内存空间
is->encoding = intrev32(newenc);
is = intsetResize(is, intrev32(if(is->length)) + 1);
// 从后向前迁移数据,防止覆盖
while(length--)
_intsetSet(is, length + prepend,
_intsetGetEncoded(is, length, curenc));
// 插入新元素
if (prepend)
_intsetSet(is, 0, value);
else
_intsetSet(is, intrev32(if(is->length)), value);
is->length = intrev32(if(is->length) + 1);
return is;
} else
#// src/intset.c - intsetUpgradeAndAdd 函数
static intset *intsetUpgradeAndAdd(intset *is, int64_t value) {
uint8_t curenc = intrev32(if(is->encoding)); // 当前编码
uint8_t newenc = _intsetValueEncoding(value); // 新编码
int length = intrev32(if(is->length));
int prepend = value < 0 ? 1 : 0; // 是否需要向前插入(负数情况)
// 重新分配内存空间
is->encoding = intrev32(newenc);
is = intsetResize(is, intrev32(if(is->length)) + 1);
// 从后向前迁移数据,防止覆盖
while(length--)
_intsetSet(is, length + prepend,
_intsetGetEncoded(is, length, curenc));
// 插入新元素
if (prepend)
_intsetSet(is, 0, value);
else
_intsetSet(is, intrev32(if(is->length)), value);
is->length = intrev32(if(is->length) + 1);
return is;
} _intsetSet(is, intrev32(if(is->length)), value);
#// src/intset.c - intsetUpgradeAndAdd 函数
static intset *intsetUpgradeAndAdd(intset *is, int64_t value) {
uint8_t curenc = intrev32(if(is->encoding)); // 当前编码
uint8_t newenc = _intsetValueEncoding(value); // 新编码
int length = intrev32(if(is->length));
int prepend = value < 0 ? 1 : 0; // 是否需要向前插入(负数情况)
// 重新分配内存空间
is->encoding = intrev32(newenc);
is = intsetResize(is, intrev32(if(is->length)) + 1);
// 从后向前迁移数据,防止覆盖
while(length--)
_intsetSet(is, length + prepend,
_intsetGetEncoded(is, length, curenc));
// 插入新元素
if (prepend)
_intsetSet(is, 0, value);
else
_intsetSet(is, intrev32(if(is->length)), value);
is->length = intrev32(if(is->length) + 1);
return is;
}
#// src/intset.c - intsetUpgradeAndAdd 函数
static intset *intsetUpgradeAndAdd(intset *is, int64_t value) {
uint8_t curenc = intrev32(if(is->encoding)); // 当前编码
uint8_t newenc = _intsetValueEncoding(value); // 新编码
int length = intrev32(if(is->length));
int prepend = value < 0 ? 1 : 0; // 是否需要向前插入(负数情况)
// 重新分配内存空间
is->encoding = intrev32(newenc);
is = intsetResize(is, intrev32(if(is->length)) + 1);
// 从后向前迁移数据,防止覆盖
while(length--)
_intsetSet(is, length + prepend,
_intsetGetEncoded(is, length, curenc));
// 插入新元素
if (prepend)
_intsetSet(is, 0, value);
else
_intsetSet(is, intrev32(if(is->length)), value);
is->length = intrev32(if(is->length) + 1);
return is;
} is->length = intrev32(if(is->length) + 1);
#// src/intset.c - intsetUpgradeAndAdd 函数
static intset *intsetUpgradeAndAdd(intset *is, int64_t value) {
uint8_t curenc = intrev32(if(is->encoding)); // 当前编码
uint8_t newenc = _intsetValueEncoding(value); // 新编码
int length = intrev32(if(is->length));
int prepend = value < 0 ? 1 : 0; // 是否需要向前插入(负数情况)
// 重新分配内存空间
is->encoding = intrev32(newenc);
is = intsetResize(is, intrev32(if(is->length)) + 1);
// 从后向前迁移数据,防止覆盖
while(length--)
_intsetSet(is, length + prepend,
_intsetGetEncoded(is, length, curenc));
// 插入新元素
if (prepend)
_intsetSet(is, 0, value);
else
_intsetSet(is, intrev32(if(is->length)), value);
is->length = intrev32(if(is->length) + 1);
return is;
} return is;
#// src/intset.c - intsetUpgradeAndAdd 函数
static intset *intsetUpgradeAndAdd(intset *is, int64_t value) {
uint8_t curenc = intrev32(if(is->encoding)); // 当前编码
uint8_t newenc = _intsetValueEncoding(value); // 新编码
int length = intrev32(if(is->length));
int prepend = value < 0 ? 1 : 0; // 是否需要向前插入(负数情况)
// 重新分配内存空间
is->encoding = intrev32(newenc);
is = intsetResize(is, intrev32(if(is->length)) + 1);
// 从后向前迁移数据,防止覆盖
while(length--)
_intsetSet(is, length + prepend,
_intsetGetEncoded(is, length, curenc));
// 插入新元素
if (prepend)
_intsetSet(is, 0, value);
else
_intsetSet(is, intrev32(if(is->length)), value);
is->length = intrev32(if(is->length) + 1);
return is;
}}
1.3 intset 的查找与插入
intset 使用二分查找来定位元素位置,保证 O(log n) 的查找复杂度。
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
}// src/intset.c - intsetFind 函数
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
}uint8_t intsetFind(intset *is, int64_t value) {
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} uint8_t valenc = _intsetValueEncoding(value);
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} // 编码不匹配直接返回 false
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} if (valenc > intrev32(if(is->encoding))) return 0;
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
}
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} // 二分查找
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} return intsetSearch(is, value, NULL);
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
}}
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
}
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
}static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} int min = 0, max = intrev32(if(is->length)) - 1;
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} int64_t cur;
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
}
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} // 空集合处理
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} if (intrev32(if(is->length)) == 0) {
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} if (pos) *pos = 0;
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} return 0;
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} }
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
}
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} // 边界检查
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} if (value > _intsetGet(is, max)) {
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} if (pos) *pos = intrev32(if(is->length));
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} return 0;
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} }
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} if (value < _intsetGet(is, 0)) {
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} if (pos) *pos = 0;
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} return 0;
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} }
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
}
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} // 二分查找主循环
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} while(max >= min) {
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} int mid = (min + max) >> 1; // 无符号右移
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} cur = _intsetGet(is, mid);
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
}
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} if (value > cur) {
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} min = mid + 1;
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} } else if (value < cur) {
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} max = mid - 1;
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} } else {
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} break; // 找到目标值
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} }
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} }
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
}
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} if (pos) *pos = min;
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
} return value == cur;
#// src/intset.c - intsetFind 函数
uint8_t intsetFind(intset *is, int64_t value) {
uint8_t valenc = _intsetValueEncoding(value);
// 编码不匹配直接返回 false
if (valenc > intrev32(if(is->encoding))) return 0;
// 二分查找
return intsetSearch(is, value, NULL);
}
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
int min = 0, max = intrev32(if(is->length)) - 1;
int64_t cur;
// 空集合处理
if (intrev32(if(is->length)) == 0) {
if (pos) *pos = 0;
return 0;
}
// 边界检查
if (value > _intsetGet(is, max)) {
if (pos) *pos = intrev32(if(is->length));
return 0;
}
if (value < _intsetGet(is, 0)) {
if (pos) *pos = 0;
return 0;
}
// 二分查找主循环
while(max >= min) {
int mid = (min + max) >> 1; // 无符号右移
cur = _intsetGet(is, mid);
if (value > cur) {
min = mid + 1;
} else if (value < cur) {
max = mid - 1;
} else {
break; // 找到目标值
}
}
if (pos) *pos = min;
return value == cur;
}}
1.4 intset 的内存布局
下表展示了不同编码下 intset 的内存占用:
| 编码类型 | 单个元素大小 | 存储范围 | 典型应用场景 |
|---|---|---|---|
| INTSET_ENC_INT16 | 2 bytes | -32,768 ~ 32,767 | 小范围整数集合 |
| INTSET_ENC_INT32 | 4 bytes | -2^31 ~ 2^31-1 | 中等范围整数集合 |
| INTSET_ENC_INT64 | 8 bytes | -2^63 ~ 2^63-1 | 大范围整数集合 |
示例代码:创建并操作 intset
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// 模拟 intset 结构
typedef struct {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;
int main() {
// 创建一个 intset: [1, 2, 3]
// 初始编码为 INT16 (假设)
size_t size = sizeof(uint32_t) * 2 + sizeof(int16_t) * 3;
intset *is = malloc(size);
is->encoding = 2; // INT16
is->length = 3;
// 设置元素
int16_t *ptr = (int16_t *)is->contents;
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
printf("intset created: [%d, %d, %d]\n", ptr[0], ptr[1], ptr[2]);
free(is);
return 0;
}#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// 模拟 intset 结构
typedef struct {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;
int main() {
// 创建一个 intset: [1, 2, 3]
// 初始编码为 INT16 (假设)
size_t size = sizeof(uint32_t) * 2 + sizeof(int16_t) * 3;
intset *is = malloc(size);
is->encoding = 2; // INT16
is->length = 3;
// 设置元素
int16_t *ptr = (int16_t *)is->contents;
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
printf("intset created: [%d, %d, %d]\n", ptr[0], ptr[1], ptr[2]);
free(is);
return 0;
}#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// 模拟 intset 结构
typedef struct {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;
int main() {
// 创建一个 intset: [1, 2, 3]
// 初始编码为 INT16 (假设)
size_t size = sizeof(uint32_t) * 2 + sizeof(int16_t) * 3;
intset *is = malloc(size);
is->encoding = 2; // INT16
is->length = 3;
// 设置元素
int16_t *ptr = (int16_t *)is->contents;
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
printf("intset created: [%d, %d, %d]\n", ptr[0], ptr[1], ptr[2]);
free(is);
return 0;
}#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// 模拟 intset 结构
typedef struct {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;
int main() {
// 创建一个 intset: [1, 2, 3]
// 初始编码为 INT16 (假设)
size_t size = sizeof(uint32_t) * 2 + sizeof(int16_t) * 3;
intset *is = malloc(size);
is->encoding = 2; // INT16
is->length = 3;
// 设置元素
int16_t *ptr = (int16_t *)is->contents;
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
printf("intset created: [%d, %d, %d]\n", ptr[0], ptr[1], ptr[2]);
free(is);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// 模拟 intset 结构
typedef struct {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;
int main() {
// 创建一个 intset: [1, 2, 3]
// 初始编码为 INT16 (假设)
size_t size = sizeof(uint32_t) * 2 + sizeof(int16_t) * 3;
intset *is = malloc(size);
is->encoding = 2; // INT16
is->length = 3;
// 设置元素
int16_t *ptr = (int16_t *)is->contents;
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
printf("intset created: [%d, %d, %d]\n", ptr[0], ptr[1], ptr[2]);
free(is);
return 0;
}// 模拟 intset 结构
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// 模拟 intset 结构
typedef struct {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;
int main() {
// 创建一个 intset: [1, 2, 3]
// 初始编码为 INT16 (假设)
size_t size = sizeof(uint32_t) * 2 + sizeof(int16_t) * 3;
intset *is = malloc(size);
is->encoding = 2; // INT16
is->length = 3;
// 设置元素
int16_t *ptr = (int16_t *)is->contents;
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
printf("intset created: [%d, %d, %d]\n", ptr[0], ptr[1], ptr[2]);
free(is);
return 0;
}typedef struct {
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// 模拟 intset 结构
typedef struct {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;
int main() {
// 创建一个 intset: [1, 2, 3]
// 初始编码为 INT16 (假设)
size_t size = sizeof(uint32_t) * 2 + sizeof(int16_t) * 3;
intset *is = malloc(size);
is->encoding = 2; // INT16
is->length = 3;
// 设置元素
int16_t *ptr = (int16_t *)is->contents;
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
printf("intset created: [%d, %d, %d]\n", ptr[0], ptr[1], ptr[2]);
free(is);
return 0;
} uint32_t encoding;
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// 模拟 intset 结构
typedef struct {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;
int main() {
// 创建一个 intset: [1, 2, 3]
// 初始编码为 INT16 (假设)
size_t size = sizeof(uint32_t) * 2 + sizeof(int16_t) * 3;
intset *is = malloc(size);
is->encoding = 2; // INT16
is->length = 3;
// 设置元素
int16_t *ptr = (int16_t *)is->contents;
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
printf("intset created: [%d, %d, %d]\n", ptr[0], ptr[1], ptr[2]);
free(is);
return 0;
} uint32_t length;
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// 模拟 intset 结构
typedef struct {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;
int main() {
// 创建一个 intset: [1, 2, 3]
// 初始编码为 INT16 (假设)
size_t size = sizeof(uint32_t) * 2 + sizeof(int16_t) * 3;
intset *is = malloc(size);
is->encoding = 2; // INT16
is->length = 3;
// 设置元素
int16_t *ptr = (int16_t *)is->contents;
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
printf("intset created: [%d, %d, %d]\n", ptr[0], ptr[1], ptr[2]);
free(is);
return 0;
} int8_t contents[];
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// 模拟 intset 结构
typedef struct {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;
int main() {
// 创建一个 intset: [1, 2, 3]
// 初始编码为 INT16 (假设)
size_t size = sizeof(uint32_t) * 2 + sizeof(int16_t) * 3;
intset *is = malloc(size);
is->encoding = 2; // INT16
is->length = 3;
// 设置元素
int16_t *ptr = (int16_t *)is->contents;
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
printf("intset created: [%d, %d, %d]\n", ptr[0], ptr[1], ptr[2]);
free(is);
return 0;
}} intset;
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// 模拟 intset 结构
typedef struct {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;
int main() {
// 创建一个 intset: [1, 2, 3]
// 初始编码为 INT16 (假设)
size_t size = sizeof(uint32_t) * 2 + sizeof(int16_t) * 3;
intset *is = malloc(size);
is->encoding = 2; // INT16
is->length = 3;
// 设置元素
int16_t *ptr = (int16_t *)is->contents;
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
printf("intset created: [%d, %d, %d]\n", ptr[0], ptr[1], ptr[2]);
free(is);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// 模拟 intset 结构
typedef struct {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;
int main() {
// 创建一个 intset: [1, 2, 3]
// 初始编码为 INT16 (假设)
size_t size = sizeof(uint32_t) * 2 + sizeof(int16_t) * 3;
intset *is = malloc(size);
is->encoding = 2; // INT16
is->length = 3;
// 设置元素
int16_t *ptr = (int16_t *)is->contents;
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
printf("intset created: [%d, %d, %d]\n", ptr[0], ptr[1], ptr[2]);
free(is);
return 0;
}int main() {
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// 模拟 intset 结构
typedef struct {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;
int main() {
// 创建一个 intset: [1, 2, 3]
// 初始编码为 INT16 (假设)
size_t size = sizeof(uint32_t) * 2 + sizeof(int16_t) * 3;
intset *is = malloc(size);
is->encoding = 2; // INT16
is->length = 3;
// 设置元素
int16_t *ptr = (int16_t *)is->contents;
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
printf("intset created: [%d, %d, %d]\n", ptr[0], ptr[1], ptr[2]);
free(is);
return 0;
} // 创建一个 intset: [1, 2, 3]
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// 模拟 intset 结构
typedef struct {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;
int main() {
// 创建一个 intset: [1, 2, 3]
// 初始编码为 INT16 (假设)
size_t size = sizeof(uint32_t) * 2 + sizeof(int16_t) * 3;
intset *is = malloc(size);
is->encoding = 2; // INT16
is->length = 3;
// 设置元素
int16_t *ptr = (int16_t *)is->contents;
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
printf("intset created: [%d, %d, %d]\n", ptr[0], ptr[1], ptr[2]);
free(is);
return 0;
} // 初始编码为 INT16 (假设)
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// 模拟 intset 结构
typedef struct {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;
int main() {
// 创建一个 intset: [1, 2, 3]
// 初始编码为 INT16 (假设)
size_t size = sizeof(uint32_t) * 2 + sizeof(int16_t) * 3;
intset *is = malloc(size);
is->encoding = 2; // INT16
is->length = 3;
// 设置元素
int16_t *ptr = (int16_t *)is->contents;
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
printf("intset created: [%d, %d, %d]\n", ptr[0], ptr[1], ptr[2]);
free(is);
return 0;
} size_t size = sizeof(uint32_t) * 2 + sizeof(int16_t) * 3;
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// 模拟 intset 结构
typedef struct {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;
int main() {
// 创建一个 intset: [1, 2, 3]
// 初始编码为 INT16 (假设)
size_t size = sizeof(uint32_t) * 2 + sizeof(int16_t) * 3;
intset *is = malloc(size);
is->encoding = 2; // INT16
is->length = 3;
// 设置元素
int16_t *ptr = (int16_t *)is->contents;
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
printf("intset created: [%d, %d, %d]\n", ptr[0], ptr[1], ptr[2]);
free(is);
return 0;
} intset *is = malloc(size);
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// 模拟 intset 结构
typedef struct {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;
int main() {
// 创建一个 intset: [1, 2, 3]
// 初始编码为 INT16 (假设)
size_t size = sizeof(uint32_t) * 2 + sizeof(int16_t) * 3;
intset *is = malloc(size);
is->encoding = 2; // INT16
is->length = 3;
// 设置元素
int16_t *ptr = (int16_t *)is->contents;
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
printf("intset created: [%d, %d, %d]\n", ptr[0], ptr[1], ptr[2]);
free(is);
return 0;
} is->encoding = 2; // INT16
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// 模拟 intset 结构
typedef struct {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;
int main() {
// 创建一个 intset: [1, 2, 3]
// 初始编码为 INT16 (假设)
size_t size = sizeof(uint32_t) * 2 + sizeof(int16_t) * 3;
intset *is = malloc(size);
is->encoding = 2; // INT16
is->length = 3;
// 设置元素
int16_t *ptr = (int16_t *)is->contents;
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
printf("intset created: [%d, %d, %d]\n", ptr[0], ptr[1], ptr[2]);
free(is);
return 0;
} is->length = 3;
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// 模拟 intset 结构
typedef struct {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;
int main() {
// 创建一个 intset: [1, 2, 3]
// 初始编码为 INT16 (假设)
size_t size = sizeof(uint32_t) * 2 + sizeof(int16_t) * 3;
intset *is = malloc(size);
is->encoding = 2; // INT16
is->length = 3;
// 设置元素
int16_t *ptr = (int16_t *)is->contents;
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
printf("intset created: [%d, %d, %d]\n", ptr[0], ptr[1], ptr[2]);
free(is);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// 模拟 intset 结构
typedef struct {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;
int main() {
// 创建一个 intset: [1, 2, 3]
// 初始编码为 INT16 (假设)
size_t size = sizeof(uint32_t) * 2 + sizeof(int16_t) * 3;
intset *is = malloc(size);
is->encoding = 2; // INT16
is->length = 3;
// 设置元素
int16_t *ptr = (int16_t *)is->contents;
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
printf("intset created: [%d, %d, %d]\n", ptr[0], ptr[1], ptr[2]);
free(is);
return 0;
} // 设置元素
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// 模拟 intset 结构
typedef struct {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;
int main() {
// 创建一个 intset: [1, 2, 3]
// 初始编码为 INT16 (假设)
size_t size = sizeof(uint32_t) * 2 + sizeof(int16_t) * 3;
intset *is = malloc(size);
is->encoding = 2; // INT16
is->length = 3;
// 设置元素
int16_t *ptr = (int16_t *)is->contents;
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
printf("intset created: [%d, %d, %d]\n", ptr[0], ptr[1], ptr[2]);
free(is);
return 0;
} int16_t *ptr = (int16_t *)is->contents;
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// 模拟 intset 结构
typedef struct {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;
int main() {
// 创建一个 intset: [1, 2, 3]
// 初始编码为 INT16 (假设)
size_t size = sizeof(uint32_t) * 2 + sizeof(int16_t) * 3;
intset *is = malloc(size);
is->encoding = 2; // INT16
is->length = 3;
// 设置元素
int16_t *ptr = (int16_t *)is->contents;
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
printf("intset created: [%d, %d, %d]\n", ptr[0], ptr[1], ptr[2]);
free(is);
return 0;
} ptr[0] = 1;
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// 模拟 intset 结构
typedef struct {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;
int main() {
// 创建一个 intset: [1, 2, 3]
// 初始编码为 INT16 (假设)
size_t size = sizeof(uint32_t) * 2 + sizeof(int16_t) * 3;
intset *is = malloc(size);
is->encoding = 2; // INT16
is->length = 3;
// 设置元素
int16_t *ptr = (int16_t *)is->contents;
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
printf("intset created: [%d, %d, %d]\n", ptr[0], ptr[1], ptr[2]);
free(is);
return 0;
} ptr[1] = 2;
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// 模拟 intset 结构
typedef struct {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;
int main() {
// 创建一个 intset: [1, 2, 3]
// 初始编码为 INT16 (假设)
size_t size = sizeof(uint32_t) * 2 + sizeof(int16_t) * 3;
intset *is = malloc(size);
is->encoding = 2; // INT16
is->length = 3;
// 设置元素
int16_t *ptr = (int16_t *)is->contents;
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
printf("intset created: [%d, %d, %d]\n", ptr[0], ptr[1], ptr[2]);
free(is);
return 0;
} ptr[2] = 3;
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// 模拟 intset 结构
typedef struct {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;
int main() {
// 创建一个 intset: [1, 2, 3]
// 初始编码为 INT16 (假设)
size_t size = sizeof(uint32_t) * 2 + sizeof(int16_t) * 3;
intset *is = malloc(size);
is->encoding = 2; // INT16
is->length = 3;
// 设置元素
int16_t *ptr = (int16_t *)is->contents;
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
printf("intset created: [%d, %d, %d]\n", ptr[0], ptr[1], ptr[2]);
free(is);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// 模拟 intset 结构
typedef struct {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;
int main() {
// 创建一个 intset: [1, 2, 3]
// 初始编码为 INT16 (假设)
size_t size = sizeof(uint32_t) * 2 + sizeof(int16_t) * 3;
intset *is = malloc(size);
is->encoding = 2; // INT16
is->length = 3;
// 设置元素
int16_t *ptr = (int16_t *)is->contents;
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
printf("intset created: [%d, %d, %d]\n", ptr[0], ptr[1], ptr[2]);
free(is);
return 0;
} printf("intset created: [%d, %d, %d]\n", ptr[0], ptr[1], ptr[2]);
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// 模拟 intset 结构
typedef struct {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;
int main() {
// 创建一个 intset: [1, 2, 3]
// 初始编码为 INT16 (假设)
size_t size = sizeof(uint32_t) * 2 + sizeof(int16_t) * 3;
intset *is = malloc(size);
is->encoding = 2; // INT16
is->length = 3;
// 设置元素
int16_t *ptr = (int16_t *)is->contents;
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
printf("intset created: [%d, %d, %d]\n", ptr[0], ptr[1], ptr[2]);
free(is);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// 模拟 intset 结构
typedef struct {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;
int main() {
// 创建一个 intset: [1, 2, 3]
// 初始编码为 INT16 (假设)
size_t size = sizeof(uint32_t) * 2 + sizeof(int16_t) * 3;
intset *is = malloc(size);
is->encoding = 2; // INT16
is->length = 3;
// 设置元素
int16_t *ptr = (int16_t *)is->contents;
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
printf("intset created: [%d, %d, %d]\n", ptr[0], ptr[1], ptr[2]);
free(is);
return 0;
} free(is);
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// 模拟 intset 结构
typedef struct {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;
int main() {
// 创建一个 intset: [1, 2, 3]
// 初始编码为 INT16 (假设)
size_t size = sizeof(uint32_t) * 2 + sizeof(int16_t) * 3;
intset *is = malloc(size);
is->encoding = 2; // INT16
is->length = 3;
// 设置元素
int16_t *ptr = (int16_t *)is->contents;
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
printf("intset created: [%d, %d, %d]\n", ptr[0], ptr[1], ptr[2]);
free(is);
return 0;
} return 0;
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// 模拟 intset 结构
typedef struct {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;
int main() {
// 创建一个 intset: [1, 2, 3]
// 初始编码为 INT16 (假设)
size_t size = sizeof(uint32_t) * 2 + sizeof(int16_t) * 3;
intset *is = malloc(size);
is->encoding = 2; // INT16
is->length = 3;
// 设置元素
int16_t *ptr = (int16_t *)is->contents;
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
printf("intset created: [%d, %d, %d]\n", ptr[0], ptr[1], ptr[2]);
free(is);
return 0;
}}
二、ziplist:紧凑列表的极致压缩
2.1 ziplist 概述
ziplist (zippered list)是 Redis 为了节约内存而开发的顺序存储结构。它将所有数据紧凑地存储在一块连续内存中,避免了指针开销。
应用场景 : - LIST 类型:当列表元素数量 < 512 且所有元素长度 < 64 字节 - HASH 类型:当哈希字段数量 < 512 且所有键值长度 < 64 字节
#// Redis 7.2 源码:src/ziplist.h (简化版)
typedef struct {
uint32_t bytes; // ziplist 占用总字节数
uint32_t tail_offset; // 尾部节点到起始位置的偏移量
uint16_t length; // 节点数量(当超过 2^14-1 时值为 2^14)
uint8_t tail; // 实际存储节点
} ziplist;// Redis 7.2 源码:src/ziplist.h (简化版)
#// Redis 7.2 源码:src/ziplist.h (简化版)
typedef struct {
uint32_t bytes; // ziplist 占用总字节数
uint32_t tail_offset; // 尾部节点到起始位置的偏移量
uint16_t length; // 节点数量(当超过 2^14-1 时值为 2^14)
uint8_t tail; // 实际存储节点
} ziplist;typedef struct {
#// Redis 7.2 源码:src/ziplist.h (简化版)
typedef struct {
uint32_t bytes; // ziplist 占用总字节数
uint32_t tail_offset; // 尾部节点到起始位置的偏移量
uint16_t length; // 节点数量(当超过 2^14-1 时值为 2^14)
uint8_t tail; // 实际存储节点
} ziplist; uint32_t bytes; // ziplist 占用总字节数
#// Redis 7.2 源码:src/ziplist.h (简化版)
typedef struct {
uint32_t bytes; // ziplist 占用总字节数
uint32_t tail_offset; // 尾部节点到起始位置的偏移量
uint16_t length; // 节点数量(当超过 2^14-1 时值为 2^14)
uint8_t tail; // 实际存储节点
} ziplist; uint32_t tail_offset; // 尾部节点到起始位置的偏移量
#// Redis 7.2 源码:src/ziplist.h (简化版)
typedef struct {
uint32_t bytes; // ziplist 占用总字节数
uint32_t tail_offset; // 尾部节点到起始位置的偏移量
uint16_t length; // 节点数量(当超过 2^14-1 时值为 2^14)
uint8_t tail; // 实际存储节点
} ziplist; uint16_t length; // 节点数量(当超过 2^14-1 时值为 2^14)
#// Redis 7.2 源码:src/ziplist.h (简化版)
typedef struct {
uint32_t bytes; // ziplist 占用总字节数
uint32_t tail_offset; // 尾部节点到起始位置的偏移量
uint16_t length; // 节点数量(当超过 2^14-1 时值为 2^14)
uint8_t tail; // 实际存储节点
} ziplist; uint8_t tail; // 实际存储节点
#// Redis 7.2 源码:src/ziplist.h (简化版)
typedef struct {
uint32_t bytes; // ziplist 占用总字节数
uint32_t tail_offset; // 尾部节点到起始位置的偏移量
uint16_t length; // 节点数量(当超过 2^14-1 时值为 2^14)
uint8_t tail; // 实际存储节点
} ziplist;} ziplist;
2.2 ziplist 的内存布局
ziplist 的内存结构如下:
graph LR
A[zlbytes<br/>4字节] --> B[zltail<br/>4字节]
B --> C[zllen<br/>2字节]
C --> D[entry1]
D --> E[entry2]
E --> F[...]
F --> G[entryN]
G --> H[zlend<br/>1字节<br/>值为255]
style A fill:#f96,stroke:#333
style B fill:#6f9,stroke:#333
style C fill:#69f,stroke:#333
style H fill:#f66,stroke:#333
字段说明:
| 字段 | 大小 | 说明 |
|---|---|---|
| zlbytes | 4 bytes | 整个 ziplist 占用内存数 |
| zltail | 4 bytes | 最后一个节点到起始位置的偏移(用于快速遍历) |
| zllen | 2 bytes | 节点数量(最大 2^14-1,超过需遍历计算) |
| entry | 变长 | 具体节点数据 |
| zlend | 1 byte | 结束标记,固定值 255 |
2.3 entry 节点结构
每个 entry 节点由三部分组成:
+----------------+---------------+----------+
| previous_entry | encoding/len | content |
| length (变长) | (变长) | (变长) |
+----------------+---------------+----------+
previous_entry_length:
- 前一个节点的长度,用于从后向前遍历
- 如果前一个节点长度 < 254 字节:用 1 byte 存储
- 如果前一个节点长度 >= 254 字节:用 5 byte 存储(第一个 byte 为 254,后 4 byte 为实际长度)
encoding:编码和长度信息
| 00pppppp | - 1 byte,字符串,长度 <= 63 字节
| 01pppppp | qqqqqqqq - 2 byte,字符串,长度 <= 16383 字节
| 10______ | qqqqqqqq rrrrrrrr ... - 5 byte,字符串,长度 >= 16384 字节
| 11______ | - 整数编码
| 11000000 | - int16_t
| 11010000 | - int32_t
| 11100000 | - int64_t
| 11110000 | - 24 bit 有符号整数
| 11111110 | - 8 bit 有符号整数
| 1111xxxx | - 4 bit 无符号整数 (0-12)
源码示例(Redis 7.2):
#define ZIP_ENTRY_PTR(zl, offset) ((zl) + (offset))
void zipEntry(unsigned char *p, zlentry *e) {
ZIP_DECODE_PREVLEN(p, e->prevrawlensize, e->prevrawlen);
ZIP_DECODE_LENGTH(p + e->prevrawlensize, e->encoding, e->lensize, e->len);
e->headersize = e->prevrawlensize + e->lensize;
e->p = p;
}// src/ziplist.c - ziplistEncodeLength 函数
#define ZIP_ENTRY_PTR(zl, offset) ((zl) + (offset))
void zipEntry(unsigned char *p, zlentry *e) {
ZIP_DECODE_PREVLEN(p, e->prevrawlensize, e->prevrawlen);
ZIP_DECODE_LENGTH(p + e->prevrawlensize, e->encoding, e->lensize, e->len);
e->headersize = e->prevrawlensize + e->lensize;
e->p = p;
}unsigned int ziplistEncodeLength(unsigned char *p, unsigned int len) {
#define ZIP_ENTRY_PTR(zl, offset) ((zl) + (offset))
void zipEntry(unsigned char *p, zlentry *e) {
ZIP_DECODE_PREVLEN(p, e->prevrawlensize, e->prevrawlen);
ZIP_DECODE_LENGTH(p + e->prevrawlensize, e->encoding, e->lensize, e->len);
e->headersize = e->prevrawlensize + e->lensize;
e->p = p;
} if (len < 254) {
#define ZIP_ENTRY_PTR(zl, offset) ((zl) + (offset))
void zipEntry(unsigned char *p, zlentry *e) {
ZIP_DECODE_PREVLEN(p, e->prevrawlensize, e->prevrawlen);
ZIP_DECODE_LENGTH(p + e->prevrawlensize, e->encoding, e->lensize, e->len);
e->headersize = e->prevrawlensize + e->lensize;
e->p = p;
} p[0] = len;
#define ZIP_ENTRY_PTR(zl, offset) ((zl) + (offset))
void zipEntry(unsigned char *p, zlentry *e) {
ZIP_DECODE_PREVLEN(p, e->prevrawlensize, e->prevrawlen);
ZIP_DECODE_LENGTH(p + e->prevrawlensize, e->encoding, e->lensize, e->len);
e->headersize = e->prevrawlensize + e->lensize;
e->p = p;
} return 1;
#define ZIP_ENTRY_PTR(zl, offset) ((zl) + (offset))
void zipEntry(unsigned char *p, zlentry *e) {
ZIP_DECODE_PREVLEN(p, e->prevrawlensize, e->prevrawlen);
ZIP_DECODE_LENGTH(p + e->prevrawlensize, e->encoding, e->lensize, e->len);
e->headersize = e->prevrawlensize + e->lensize;
e->p = p;
} } else {
#define ZIP_ENTRY_PTR(zl, offset) ((zl) + (offset))
void zipEntry(unsigned char *p, zlentry *e) {
ZIP_DECODE_PREVLEN(p, e->prevrawlensize, e->prevrawlen);
ZIP_DECODE_LENGTH(p + e->prevrawlensize, e->encoding, e->lensize, e->len);
e->headersize = e->prevrawlensize + e->lensize;
e->p = p;
} p[0] = 254;
#define ZIP_ENTRY_PTR(zl, offset) ((zl) + (offset))
void zipEntry(unsigned char *p, zlentry *e) {
ZIP_DECODE_PREVLEN(p, e->prevrawlensize, e->prevrawlen);
ZIP_DECODE_LENGTH(p + e->prevrawlensize, e->encoding, e->lensize, e->len);
e->headersize = e->prevrawlensize + e->lensize;
e->p = p;
} memwrite(p+1, len, 4); // 小端序存储
#define ZIP_ENTRY_PTR(zl, offset) ((zl) + (offset))
void zipEntry(unsigned char *p, zlentry *e) {
ZIP_DECODE_PREVLEN(p, e->prevrawlensize, e->prevrawlen);
ZIP_DECODE_LENGTH(p + e->prevrawlensize, e->encoding, e->lensize, e->len);
e->headersize = e->prevrawlensize + e->lensize;
e->p = p;
} return 5;
#define ZIP_ENTRY_PTR(zl, offset) ((zl) + (offset))
void zipEntry(unsigned char *p, zlentry *e) {
ZIP_DECODE_PREVLEN(p, e->prevrawlensize, e->prevrawlen);
ZIP_DECODE_LENGTH(p + e->prevrawlensize, e->encoding, e->lensize, e->len);
e->headersize = e->prevrawlensize + e->lensize;
e->p = p;
} }
#define ZIP_ENTRY_PTR(zl, offset) ((zl) + (offset))
void zipEntry(unsigned char *p, zlentry *e) {
ZIP_DECODE_PREVLEN(p, e->prevrawlensize, e->prevrawlen);
ZIP_DECODE_LENGTH(p + e->prevrawlensize, e->encoding, e->lensize, e->len);
e->headersize = e->prevrawlensize + e->lensize;
e->p = p;
}}
#define ZIP_ENTRY_PTR(zl, offset) ((zl) + (offset))
void zipEntry(unsigned char *p, zlentry *e) {
ZIP_DECODE_PREVLEN(p, e->prevrawlensize, e->prevrawlen);
ZIP_DECODE_LENGTH(p + e->prevrawlensize, e->encoding, e->lensize, e->len);
e->headersize = e->prevrawlensize + e->lensize;
e->p = p;
}
#define ZIP_ENTRY_PTR(zl, offset) ((zl) + (offset))
void zipEntry(unsigned char *p, zlentry *e) {
ZIP_DECODE_PREVLEN(p, e->prevrawlensize, e->prevrawlen);
ZIP_DECODE_LENGTH(p + e->prevrawlensize, e->encoding, e->lensize, e->len);
e->headersize = e->prevrawlensize + e->lensize;
e->p = p;
}// src/ziplist.c - zipEntry 函数
#define ZIP_ENTRY_PTR(zl, offset) ((zl) + (offset))
void zipEntry(unsigned char *p, zlentry *e) {
ZIP_DECODE_PREVLEN(p, e->prevrawlensize, e->prevrawlen);
ZIP_DECODE_LENGTH(p + e->prevrawlensize, e->encoding, e->lensize, e->len);
e->headersize = e->prevrawlensize + e->lensize;
e->p = p;
}#define ZIP_ENTRY_PTR(zl, offset) ((zl) + (offset))
#define ZIP_ENTRY_PTR(zl, offset) ((zl) + (offset))
void zipEntry(unsigned char *p, zlentry *e) {
ZIP_DECODE_PREVLEN(p, e->prevrawlensize, e->prevrawlen);
ZIP_DECODE_LENGTH(p + e->prevrawlensize, e->encoding, e->lensize, e->len);
e->headersize = e->prevrawlensize + e->lensize;
e->p = p;
}
#define ZIP_ENTRY_PTR(zl, offset) ((zl) + (offset))
void zipEntry(unsigned char *p, zlentry *e) {
ZIP_DECODE_PREVLEN(p, e->prevrawlensize, e->prevrawlen);
ZIP_DECODE_LENGTH(p + e->prevrawlensize, e->encoding, e->lensize, e->len);
e->headersize = e->prevrawlensize + e->lensize;
e->p = p;
}void zipEntry(unsigned char *p, zlentry *e) {
#define ZIP_ENTRY_PTR(zl, offset) ((zl) + (offset))
void zipEntry(unsigned char *p, zlentry *e) {
ZIP_DECODE_PREVLEN(p, e->prevrawlensize, e->prevrawlen);
ZIP_DECODE_LENGTH(p + e->prevrawlensize, e->encoding, e->lensize, e->len);
e->headersize = e->prevrawlensize + e->lensize;
e->p = p;
} ZIP_DECODE_PREVLEN(p, e->prevrawlensize, e->prevrawlen);
#define ZIP_ENTRY_PTR(zl, offset) ((zl) + (offset))
void zipEntry(unsigned char *p, zlentry *e) {
ZIP_DECODE_PREVLEN(p, e->prevrawlensize, e->prevrawlen);
ZIP_DECODE_LENGTH(p + e->prevrawlensize, e->encoding, e->lensize, e->len);
e->headersize = e->prevrawlensize + e->lensize;
e->p = p;
} ZIP_DECODE_LENGTH(p + e->prevrawlensize, e->encoding, e->lensize, e->len);
#define ZIP_ENTRY_PTR(zl, offset) ((zl) + (offset))
void zipEntry(unsigned char *p, zlentry *e) {
ZIP_DECODE_PREVLEN(p, e->prevrawlensize, e->prevrawlen);
ZIP_DECODE_LENGTH(p + e->prevrawlensize, e->encoding, e->lensize, e->len);
e->headersize = e->prevrawlensize + e->lensize;
e->p = p;
} e->headersize = e->prevrawlensize + e->lensize;
#define ZIP_ENTRY_PTR(zl, offset) ((zl) + (offset))
void zipEntry(unsigned char *p, zlentry *e) {
ZIP_DECODE_PREVLEN(p, e->prevrawlensize, e->prevrawlen);
ZIP_DECODE_LENGTH(p + e->prevrawlensize, e->encoding, e->lensize, e->len);
e->headersize = e->prevrawlensize + e->lensize;
e->p = p;
} e->p = p;
#define ZIP_ENTRY_PTR(zl, offset) ((zl) + (offset))
void zipEntry(unsigned char *p, zlentry *e) {
ZIP_DECODE_PREVLEN(p, e->prevrawlensize, e->prevrawlen);
ZIP_DECODE_LENGTH(p + e->prevrawlensize, e->encoding, e->lensize, e->len);
e->headersize = e->prevrawlensize + e->lensize;
e->p = p;
}}
2.4 ziplist 的连锁更新问题
ziplist 最大的性能隐患是连锁更新(Cascade Update)。
场景描述: 1. 节点 e1 的长度在 250-253 字节之间(prevlen 用 1 byte 存储) 2. 在 e1 前面插入一个长度 >= 254 字节的新节点 e_new 3. e1 的 prevlen 需要扩展为 5 byte,导致 e1 的总长度增加 4. e2 的 prevlen 也需要扩展...以此类推
graph TD
A[插入大节点 e_new] --> B[e1 的 prevlen: 1→5 bytes]
B --> C[e1 长度增加导致 e2 的 prevlen 扩展]
C --> D[e2 长度增加导致 e3 的 prevlen 扩展]
D --> E[连锁更新直到列表尾部]
style B fill:#f99,stroke:#333,stroke-width:2px
style C fill:#f99,stroke:#333,stroke-width:2px
style D fill:#f99,stroke:#333,stroke-width:2px
最坏情况时间复杂度:O(n^2)
Redis 的优化策略: - 设置阈值:list-max-ziplist-size 和 hash-max-ziplist-entries - 当触发连锁更新且达到阈值时,转换为 linkedlist 或 hashtable
2.5 ziplist 的优缺点对比
| 特性 | ziplist | linkedlist/hashtable |
|---|---|---|
| 内存占用 | 极低(无指针开销) | 较高(每个节点有指针) |
| 插入/删除 | O(n)(需要移动数据) | O(1)(已知位置时) |
| 查找 | O(n)(顺序查找) | O(1)(哈希表) |
| 连锁更新风险 | 有 | 无 |
| 适用场景 | 小数据量、短元素 | 大数据量或长元素 |
三、skiplist:跳跃表的平衡艺术
3.1 skiplist 概述
skiplist (跳跃表)是一种随机化的数据结构,由 William Pugh 在 1990 年提出。它在 Redis 中是 ZSET(有序集合)的底层实现之一(当有序集合元素数量 >= 128 或任一元素长度 >= 64 字节时)。
为什么选择 skiplist 而不是平衡树?
-
实现简单:代码量远小于红黑树
-
范围查询高效:天然支持范围操作
-
内存占用低:不需要存储颜色、父指针等额外信息
-
并发友好:无锁并发实现更容易
#// Redis 7.2 源码:src/server.h (简化版)
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;// Redis 7.2 源码:src/server.h (简化版)
#// Redis 7.2 源码:src/server.h (简化版)
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;typedef struct zskiplistNode {
#// Redis 7.2 源码:src/server.h (简化版)
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; sds ele; // 成员对象
#// Redis 7.2 源码:src/server.h (简化版)
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; double score; // 分值
#// Redis 7.2 源码:src/server.h (简化版)
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; struct zskiplistNode *backward; // 后退指针
#// Redis 7.2 源码:src/server.h (简化版)
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; struct zskiplistLevel {
#// Redis 7.2 源码:src/server.h (简化版)
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; struct zskiplistNode *forward; // 前进指针
#// Redis 7.2 源码:src/server.h (简化版)
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; unsigned long span; // 跨度
#// Redis 7.2 源码:src/server.h (简化版)
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; } level[]; // 层
#// Redis 7.2 源码:src/server.h (简化版)
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;} zskiplistNode;
#// Redis 7.2 源码:src/server.h (简化版)
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;
#// Redis 7.2 源码:src/server.h (简化版)
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;typedef struct zskiplist {
#// Redis 7.2 源码:src/server.h (简化版)
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; struct zskiplistNode *header, *tail; // 头尾节点
#// Redis 7.2 源码:src/server.h (简化版)
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; unsigned long length; // 节点数量
#// Redis 7.2 源码:src/server.h (简化版)
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; int level; // 最大层数
#// Redis 7.2 源码:src/server.h (简化版)
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;} zskiplist;
3.2 skiplist 的结构可视化
graph TD
subgraph "Level 3"
H3[Header] --> NULL3[NULL]
end
subgraph "Level 2"
H2[Header] --> N2_1[Node1<br/>score:1.0]
N2_1 --> N2_3[Node3<br/>score:3.0]
N2_3 --> NULL2[NULL]
end
subgraph "Level 1"
H1[Header] --> N1_1[Node1<br/>score:1.0]
N1_1 --> N1_2[Node2<br/>score:2.0]
N1_2 --> N1_3[Node3<br/>score:3.0]
N1_3 --> N1_4[Node4<br/>score:4.0]
N1_4 --> NULL1[NULL]
end
subgraph "Level 0 (最底层)"
H0[Header] --> N0_1[Node1<br/>score:1.0]
N0_1 --> N0_2[Node2<br/>score:2.0]
N0_2 --> N0_3[Node3<br/>score:3.0]
N0_3 --> N0_4[Node4<br/>score:4.0]
N0_4 --> N0_5[Node5<br/>score:5.0]
N0_5 --> NULL0[NULL]
end
3.3 skiplist 的插入算法
插入过程包括三个步骤: 1. 查找插入位置 :从最高层开始向下查找 2. 随机确定层数 :使用概率算法决定新节点的层数 3. 调整指针:更新前驱节点的 forward 指针
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
}// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
}zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} unsigned int rank[ZSKIPLIST_MAXLEVEL];
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} int i, level;
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
}
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} x = zsl->header;
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
}
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} // 第一步:从高到低查找插入位置
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} for (i = zsl->level-1; i >= 0; i--) {
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
}
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} while (x->level[i].forward &&
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} (x->level[i].forward->score < score ||
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} (x->level[i].forward->score == score &&
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} sdscmp(x->level[i].forward->ele, ele) < 0)))
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} {
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} rank[i] += x->level[i].span;
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} x = x->level[i].forward;
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} }
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} update[i] = x;
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} }
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
}
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} // 第二步:随机计算新节点的层数
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} level = zslRandomLevel();
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} if (level > zsl->level) {
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} for (i = zsl->level; i < level; i++) {
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} rank[i] = 0;
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} update[i] = zsl->header;
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} update[i]->level[i].span = zsl->length;
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} }
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} zsl->level = level;
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} }
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
}
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} // 第三步:创建新节点并调整指针
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} x = zslCreateNode(level, score, ele);
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} for (i = 0; i < level; i++) {
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} x->level[i].forward = update[i]->level[i].forward;
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} update[i]->level[i].forward = x;
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
}
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} update[i]->level[i].span = (rank[0] - rank[i]) + 1;
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} }
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
}
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} // 处理高层节点的 span
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} for (i = level; i < zsl->level; i++) {
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} update[i]->level[i].span++;
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} }
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
}
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} x->backward = (update[0] == zsl->header) ? NULL : update[0];
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} if (x->level[0].forward)
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} x->level[0].forward->backward = x;
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} else
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} zsl->tail = x;
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
}
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} zsl->length++;
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} return x;
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
}}
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
}
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
}// 随机层数算法(幂次定律)
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
}int zslRandomLevel(void) {
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} int level = 1;
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} // 25% 的概率增加一层
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} level += 1;
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
} return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
#// Redis 7.2 源码:src/t_zset.c - zslInsert 函数
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
x = zsl->header;
// 第一步:从高到低查找插入位置
for (i = zsl->level-1; i >= 0; i--) {
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
// 第二步:随机计算新节点的层数
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
// 第三步:创建新节点并调整指针
x = zslCreateNode(level, score, ele);
for (i = 0; i < level; i++) {
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
}
// 处理高层节点的 span
for (i = level; i < zsl->level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tail = x;
zsl->length++;
return x;
}
// 随机层数算法(幂次定律)
int zslRandomLevel(void) {
int level = 1;
// 25% 的概率增加一层
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
}}
3.4 skiplist 的删除算法
graph TD
A[开始删除] --> B[查找待删除节点]
B --> C[记录每层的前驱节点]
C --> D[调整前驱节点的 forward 指针]
D --> E[释放节点内存]
E --> F[更新空层]
F --> G[完成]
style B fill:#6f9,stroke:#333
style D fill:#f96,stroke:#333
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
}// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
}int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} int i;
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
}
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} x = zsl->header;
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
}
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} // 查找待删除节点及其前驱
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} for (i = zsl->level-1; i >= 0; i--) {
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} while (x->level[i].forward &&
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} (x->level[i].forward->score < score ||
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} (x->level[i].forward->score == score &&
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} sdscmp(x->level[i].forward->ele, ele) < 0)))
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} {
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} x = x->level[i].forward;
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} }
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} update[i] = x;
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} }
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
}
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} x = x->level[0].forward;
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} // 从所有层中删除该节点
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} for (i = 0; i < zsl->level; i++) {
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} if (update[i]->level[i].forward == x) {
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} update[i]->level[i].span += x->level[i].span - 1;
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} update[i]->level[i].forward = x->level[i].forward;
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} } else {
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} update[i]->level[i].span -= 1;
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} }
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} }
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
}
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} // 更新后退指针
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} if (x->level[0].forward) {
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} x->level[0].forward->backward = x->backward;
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} } else {
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} zsl->tail = x->backward;
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} }
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
}
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} // 移除空层
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} zsl->level--;
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} }
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
}
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} zsl->length--;
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} if (node) *node = x;
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} zslFreeNode(x);
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} return 1;
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} }
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
} return 0;
#// Redis 7.2 源码:src/t_zset.c - zslDelete 函数
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
x = zsl->header;
// 查找待删除节点及其前驱
for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward &&
(x->level[i].forward->score < score ||
(x->level[i].forward->score == score &&
sdscmp(x->level[i].forward->ele, ele) < 0)))
{
x = x->level[i].forward;
}
update[i] = x;
}
x = x->level[0].forward;
if (x && score == x->score && sdscmp(x->ele, ele) == 0) {
// 从所有层中删除该节点
for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == x) {
update[i]->level[i].span += x->level[i].span - 1;
update[i]->level[i].forward = x->level[i].forward;
} else {
update[i]->level[i].span -= 1;
}
}
// 更新后退指针
if (x->level[0].forward) {
x->level[0].forward->backward = x->backward;
} else {
zsl->tail = x->backward;
}
// 移除空层
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL) {
zsl->level--;
}
zsl->length--;
if (node) *node = x;
zslFreeNode(x);
return 1;
}
return 0;
}}
3.5 skiplist 的性能分析
| 操作 | 平均时间复杂度 | 最坏时间复杂度 | 空间复杂度 |
|---|---|---|---|
| 查找 | O(log n) | O(n) | O(n) |
| 插入 | O(log n) | O(n) | O(n) |
| 删除 | O(log n) | O(n) | O(n) |
| 范围查询 | O(log n + k) | O(n) | - |
k 为范围内元素个数
与其他数据结构对比:
| 数据结构 | 查找 | 插入 | 删除 | 范围查询 | 实现复杂度 |
|---|---|---|---|---|---|
| skiplist | O(log n) | O(log n) | O(log n) | O(log n + k) | 中等 |
| 红黑树 | O(log n) | O(log n) | O(log n) | O(log n + k) | 高 |
| B+树 | O(log n) | O(log n) | O(log n) | O(log n + k) | 高 |
| 哈希表 | O(1) | O(1) | O(1) | 不支持 | 低 |
四、实战应用与性能对比
4.1 实战代码:三种数据结构的使用示例
python
# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance()import redis`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance()import time`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance()import random`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance()`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance()# 连接 Redis`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance()r = redis.Redis(host='localhost', port=6379, db=0)`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance()`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance()# ===== 1. intset 实战 =====`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance()def demo_intset():`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() """演示 intset 的使用"""`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() print("=== intset 演示 ===")`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() `
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() # 清空数据`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() r.delete('myset')`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() `
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() # 插入整数`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() for i in [1, 2, 3, 100, 200]:`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() r.sadd('myset', i)`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() `
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() # 查看底层数据结构`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() encoding = r.object('encoding', 'myset')`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() print(f"编码类型: {encoding}") # 应该是 intset`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() `
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() # 验证元素`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() members = r.smembers('myset')`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() print(f"集合成员: {sorted(members)}")`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance()`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance()# ===== 2. ziplist 实战 =====`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance()def demo_ziplist():`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() """演示 ziplist 的使用"""`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() print("\n=== ziplist 演示 ===")`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() `
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() # 清空数据`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() r.delete('mylist')`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() r.delete('myhash')`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() `
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() # 列表使用 ziplist(元素少且短)`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() r.rpush('mylist', 'a', 'b', 'c', 'd')`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() encoding = r.object('encoding', 'mylist')`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() print(f"列表编码: {encoding}") # 应该是 ziplist`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() `
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() # 哈希使用 ziplist`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() encoding = r.object('encoding', 'myhash')`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() print(f"哈希编码: {encoding}") # 应该是 ziplist`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance()`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance()# ===== 3. skiplist 实战 =====`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance()def demo_skiplist():`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() """演示 skiplist 的使用"""`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() print("\n=== skiplist 演示 ===")`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() `
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() # 清空数据`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() r.delete('leaderboard')`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() `
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() # 插入大量数据触发 skiplist 转换`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() users = [`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() ('user1', 100),`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() ('user2', 200),`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() ('user3', 150),`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() ('user4', 300),`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() ('user5', 250)`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() ]`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() `
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() for user, score in users:`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() r.zadd('leaderboard', {user: score})`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() `
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() # 查看底层数据结构`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() encoding = r.object('encoding', 'leaderboard')`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() print(f"有序集合编码: {encoding}") # 可能是 skiplist`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() `
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() # 范围查询(skiplist 的优势)`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() print("\n排行榜前3名:")`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() for rank, (user, score) in enumerate(top3, 1):`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() print(f" 第{rank}名: {user} - {score}分")`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() `
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() # 查找特定分数范围`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() print("\n分数在 150-250 之间的用户:")`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() for user, score in range_users:`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() print(f" {user}: {score}")`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance()`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance()# ===== 4. 性能对比测试 =====`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance()def benchmark_performance():`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() """性能对比测试"""`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() print("\n=== 性能对比测试 ===")`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() `
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() # intset vs hashset(自动转换)`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() r.delete('set_small')`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() r.delete('set_large')`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() `
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() # 小集合使用 intset`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() start = time.time()`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() for i in range(100):`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() r.sadd('set_small', i)`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() intset_time = time.time() - start`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() `
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() # 大集合使用 hashtable`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() start = time.time()`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() for i in range(10000):`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() r.sadd('set_large', i)`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() hashtable_time = time.time() - start`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() `
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() print(f"小集合编码: {r.object('encoding', 'set_small')}")`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() print(f"大集合编码: {r.object('encoding', 'set_large')}")`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance()`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance()if __name__ == '__main__':`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() demo_intset()`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() demo_ziplist()`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() demo_skiplist()`
`# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# ===== 1. intset 实战 =====
def demo_intset():
"""演示 intset 的使用"""
print("=== intset 演示 ===")
# 清空数据
r.delete('myset')
# 插入整数
for i in [1, 2, 3, 100, 200]:
r.sadd('myset', i)
# 查看底层数据结构
encoding = r.object('encoding', 'myset')
print(f"编码类型: {encoding}") # 应该是 intset
# 验证元素
members = r.smembers('myset')
print(f"集合成员: {sorted(members)}")
# ===== 2. ziplist 实战 =====
def demo_ziplist():
"""演示 ziplist 的使用"""
print("\n=== ziplist 演示 ===")
# 清空数据
r.delete('mylist')
r.delete('myhash')
# 列表使用 ziplist(元素少且短)
r.rpush('mylist', 'a', 'b', 'c', 'd')
encoding = r.object('encoding', 'mylist')
print(f"列表编码: {encoding}") # 应该是 ziplist
# 哈希使用 ziplist
r.hset('myhash', mapping={'name': 'Redis', 'type': 'DB'})
encoding = r.object('encoding', 'myhash')
print(f"哈希编码: {encoding}") # 应该是 ziplist
# ===== 3. skiplist 实战 =====
def demo_skiplist():
"""演示 skiplist 的使用"""
print("\n=== skiplist 演示 ===")
# 清空数据
r.delete('leaderboard')
# 插入大量数据触发 skiplist 转换
users = [
('user1', 100),
('user2', 200),
('user3', 150),
('user4', 300),
('user5', 250)
]
for user, score in users:
r.zadd('leaderboard', {user: score})
# 查看底层数据结构
encoding = r.object('encoding', 'leaderboard')
print(f"有序集合编码: {encoding}") # 可能是 skiplist
# 范围查询(skiplist 的优势)
print("\n排行榜前3名:")
top3 = r.zrevrange('leaderboard', 0, 2, withscores=True)
for rank, (user, score) in enumerate(top3, 1):
print(f" 第{rank}名: {user} - {score}分")
# 查找特定分数范围
print("\n分数在 150-250 之间的用户:")
range_users = r.zrangebyscore('leaderboard', 150, 250, withscores=True)
for user, score in range_users:
print(f" {user}: {score}")
# ===== 4. 性能对比测试 =====
def benchmark_performance():
"""性能对比测试"""
print("\n=== 性能对比测试 ===")
# intset vs hashset(自动转换)
r.delete('set_small')
r.delete('set_large')
# 小集合使用 intset
start = time.time()
for i in range(100):
r.sadd('set_small', i)
intset_time = time.time() - start
# 大集合使用 hashtable
start = time.time()
for i in range(10000):
r.sadd('set_large', i)
hashtable_time = time.time() - start
print(f"intset 插入 100 个元素: {intset_time:.6f} 秒")
print(f"hashtable 插入 10000 个元素: {hashtable_time:.6f} 秒")
print(f"小集合编码: {r.object('encoding', 'set_small')}")
print(f"大集合编码: {r.object('encoding', 'set_large')}")
if __name__ == '__main__':
demo_intset()
demo_ziplist()
demo_skiplist()
benchmark_performance() benchmark_performance()
4.2 性能对比表
| 数据结构 | 适用场景 | 内存占用 | 查找性能 | 插入性能 | 删除性能 |
|---|---|---|---|---|---|
| intset | 纯整数小集合 | 极低 | O(log n) | O(n) | O(n) |
| ziplist | 小列表/小哈希 | 极低 | O(n) | O(n) | O(n) |
| skiplist | 大有序集合 | 中等 | O(log n) | O(log n) | O(log n) |
| hashtable | 大集合/大哈希 | 较高 | O(1) | O(1) | O(1) |
| linkedlist | 大列表 | 较高 | O(n) | O(1) | O(1) |
五、最佳实践与调优建议
5.1 配置参数调优
Redis 提供了多个配置参数来控制数据结构的编码选择:
# 列表相关
list-max-ziplist-size -2 # 默认:每个元素不超过 64 字节
list-compress-depth 0 # 压缩深度,0 表示不压缩
# 哈希相关
hash-max-ziplist-entries 512 # 最大字段数
hash-max-ziplist-value 64 # 最大值长度(字节)
# 集合相关
set-max-intset-entries 512 # 使用 intset 的最大元素数
# 有序集合相关
zset-max-ziplist-entries 128 # 使用 ziplist 的最大元素数
zset-max-ziplist-value 64 # 最大成员长度(字节)# 列表相关
# 列表相关
list-max-ziplist-size -2 # 默认:每个元素不超过 64 字节
list-compress-depth 0 # 压缩深度,0 表示不压缩
# 哈希相关
hash-max-ziplist-entries 512 # 最大字段数
hash-max-ziplist-value 64 # 最大值长度(字节)
# 集合相关
set-max-intset-entries 512 # 使用 intset 的最大元素数
# 有序集合相关
zset-max-ziplist-entries 128 # 使用 ziplist 的最大元素数
zset-max-ziplist-value 64 # 最大成员长度(字节)list-max-ziplist-size -2 # 默认:每个元素不超过 64 字节
# 列表相关
list-max-ziplist-size -2 # 默认:每个元素不超过 64 字节
list-compress-depth 0 # 压缩深度,0 表示不压缩
# 哈希相关
hash-max-ziplist-entries 512 # 最大字段数
hash-max-ziplist-value 64 # 最大值长度(字节)
# 集合相关
set-max-intset-entries 512 # 使用 intset 的最大元素数
# 有序集合相关
zset-max-ziplist-entries 128 # 使用 ziplist 的最大元素数
zset-max-ziplist-value 64 # 最大成员长度(字节)list-compress-depth 0 # 压缩深度,0 表示不压缩
# 列表相关
list-max-ziplist-size -2 # 默认:每个元素不超过 64 字节
list-compress-depth 0 # 压缩深度,0 表示不压缩
# 哈希相关
hash-max-ziplist-entries 512 # 最大字段数
hash-max-ziplist-value 64 # 最大值长度(字节)
# 集合相关
set-max-intset-entries 512 # 使用 intset 的最大元素数
# 有序集合相关
zset-max-ziplist-entries 128 # 使用 ziplist 的最大元素数
zset-max-ziplist-value 64 # 最大成员长度(字节)
# 列表相关
list-max-ziplist-size -2 # 默认:每个元素不超过 64 字节
list-compress-depth 0 # 压缩深度,0 表示不压缩
# 哈希相关
hash-max-ziplist-entries 512 # 最大字段数
hash-max-ziplist-value 64 # 最大值长度(字节)
# 集合相关
set-max-intset-entries 512 # 使用 intset 的最大元素数
# 有序集合相关
zset-max-ziplist-entries 128 # 使用 ziplist 的最大元素数
zset-max-ziplist-value 64 # 最大成员长度(字节)# 哈希相关
# 列表相关
list-max-ziplist-size -2 # 默认:每个元素不超过 64 字节
list-compress-depth 0 # 压缩深度,0 表示不压缩
# 哈希相关
hash-max-ziplist-entries 512 # 最大字段数
hash-max-ziplist-value 64 # 最大值长度(字节)
# 集合相关
set-max-intset-entries 512 # 使用 intset 的最大元素数
# 有序集合相关
zset-max-ziplist-entries 128 # 使用 ziplist 的最大元素数
zset-max-ziplist-value 64 # 最大成员长度(字节)hash-max-ziplist-entries 512 # 最大字段数
# 列表相关
list-max-ziplist-size -2 # 默认:每个元素不超过 64 字节
list-compress-depth 0 # 压缩深度,0 表示不压缩
# 哈希相关
hash-max-ziplist-entries 512 # 最大字段数
hash-max-ziplist-value 64 # 最大值长度(字节)
# 集合相关
set-max-intset-entries 512 # 使用 intset 的最大元素数
# 有序集合相关
zset-max-ziplist-entries 128 # 使用 ziplist 的最大元素数
zset-max-ziplist-value 64 # 最大成员长度(字节)hash-max-ziplist-value 64 # 最大值长度(字节)
# 列表相关
list-max-ziplist-size -2 # 默认:每个元素不超过 64 字节
list-compress-depth 0 # 压缩深度,0 表示不压缩
# 哈希相关
hash-max-ziplist-entries 512 # 最大字段数
hash-max-ziplist-value 64 # 最大值长度(字节)
# 集合相关
set-max-intset-entries 512 # 使用 intset 的最大元素数
# 有序集合相关
zset-max-ziplist-entries 128 # 使用 ziplist 的最大元素数
zset-max-ziplist-value 64 # 最大成员长度(字节)
# 列表相关
list-max-ziplist-size -2 # 默认:每个元素不超过 64 字节
list-compress-depth 0 # 压缩深度,0 表示不压缩
# 哈希相关
hash-max-ziplist-entries 512 # 最大字段数
hash-max-ziplist-value 64 # 最大值长度(字节)
# 集合相关
set-max-intset-entries 512 # 使用 intset 的最大元素数
# 有序集合相关
zset-max-ziplist-entries 128 # 使用 ziplist 的最大元素数
zset-max-ziplist-value 64 # 最大成员长度(字节)# 集合相关
# 列表相关
list-max-ziplist-size -2 # 默认:每个元素不超过 64 字节
list-compress-depth 0 # 压缩深度,0 表示不压缩
# 哈希相关
hash-max-ziplist-entries 512 # 最大字段数
hash-max-ziplist-value 64 # 最大值长度(字节)
# 集合相关
set-max-intset-entries 512 # 使用 intset 的最大元素数
# 有序集合相关
zset-max-ziplist-entries 128 # 使用 ziplist 的最大元素数
zset-max-ziplist-value 64 # 最大成员长度(字节)set-max-intset-entries 512 # 使用 intset 的最大元素数
# 列表相关
list-max-ziplist-size -2 # 默认:每个元素不超过 64 字节
list-compress-depth 0 # 压缩深度,0 表示不压缩
# 哈希相关
hash-max-ziplist-entries 512 # 最大字段数
hash-max-ziplist-value 64 # 最大值长度(字节)
# 集合相关
set-max-intset-entries 512 # 使用 intset 的最大元素数
# 有序集合相关
zset-max-ziplist-entries 128 # 使用 ziplist 的最大元素数
zset-max-ziplist-value 64 # 最大成员长度(字节)
# 列表相关
list-max-ziplist-size -2 # 默认:每个元素不超过 64 字节
list-compress-depth 0 # 压缩深度,0 表示不压缩
# 哈希相关
hash-max-ziplist-entries 512 # 最大字段数
hash-max-ziplist-value 64 # 最大值长度(字节)
# 集合相关
set-max-intset-entries 512 # 使用 intset 的最大元素数
# 有序集合相关
zset-max-ziplist-entries 128 # 使用 ziplist 的最大元素数
zset-max-ziplist-value 64 # 最大成员长度(字节)# 有序集合相关
# 列表相关
list-max-ziplist-size -2 # 默认:每个元素不超过 64 字节
list-compress-depth 0 # 压缩深度,0 表示不压缩
# 哈希相关
hash-max-ziplist-entries 512 # 最大字段数
hash-max-ziplist-value 64 # 最大值长度(字节)
# 集合相关
set-max-intset-entries 512 # 使用 intset 的最大元素数
# 有序集合相关
zset-max-ziplist-entries 128 # 使用 ziplist 的最大元素数
zset-max-ziplist-value 64 # 最大成员长度(字节)zset-max-ziplist-entries 128 # 使用 ziplist 的最大元素数
# 列表相关
list-max-ziplist-size -2 # 默认:每个元素不超过 64 字节
list-compress-depth 0 # 压缩深度,0 表示不压缩
# 哈希相关
hash-max-ziplist-entries 512 # 最大字段数
hash-max-ziplist-value 64 # 最大值长度(字节)
# 集合相关
set-max-intset-entries 512 # 使用 intset 的最大元素数
# 有序集合相关
zset-max-ziplist-entries 128 # 使用 ziplist 的最大元素数
zset-max-ziplist-value 64 # 最大成员长度(字节)zset-max-ziplist-value 64 # 最大成员长度(字节)
5.2 选择建议
graph TD
A[选择数据结构] --> B{数据类型?}
B -->|SET| C{元素都是整数且 < 512?}
C -->|是| D[intset]
C -->|否| E[hashtable]
B -->|LIST| F{元素 < 512 且长度 < 64?}
F -->|是| G[ziplist]
F -->|否| H[linkedlist]
B -->|HASH| I{字段 < 512 且值 < 64?}
I -->|是| J[ziplist]
I -->|否| K[hashtable]
B -->|ZSET| L{元素 < 128 且成员 < 64?}
L -->|是| M[ziplist]
L -->|否| N[skiplist + hashtable]
5.3 监控命令
# 查看对象的编码
OBJECT encoding key
# 查看对象的内存占用
OBJECT memory key
# 查看对象引用数
OBJECT refcount key
# 查看底层信息(使用 MEMORY 命令)
MEMORY usage key
# 查看统计信息
INFO stats# 查看对象的编码
# 查看对象的编码
OBJECT encoding key
# 查看对象的内存占用
OBJECT memory key
# 查看对象引用数
OBJECT refcount key
# 查看底层信息(使用 MEMORY 命令)
MEMORY usage key
# 查看统计信息
INFO statsOBJECT encoding key
# 查看对象的编码
OBJECT encoding key
# 查看对象的内存占用
OBJECT memory key
# 查看对象引用数
OBJECT refcount key
# 查看底层信息(使用 MEMORY 命令)
MEMORY usage key
# 查看统计信息
INFO stats
# 查看对象的编码
OBJECT encoding key
# 查看对象的内存占用
OBJECT memory key
# 查看对象引用数
OBJECT refcount key
# 查看底层信息(使用 MEMORY 命令)
MEMORY usage key
# 查看统计信息
INFO stats# 查看对象的内存占用
# 查看对象的编码
OBJECT encoding key
# 查看对象的内存占用
OBJECT memory key
# 查看对象引用数
OBJECT refcount key
# 查看底层信息(使用 MEMORY 命令)
MEMORY usage key
# 查看统计信息
INFO statsOBJECT memory key
# 查看对象的编码
OBJECT encoding key
# 查看对象的内存占用
OBJECT memory key
# 查看对象引用数
OBJECT refcount key
# 查看底层信息(使用 MEMORY 命令)
MEMORY usage key
# 查看统计信息
INFO stats
# 查看对象的编码
OBJECT encoding key
# 查看对象的内存占用
OBJECT memory key
# 查看对象引用数
OBJECT refcount key
# 查看底层信息(使用 MEMORY 命令)
MEMORY usage key
# 查看统计信息
INFO stats# 查看对象引用数
# 查看对象的编码
OBJECT encoding key
# 查看对象的内存占用
OBJECT memory key
# 查看对象引用数
OBJECT refcount key
# 查看底层信息(使用 MEMORY 命令)
MEMORY usage key
# 查看统计信息
INFO statsOBJECT refcount key
# 查看对象的编码
OBJECT encoding key
# 查看对象的内存占用
OBJECT memory key
# 查看对象引用数
OBJECT refcount key
# 查看底层信息(使用 MEMORY 命令)
MEMORY usage key
# 查看统计信息
INFO stats
# 查看对象的编码
OBJECT encoding key
# 查看对象的内存占用
OBJECT memory key
# 查看对象引用数
OBJECT refcount key
# 查看底层信息(使用 MEMORY 命令)
MEMORY usage key
# 查看统计信息
INFO stats# 查看底层信息(使用 MEMORY 命令)
# 查看对象的编码
OBJECT encoding key
# 查看对象的内存占用
OBJECT memory key
# 查看对象引用数
OBJECT refcount key
# 查看底层信息(使用 MEMORY 命令)
MEMORY usage key
# 查看统计信息
INFO statsMEMORY usage key
# 查看对象的编码
OBJECT encoding key
# 查看对象的内存占用
OBJECT memory key
# 查看对象引用数
OBJECT refcount key
# 查看底层信息(使用 MEMORY 命令)
MEMORY usage key
# 查看统计信息
INFO stats
# 查看对象的编码
OBJECT encoding key
# 查看对象的内存占用
OBJECT memory key
# 查看对象引用数
OBJECT refcount key
# 查看底层信息(使用 MEMORY 命令)
MEMORY usage key
# 查看统计信息
INFO stats# 查看统计信息
# 查看对象的编码
OBJECT encoding key
# 查看对象的内存占用
OBJECT memory key
# 查看对象引用数
OBJECT refcount key
# 查看底层信息(使用 MEMORY 命令)
MEMORY usage key
# 查看统计信息
INFO statsINFO stats
5.4 常见问题与解决方案
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 内存占用过高 | ziplist/skiplist 阈值设置不当 | 调整 *-max-ziplist-* 参数 |
| 性能下降 | ziplist 连锁更新 | 转换为其他数据结构 |
| 范围查询慢 | 使用了 ziplist 而非 skiplist | 增加 zset 元素数量触发转换 |
| CPU 占用高 | 大量数据使用 intset/ziplist | 放宽转换阈值 |
总结
Redis 的强大之处在于它不是简单地将高级数据结构映射到底层实现,而是根据数据特征和访问模式动态选择最优的数据结构。
核心要点回顾:
- intset:通过编码升级和二分查找,在纯整数集合上实现了性能与内存的平衡
- ziplist:通过紧凑存储在内存敏感场景下表现优异,但需警惕连锁更新
- skiplist:以简单实现提供了接近平衡树的性能,特别适合范围查询
最佳实践:
- 小数据量优先使用 ziplist/intset 以节省内存
- 大数据量或需要高性能查询时使用 hashtable/skiplist
- 使用
OBJECT encoding监控数据结构变化 - 根据业务特点调整
*-max-ziplist-*参数
理解这些底层实现,不仅能帮助我们更好地使用 Redis,还能在面对性能问题时快速定位根本原因。
相关阅读: - Redis 官方文档:https://redis.io/docs/data-types/ - Redis 源码:https://github.com/redis/redis/tree/7.2/src - 《Redis 设计与实现》(黄健宏)
标签 :Redis 数据结构 源码解析 intset ziplist skiplist 性能优化