Redis跳跃列表究竟怎么跳( 三 )


void zslDeleteNode(zskiplist *zsl, zskiplistNode *x, zskiplistNode **update) { int i; 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--;}复制代码删除过程的代码也比较容易理解,首先按照搜索路径,从下到上,逐层更新前向指针 。然后更新回溯指针 。如果删除节点的层数是最大的层数,那么还需要更新skiplist的level字段 。最后长度减一 。
总结
skiplist是节点有层级的list,节点的查找过程可以跨越多个节点,从而节省查找时间 。
Redis的zset由hash字典和skiplist组成,hash字典负责数据到分数的对应,skiplist负责根据分数查找数据 。
Redis中skiplist插入和删除操作都依赖于搜索路径,更新操作是先删除再插入 。




推荐阅读