Java 中的跳跃表 - ConcurrentSkipListMap

数据结构

  1. /**
  2. * Nodes hold keys and values, and are singly linked in sorted
  3. * order, possibly with some intervening marker nodes. The list is
  4. * headed by a header node accessible as head.node. Headers and
  5. * marker nodes have null keys. The val field (but currently not
  6. * the key field) is nulled out upon deletion.
  7. */
  8. static final class Index<K,V> {
  9. final Node<K,V> node; // currently, never detached
  10. final Index<K,V> down;
  11. Index<K,V> right;
  12. Index(Node<K,V> node, Index<K,V> down, Index<K,V> right) {
  13. this.node = node;
  14. this.down = down;
  15. this.right = right;
  16. }
  17. }
  18. /**
  19. * Index nodes represent the levels of the skip list.
  20. */
  21. static final class Node<K,V> {
  22. final K key; // currently, never detached
  23. V val;
  24. Node<K,V> next;
  25. Node(K key, V value, Node<K,V> next) {
  26. this.key = key;
  27. this.val = value;
  28. this.next = next;
  29. }
  30. }
  1. +-+ +-+
  2. |1|---------------->|5|--> NULL
  3. +-+ +-+
  4. | |
  5. v v
  6. +-+ +-+ +-+ +-+
  7. |1|------>|3|-------|5|------>|7|--> NULL
  8. +-+ +-+ +-+ +-+
  9. | | | |
  10. v v v v
  11. +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+
  12. |1|->|2|->|3|->|4|->|5|->|6|->|7|->|8|->|9|-> NULL
  13. +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+
  14. | | | | | | | | |
  15. v v v v v v v v v
  16. NULL NULL NULL NULL NULL NULL NULL NULL NULL

Redis 中的跳跃表

数据结构

zskiplistNoe

  1. typedef struct zskiplistNode {
  2. // 后退指针
  3. struct zskiplistNode *backward;
  4. // 分值
  5. double score;
  6. // 成员对象
  7. robj *obj;
  8. // 层
  9. struct zskiplistLevel {
  10. // 前进指针
  11. struct zskiplistNode *forward;
  12. // 跨度
  13. unsigned int span;
  14. } level[];
  15. } zskiplistNode;
  1. +-------------+
  2. |zskiplistNode|
  3. |-------------|
  4. | level[4] |
  5. +-------------+ |-------------|
  6. |zskiplistNode| | level[3] |
  7. |-------------| |-------------|
  8. | level[2] | | level[2] |
  9. +-------------+ |-------------| |-------------|
  10. |zskiplistNode| | level[1] | | level[1] |
  11. |-------------| |-------------| |-------------|
  12. | level[0] | | level[0] | | level[0] |
  13. |-------------| |-------------| |-------------|
  14. | backward | | backward | | backward |
  15. |-------------| |-------------| |-------------|
  16. | score | | score | | score |
  17. |-------------| |-------------| |-------------|
  18. | obj | | obj | | obj |
  19. +-------------+ +-------------+ +-------------+
  1. +--------+ +--------+
  2. |level[2]|----------------------------------------->|level[2]|--> NULL
  3. |--------| +--------+ |--------| +--------+
  4. |level[1]|--------------->|level[1]|--------------->|level[1]|--------------->|level[1]| --> NULL
  5. |--------| +--------+ |--------| +--------+ |--------| +--------+ |--------| +--------+ +--------+
  6. |level[0]|-->|level[0]|-->|level[0]|-->|level[0]|-->|level[0]|-->|level[0]|-->|level[0]|-->|level[0]|-->|level[0]|--> NULL
  7. |--------| |--------| |--------| |--------| |--------| |--------| |--------| |--------| |--------|
  8. |backward|<--|backward|<--|backward|<--|backward|<--|backward|<--|backward|<--|backward|<--|backward|<--|backward|
  9. |--------| |--------| |--------| |--------| |--------| |--------| |--------| |--------| |--------|
  10. |score=1 | |score=2 | |score=3 | |score=4 | |score=5 | |score=6 | |score=7 | |score=8 | |score=9 |
  11. |--------| |--------| |--------| |--------| |--------| |--------| |--------| |--------| |--------|
  12. |obj1 | |obj2 | |obj3 | |obj4 | |obj5 | |obj6 | |obj7 | |obj8 | |obj9 |
  13. +--------+ +--------+ +--------+ +--------+ +--------+ +--------+ +--------+ +--------+ +--------+

字段描述:

  1. zskiplistNode 的 level 数组可以包含多个元素,每个元素都包含一个指向其它节点的指针;
    1. zskiplistLevel 每层都有一个指向表尾方向的指针(level[i].forward),用于从表头向表尾访问节点;
    2. zskiplistLevel 每层都有一个跨度(level[i].span),用于记录两个节点之间的距离;
  2. zskiplistNode 的 backward 属性用于从表尾向表头方向访问节点,但每次只能后退一个节点;
  3. zskiplistNode 的 score 属性是一个 double 类型的浮点数,跳跃表中的所有节点都按分值的从小到大来排序;
  4. zskiplistNode 的 obj 属性是一个指向字符串对象的指针,字符串对象保存着一个 SDS 值。

    zskiplistlist

    ```c typedef struct zskiplist {

    // 表头节点和表尾节点 struct zskiplistNode header, tail;

    // 表中节点的数量 unsigned long length;

    // 表中层数最大的节点的层数 int level;

} zskiplist;

  1. ```
  2. +---------+
  3. |zskiplist| +--------+ +--------+ +--------+
  4. |---------| |level[1]|-->|level[1]|--------------->|level[1]|--> NULL
  5. | head |------>|--------| |--------| +--------+ |--------|
  6. |---------| |level[0]|-->|level[0]|-->|level[0]|-->|level[0]|--> NULL
  7. | tail |---+ +--------+ |--------| |--------| |--------|
  8. |---------| | NULL <--|backward|<--|backward|<--|backward|
  9. | level | | |--------| |--------| |--------|
  10. |---------| | |score=1 | |score=2 | |score=3 |
  11. | length | | |--------| |--------| |--------|
  12. +---------+ | |obj1 | |obj2 | |obj3 |
  13. | +--------+ +--------+ +--------+
  14. | ^
  15. +-----------------------------------------------+