From 0ead8c347060ecb58d170e2bbebf8479678797ea Mon Sep 17 00:00:00 2001 From: zeekling Date: Fri, 23 Dec 2022 21:50:18 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8E=8B=E7=BC=A9=E5=88=97=E8=A1=A8=E9=81=8D?= =?UTF-8?q?=E5=8E=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ziplist/readme.md | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/ziplist/readme.md b/ziplist/readme.md index 018d963..89efd59 100644 --- a/ziplist/readme.md +++ b/ziplist/readme.md @@ -450,10 +450,11 @@ unsigned char *ziplistNext(unsigned char *zl, unsigned char *p) ### 前向遍历 -如果`p[0]==ZIP_END`,则说明前一个节点是压缩列表的尾节点。 +- 如果`p[0]==ZIP_END`,则说明前一个节点是压缩列表的尾节点。 -如果`p == ZIPLIST_ENTRY_HEAD(zl)` 说明p是压缩列表的第一个节点,前一个节点为NULL。 +- 如果`p == ZIPLIST_ENTRY_HEAD(zl)` 说明p是压缩列表的第一个节点,前一个节点为NULL。 +- 如果是查找的是中间节点,需要解析出 prevlen 往前进行偏移,然后解析出对应节点。 ```c unsigned char *ziplistPrev(unsigned char *zl, unsigned char *p) { @@ -476,4 +477,26 @@ unsigned char *ziplistPrev(unsigned char *zl, unsigned char *p) { ### 后向遍历 +- 如果`p[0] == ZIP_END`,则表示当前ziplist为空,范围NULL。 +- 在 p 当前节点的基础上,往后偏移 p 节点的字节长度,即指向下一个节点。如果之后的 p 指向 ZIP_END 说明已经达到 ziplist 尾部,没有下一个节点 + +```c +unsigned char *ziplistNext(unsigned char *zl, unsigned char *p) { + ((void) zl); + size_t zlbytes = intrev32ifbe(ZIPLIST_BYTES(zl)); + + if (p[0] == ZIP_END) { + return NULL; + } + + p += zipRawEntryLength(p); + if (p[0] == ZIP_END) { + return NULL; + } + + zipAssertValidEntry(zl, zlbytes, p); + return p; +} +``` +