Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
724371d7
Commit
724371d7
authored
Aug 22, 2012
by
Salvatore Sanfilippo
Browse files
Merge pull request #628 from pietern/unstable-zip
Fix ziplist edge case
parents
227b4293
3cc2904e
Changes
1
Hide whitespace changes
Inline
Side-by-side
src/ziplist.c
View file @
724371d7
...
@@ -500,12 +500,13 @@ static unsigned char *__ziplistDelete(unsigned char *zl, unsigned char *p, unsig
...
@@ -500,12 +500,13 @@ static unsigned char *__ziplistDelete(unsigned char *zl, unsigned char *p, unsig
totlen
=
p
-
first
.
p
;
totlen
=
p
-
first
.
p
;
if
(
totlen
>
0
)
{
if
(
totlen
>
0
)
{
if
(
p
[
0
]
!=
ZIP_END
)
{
if
(
p
[
0
]
!=
ZIP_END
)
{
/*
Tricky: s
toring
the
prevlen in this entry m
ight reduce or
/*
S
toring
`
prev
raw
len
`
in this entry m
ay increase or decrease the
*
increase the
number of bytes
needed,
compare
d
to the current
* number of bytes
required
compare to the current
`prevrawlen`.
*
prevlen. Note that we can always
store this
length
because
*
There always is room to
store this
,
because
it was previously
*
it was previously
stored by an entry that is being deleted. */
* stored by an entry that is
now
being deleted. */
nextdiff
=
zipPrevLenByteDiff
(
p
,
first
.
prevrawlen
);
nextdiff
=
zipPrevLenByteDiff
(
p
,
first
.
prevrawlen
);
zipPrevEncodeLength
(
p
-
nextdiff
,
first
.
prevrawlen
);
p
-=
nextdiff
;
zipPrevEncodeLength
(
p
,
first
.
prevrawlen
);
/* Update offset for tail */
/* Update offset for tail */
ZIPLIST_TAIL_OFFSET
(
zl
)
=
ZIPLIST_TAIL_OFFSET
(
zl
)
=
...
@@ -521,8 +522,8 @@ static unsigned char *__ziplistDelete(unsigned char *zl, unsigned char *p, unsig
...
@@ -521,8 +522,8 @@ static unsigned char *__ziplistDelete(unsigned char *zl, unsigned char *p, unsig
}
}
/* Move tail to the front of the ziplist */
/* Move tail to the front of the ziplist */
memmove
(
first
.
p
,
p
-
nextdiff
,
memmove
(
first
.
p
,
p
,
intrev32ifbe
(
ZIPLIST_BYTES
(
zl
))
-
(
p
-
zl
)
-
1
+
nextdiff
);
intrev32ifbe
(
ZIPLIST_BYTES
(
zl
))
-
(
p
-
zl
)
-
1
);
}
else
{
}
else
{
/* The entire tail was deleted. No need to move memory. */
/* The entire tail was deleted. No need to move memory. */
ZIPLIST_TAIL_OFFSET
(
zl
)
=
ZIPLIST_TAIL_OFFSET
(
zl
)
=
...
@@ -1034,6 +1035,22 @@ int randstring(char *target, unsigned int min, unsigned int max) {
...
@@ -1034,6 +1035,22 @@ int randstring(char *target, unsigned int min, unsigned int max) {
return
len
;
return
len
;
}
}
void
verify
(
unsigned
char
*
zl
,
zlentry
*
e
)
{
int
i
;
int
len
=
ziplistLen
(
zl
);
zlentry
_e
;
for
(
i
=
0
;
i
<
len
;
i
++
)
{
memset
(
&
e
[
i
],
0
,
sizeof
(
zlentry
));
e
[
i
]
=
zipEntry
(
ziplistIndex
(
zl
,
i
));
memset
(
&
_e
,
0
,
sizeof
(
zlentry
));
_e
=
zipEntry
(
ziplistIndex
(
zl
,
-
len
+
i
));
assert
(
memcmp
(
&
e
[
i
],
&
_e
,
sizeof
(
zlentry
))
==
0
);
}
}
int
main
(
int
argc
,
char
**
argv
)
{
int
main
(
int
argc
,
char
**
argv
)
{
unsigned
char
*
zl
,
*
p
;
unsigned
char
*
zl
,
*
p
;
unsigned
char
*
entry
;
unsigned
char
*
entry
;
...
@@ -1315,6 +1332,43 @@ int main(int argc, char **argv) {
...
@@ -1315,6 +1332,43 @@ int main(int argc, char **argv) {
printf
(
"SUCCESS
\n\n
"
);
printf
(
"SUCCESS
\n\n
"
);
}
}
printf
(
"Regression test deleting next to last entries:
\n
"
);
{
char
v
[
3
][
257
];
zlentry
e
[
3
];
int
i
;
for
(
i
=
0
;
i
<
(
sizeof
(
v
)
/
sizeof
(
v
[
0
]));
i
++
)
{
memset
(
v
[
i
],
'a'
+
i
,
sizeof
(
v
[
0
]));
}
v
[
0
][
256
]
=
'\0'
;
v
[
1
][
1
]
=
'\0'
;
v
[
2
][
256
]
=
'\0'
;
zl
=
ziplistNew
();
for
(
i
=
0
;
i
<
(
sizeof
(
v
)
/
sizeof
(
v
[
0
]));
i
++
)
{
zl
=
ziplistPush
(
zl
,
(
unsigned
char
*
)
v
[
i
],
strlen
(
v
[
i
]),
ZIPLIST_TAIL
);
}
verify
(
zl
,
e
);
assert
(
e
[
0
].
prevrawlensize
==
1
);
assert
(
e
[
1
].
prevrawlensize
==
5
);
assert
(
e
[
2
].
prevrawlensize
==
1
);
/* Deleting entry 1 will increase `prevrawlensize` for entry 2 */
unsigned
char
*
p
=
e
[
1
].
p
;
zl
=
ziplistDelete
(
zl
,
&
p
);
verify
(
zl
,
e
);
assert
(
e
[
0
].
prevrawlensize
==
1
);
assert
(
e
[
1
].
prevrawlensize
==
5
);
printf
(
"SUCCESS
\n\n
"
);
}
printf
(
"Create long list and check indices:
\n
"
);
printf
(
"Create long list and check indices:
\n
"
);
{
{
zl
=
ziplistNew
();
zl
=
ziplistNew
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment