Redis的Set链表数据结构
链表节点 -> 设计字段
typedef struct listNode {
// 前置节点
struct listNode *prev;
// 后置节点
struct listNode *next;
// 节点的值
void *value;
} listNode;
但是你以为set就这样组成吗,那简直大错特错了!
typedef struct list {
// 表头节点
listNode *head;
// 表尾节点
listNode *tail;
// 链表所包含的节点数量
unsigned long len;
// 节点值复制函数
void *(*dup)(void *ptr);
// 节点值释放函数
void (*free)(void *ptr);
// 节点值对比函数
int (*match)(void *ptr, void *key);
} list;
一个 list
结构和三个 listNode
结构组成的链
特点
- 双端: 链表节点带有
prev
和next
指针, 获取某个节点的前置节点和后置节点的复杂度都是 O(1) 。 - 无环: 表头节点的
prev
指针和表尾节点的next
指针都指向NULL
, 对链表的访问以NULL
为终点。 - 带表头指针和表尾指针: 通过
list
结构的head
指针和tail
指针, 程序获取链表的表头节点和表尾节点的复杂度为 O(1) 。 - 带链表长度计数器: 程序使用
list
结构的len
属性来对list
持有的链表节点进行计数, 程序获取链表中节点数量的复杂度为 O(1)。 - 多态: 链表节点使用
void*
指针来保存节点值, 并且可以通过list
结构的dup
、free
、match
三个属性为节点值设置类型特定函数, 所以链表可以用于保存各种不同类型的值。
链表被广泛用于实现 Redis 的各种功能, 比如列表键, 发布与订阅, 慢查询, 监视器, 等等。
Set使用场景
Set类型特点就是唯一,依靠唯一性,我们可以实现推荐好友,安全提示等功能。
1. 推荐好友
每个人的好友都可以是一个Set集合,通过SINTER可以计算出两个KEY之间的交集,如果交集大于某个阈值,就可以作为可能认识的人或者好友进行推荐,当然前提是两个人并非好友。
由于是陌生人推荐,因此需要计算这个人和其他非好友的所有人之间的好友交集,如果保证性能也是需要考虑的一个问题。
2. 安全提示
这个主要用于群聊拉人的时候,新人入群的提示,如果被拉进群聊的新人除了拉取人之外,和其他群友都不是好友关系或者跟不超过N个人是好友关系的时候,就可以给一个安全提示。此时用到的是SISMEMBER。
进群聊的新人除了拉取人之外,和其他群友都不是好友关系或者跟不超过N个人是好友关系的时候,就可以给一个安全提示。此时用到的是SISMEMBER。