Redis的有序集合数据结构
1)压缩列表
2)字典+跳表
字典存储value->score的映射,跳表存储score->value的映射,跳表中key是score,那value可能会有多个,怎么排序?Redis默认是根据value的字典序排序
引入跳表的原因是Redis要实现根据score的范围查询所有value
1)插入过程
1、先查询字典,如果value已经存在,保存旧score,更新score
2、如果score没有变化,直接返回,否则操作跳表
3、根据旧score查询跳表,删除指定的value,
4、重新插入新的score->value映射
2)删除过程
1、先查询字典,如果value不存在,直接返回,
否则从字典中删除该value;
2、根据score查询跳表,删除指定的value;
3、回收value和score的内存,字典和跳表
维护的是同一个value和同一个score
3)根据value查询对应的score
查询字典
4)查询score在某个范围的所有value
查询跳表
5)根据score从小到大排序所有value
查询跳表
Java代码
public class Zset {
//value->score
private HashMap<String, Double> dict;
//score->value 可能存在多个score相同的不同value
private SkipListMap sl;
public Zset() {
dict = new HashMap<>();
sl = new SkipListMap();
}
public static class SkipListMap {
private static final double PROBABILITY = 0.5; // < 0.5 继续做,>=0.5 停
private SkipListNode head;
private int size;
private int maxLevel;
public SkipListMap() {
head = new SkipListNode(null, null);
head.nextNodes.add(null);
size = 0;
maxLevel = 0;
}
}
private static class SkipListNode {
public Double key;
public String val;
public ArrayList<SkipListNode> nextNodes;
public SkipListNode(Double k, String v) {
key = k;
val = v;
nextNodes = new ArrayList<>();
}
}
}