04 关于 adlist
Posted 蓝风9
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了04 关于 adlist相关的知识,希望对你有一定的参考价值。
前言
关于 redis 的数据结构 adlist
相关介绍主要围绕着如下测试用例, 来看看 adlist 的存储, 以及 相关的 api
本文的 adlist 相关代码 拷贝自 redis-6.2.0
代码来自于 https://redis.io/
adlist 这个数据结构映射到 jdk 这边 类似于 java.util.LinkedList
很多操作 也是链表的基础操作, 呵呵 相当于又温习了一遍
测试用例
//
// Created by Jerry.X.He on 2021/2/25.
//
#include<iostream>
#include "../libs/sds.h"
#include "../libs/adlist.h"
using namespace std;
int main(int argc, char **argv) {
sds head = sdsnew("head");
sds tail = sdsnew("tail");
// listCreate
list *list = listCreate();
// listAddNodeHead/Tail
listAddNodeHead(list, head);
listAddNodeTail(list, tail);
// listIndex
listNode *secondEle = listIndex(list, 1);
// listSearchKey
listNode *searchedEle = listSearchKey(list, tail);
// listGetIterator/listNext/listReleaseIterator
// to head
listIter *toTailIte = listGetIterator(list, AL_START_HEAD);
listNode *toTailNode = NULL;
while ((toTailNode = listNext(toTailIte)) != NULL) {
cout << (sds) (toTailNode->value) << endl;
}
cout << "--------" << endl;
// to tail
listIter *toHeadIte = listGetIterator(list, AL_START_TAIL);
listNode *toHeadNode = NULL;
while ((toHeadNode = listNext(toHeadIte)) != NULL) {
cout << (sds) (toHeadNode->value) << endl;
}
listReleaseIterator(toHeadIte);
cout << "--------" << endl;
// listRewind/listRewindTail
listRewind(list, toTailIte);
toTailNode = NULL;
while ((toTailNode = listNext(toTailIte)) != NULL) {
cout << (sds) (toTailNode->value) << endl;
}
cout << "--------" << endl;
// listRotate
listRotateTailToHead(list);
listRewind(list, toTailIte);
toTailNode = NULL;
while ((toTailNode = listNext(toTailIte)) != NULL) {
cout << (sds) (toTailNode->value) << endl;
}
cout << "--------" << endl;
// listDelNode
listDelNode(list, secondEle);
int x = 0;
}
数据结构
普通的双向链表
listCreate
创建了一个 list 的对象, 并初始化
我们来 inspect 一下 list
所有的字段都是 NULL/0, 因此 全部都是 0x00
(lldb) x 0x7fa05f402be0 -c 0x30
0x7fa05f402be0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x7fa05f402bf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x7fa05f402c00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
listAddNodeHead
新建节点, 并初始化
添加到链表头, 更新 prev, next
更新 list 长度
inspect 一下 list, 这里已经是 struct 和 struct 的相关关联, 所以直接查看 变量是可以很清晰的看到链表的相关数据
这里 list 的 head, tail 均指向 0x7fa05f4023c0, 这个节点的 prev, next 均为 NULL, value 为 "head"
list 的长度为 1
listAddNodeTail
新建节点, 并初始化
添加到链表尾, 更新 prev, next
更新 list 长度
inspect 一下 list
这里 list 的 head 指向的是 0x7fa05f4023c0, tail 均指向 0x7fa05f400450
节点 0x7fa05f4023c0 的下一个节点是 节点 0x7fa05f400450
0x7fa05f4023c0 的数据显然就是上面的 "head"
0x7fa05f400450 的数据这里为 "tail"
list 的长度为 2
此时的 list 中的元素为 "head" -> "tail"
listIndex
迭代 n 次获取, 对应的 listNode
n 约定正数从链表头迭代, 负数向链表尾迭代
可以看到这里的 索引为 1 的元素是 "tail"
listSearchKey
从 list 头迭代到尾部, 比较 listNode 是否匹配给定的 key
返回匹配的 entry
listGetIterator
创建一个迭代器
如果是 从链表头迭代, 初始化 ite->next 为 head, 设置 direction
如果是 从链表尾迭代, 初始化 ite->next 为 tail, 设置 direction
listNext
记录 ite->next, 作为结果 result
根据方向 更新 ite->next
返回 result
listReleaseIterator
listRewind/listRewindTail
重置 给定的 iterator 的 next 和 direction
listRotateTailToHead/listRotateHeadToTail
一套组合操作
listRotateTailToHead : 将表尾元素移动到表头
listRotateHeadToTail : 将表头元素移动到表尾
listDelNode
移除给定的节点, 更新 next.prev, prev.next, list.head, list.tail 等等
并释放当前节点, 更新 list.len
完
以上是关于04 关于 adlist的主要内容,如果未能解决你的问题,请参考以下文章