Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xindoo
redis
提交
0c0d0564
R
redis
项目概览
xindoo
/
redis
通知
2
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
redis
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
0c0d0564
编写于
5月 29, 2010
作者:
P
Pieter Noordhuis
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
extract a generic delete function that can be used in pop and delete(range)
上级
bb57b965
变更
1
显示空白变更内容
内联
并排
Showing
1 changed file
with
45 addition
and
58 deletion
+45
-58
ziplist.c
ziplist.c
+45
-58
未找到文件。
ziplist.c
浏览文件 @
0c0d0564
...
@@ -56,6 +56,7 @@ typedef struct zlentry {
...
@@ -56,6 +56,7 @@ typedef struct zlentry {
unsigned
int
lensize
,
len
;
unsigned
int
lensize
,
len
;
unsigned
int
headersize
;
unsigned
int
headersize
;
unsigned
char
encoding
;
unsigned
char
encoding
;
unsigned
char
*
p
;
}
zlentry
;
}
zlentry
;
/* Return bytes needed to store integer encoded by 'encoding' */
/* Return bytes needed to store integer encoded by 'encoding' */
...
@@ -206,6 +207,7 @@ static zlentry zipEntry(unsigned char *p) {
...
@@ -206,6 +207,7 @@ static zlentry zipEntry(unsigned char *p) {
e
.
len
=
zipDecodeLength
(
p
+
e
.
prevrawlensize
,
&
e
.
lensize
);
e
.
len
=
zipDecodeLength
(
p
+
e
.
prevrawlensize
,
&
e
.
lensize
);
e
.
headersize
=
e
.
prevrawlensize
+
e
.
lensize
;
e
.
headersize
=
e
.
prevrawlensize
+
e
.
lensize
;
e
.
encoding
=
ZIP_ENCODING
(
p
+
e
.
prevrawlensize
);
e
.
encoding
=
ZIP_ENCODING
(
p
+
e
.
prevrawlensize
);
e
.
p
=
p
;
return
e
;
return
e
;
}
}
...
@@ -246,6 +248,42 @@ static unsigned char *ziplistTail(unsigned char *zl) {
...
@@ -246,6 +248,42 @@ static unsigned char *ziplistTail(unsigned char *zl) {
p
+=
zipRawEntryLength
(
p
);
p
+=
zipRawEntryLength
(
p
);
}
}
return
q
;
return
q
;
/* Delete "num" entries, starting at "p". Returns pointer to the ziplist. */
static
unsigned
char
*
__ziplistDelete
(
unsigned
char
*
zl
,
unsigned
char
*
p
,
int
num
)
{
unsigned
int
i
,
totlen
,
deleted
=
0
;
int
nextdiff
=
0
;
zlentry
first
=
zipEntry
(
p
);
for
(
i
=
0
;
p
[
0
]
!=
ZIP_END
&&
i
<
num
;
i
++
)
{
p
+=
zipRawEntryLength
(
p
);
deleted
++
;
}
totlen
=
p
-
first
.
p
;
if
(
totlen
>
0
)
{
if
(
p
[
0
]
!=
ZIP_END
)
{
/* Tricky: storing the prevlen in this entry might reduce or
* increase the number of bytes needed, compared to the current
* prevlen. Note that we can always store this length because
* it was previously stored by an entry that is being deleted. */
nextdiff
=
zipPrevLenByteDiff
(
p
,
first
.
prevrawlen
);
zipEncodeLength
(
p
-
nextdiff
,
ZIP_ENC_RAW
,
first
.
prevrawlen
);
/* Update offset for tail */
ZIPLIST_TAIL_OFFSET
(
zl
)
-=
totlen
+
nextdiff
;
/* Move tail to the front of the ziplist */
memmove
(
first
.
p
,
p
-
nextdiff
,
ZIPLIST_BYTES
(
zl
)
-
(
p
-
zl
)
-
1
+
nextdiff
);
}
else
{
/* The entire tail was deleted. No need to move memory. */
ZIPLIST_TAIL_OFFSET
(
zl
)
=
(
first
.
p
-
zl
)
-
first
.
prevrawlen
;
}
/* Resize and update length */
zl
=
ziplistResize
(
zl
,
ZIPLIST_BYTES
(
zl
)
-
totlen
+
nextdiff
);
ZIPLIST_INCR_LENGTH
(
zl
,
-
deleted
);
}
return
zl
;
}
}
unsigned
char
*
ziplistPush
(
unsigned
char
*
zl
,
unsigned
char
*
entry
,
unsigned
int
elen
,
int
where
)
{
unsigned
char
*
ziplistPush
(
unsigned
char
*
zl
,
unsigned
char
*
entry
,
unsigned
int
elen
,
int
where
)
{
...
@@ -309,9 +347,7 @@ unsigned char *ziplistPush(unsigned char *zl, unsigned char *entry, unsigned int
...
@@ -309,9 +347,7 @@ unsigned char *ziplistPush(unsigned char *zl, unsigned char *entry, unsigned int
}
}
unsigned
char
*
ziplistPop
(
unsigned
char
*
zl
,
sds
*
target
,
int
where
)
{
unsigned
char
*
ziplistPop
(
unsigned
char
*
zl
,
sds
*
target
,
int
where
)
{
unsigned
int
curlen
=
ZIPLIST_BYTES
(
zl
),
rawlen
;
zlentry
entry
;
zlentry
entry
;
int
nextdiff
=
0
;
unsigned
char
*
p
;
unsigned
char
*
p
;
long
long
value
;
long
long
value
;
if
(
target
)
*
target
=
NULL
;
if
(
target
)
*
target
=
NULL
;
...
@@ -321,7 +357,6 @@ unsigned char *ziplistPop(unsigned char *zl, sds *target, int where) {
...
@@ -321,7 +357,6 @@ unsigned char *ziplistPop(unsigned char *zl, sds *target, int where) {
if
(
*
p
==
ZIP_END
)
return
zl
;
if
(
*
p
==
ZIP_END
)
return
zl
;
entry
=
zipEntry
(
p
);
entry
=
zipEntry
(
p
);
rawlen
=
entry
.
headersize
+
entry
.
len
;
if
(
target
)
{
if
(
target
)
{
if
(
entry
.
encoding
==
ZIP_ENC_RAW
)
{
if
(
entry
.
encoding
==
ZIP_ENC_RAW
)
{
*
target
=
sdsnewlen
(
p
+
entry
.
headersize
,
entry
.
len
);
*
target
=
sdsnewlen
(
p
+
entry
.
headersize
,
entry
.
len
);
...
@@ -331,32 +366,7 @@ unsigned char *ziplistPop(unsigned char *zl, sds *target, int where) {
...
@@ -331,32 +366,7 @@ unsigned char *ziplistPop(unsigned char *zl, sds *target, int where) {
}
}
}
}
if
(
where
==
ZIPLIST_HEAD
)
{
zl
=
__ziplistDelete
(
zl
,
p
,
1
);
/* The next entry will now be the head of the list */
if
(
p
[
rawlen
]
!=
ZIP_END
)
{
/* Tricky: storing the length of the previous entry in the next
* entry (this previous length is always 0 when popping from the
* head), might reduce the number of bytes needed.
*
* In this special case (new length is 0), we know that the
* byte difference to store is always <= 0, which means that
* we always have space to store it. */
nextdiff
=
zipPrevLenByteDiff
(
p
+
rawlen
,
0
);
zipEncodeLength
(
p
+
rawlen
-
nextdiff
,
ZIP_ENC_RAW
,
0
);
}
/* Move list to the front */
memmove
(
p
,
p
+
rawlen
-
nextdiff
,
curlen
-
ZIPLIST_HEADER_SIZE
-
rawlen
+
nextdiff
);
/* Subtract the gained space from the tail offset */
ZIPLIST_TAIL_OFFSET
(
zl
)
-=
rawlen
+
nextdiff
;
}
else
{
/* Subtract the length of the previous element from the tail offset. */
ZIPLIST_TAIL_OFFSET
(
zl
)
-=
entry
.
prevrawlen
;
}
/* Resize and update length */
zl
=
ziplistResize
(
zl
,
curlen
-
rawlen
+
nextdiff
);
ZIPLIST_INCR_LENGTH
(
zl
,
-
1
);
return
zl
;
return
zl
;
}
}
...
@@ -401,42 +411,19 @@ unsigned int ziplistGet(unsigned char *p, unsigned char **sstr, unsigned int *sl
...
@@ -401,42 +411,19 @@ unsigned int ziplistGet(unsigned char *p, unsigned char **sstr, unsigned int *sl
/* Delete a range of entries from the ziplist. */
/* Delete a range of entries from the ziplist. */
unsigned
char
*
ziplistDeleteRange
(
unsigned
char
*
zl
,
unsigned
int
index
,
unsigned
int
num
)
{
unsigned
char
*
ziplistDeleteRange
(
unsigned
char
*
zl
,
unsigned
int
index
,
unsigned
int
num
)
{
unsigned
char
*
p
,
*
first
=
ziplistIndex
(
zl
,
index
);
unsigned
char
*
p
=
ziplistIndex
(
zl
,
index
);
unsigned
int
i
,
totlen
,
deleted
=
0
;
return
__ziplistDelete
(
zl
,
p
,
num
);
for
(
p
=
first
,
i
=
0
;
*
p
!=
ZIP_END
&&
i
<
num
;
i
++
)
{
p
+=
zipRawEntryLength
(
p
);
deleted
++
;
}
totlen
=
p
-
first
;
if
(
totlen
>
0
)
{
/* Move current tail to the new tail when there *is* a tail */
if
(
*
p
!=
ZIP_END
)
memmove
(
first
,
p
,
ZIPLIST_BYTES
(
zl
)
-
(
p
-
zl
)
-
1
);
/* Resize and update length */
zl
=
ziplistResize
(
zl
,
ZIPLIST_BYTES
(
zl
)
-
totlen
);
ZIPLIST_INCR_LENGTH
(
zl
,
-
deleted
);
}
return
zl
;
}
}
/* Delete a single entry from the ziplist, pointed to by *p.
/* Delete a single entry from the ziplist, pointed to by *p.
* Also update *p in place, to be able to iterate over the
* Also update *p in place, to be able to iterate over the
* ziplist, while deleting entries. */
* ziplist, while deleting entries. */
unsigned
char
*
ziplistDelete
(
unsigned
char
*
zl
,
unsigned
char
**
p
)
{
unsigned
char
*
ziplistDelete
(
unsigned
char
*
zl
,
unsigned
char
**
p
)
{
unsigned
int
offset
=
*
p
-
zl
,
tail
,
len
;
unsigned
int
offset
=
*
p
-
zl
;
len
=
zipRawEntryLength
(
*
p
);
zl
=
__ziplistDelete
(
zl
,
*
p
,
1
);
tail
=
ZIPLIST_BYTES
(
zl
)
-
offset
-
len
-
1
;
/* Move current tail to the new tail when there *is* a tail */
if
(
tail
>
0
)
memmove
(
*
p
,
*
p
+
len
,
tail
);
/* Resize and update length */
zl
=
ziplistResize
(
zl
,
ZIPLIST_BYTES
(
zl
)
-
len
);
ZIPLIST_INCR_LENGTH
(
zl
,
-
1
);
/* Store
new pointer to current element in p.
/* Store
pointer to current element in p, because ziplistDelete will
*
This needs to be done because zl can change on realloc
. */
*
do a realloc which might result in a different "zl"-pointer
. */
*
p
=
zl
+
offset
;
*
p
=
zl
+
offset
;
return
zl
;
return
zl
;
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录