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
c03206fd
Commit
c03206fd
authored
May 29, 2010
by
Pieter Noordhuis
Browse files
ziplistIndex now accepts negative indices
parent
a24ba809
Changes
2
Hide whitespace changes
Inline
Side-by-side
ziplist.c
View file @
c03206fd
...
@@ -402,15 +402,29 @@ unsigned char *ziplistPop(unsigned char *zl, sds *target, int where) {
...
@@ -402,15 +402,29 @@ unsigned char *ziplistPop(unsigned char *zl, sds *target, int where) {
return
zl
;
return
zl
;
}
}
/* Returns an offset to use for iterating with ziplistNext. */
/* Returns an offset to use for iterating with ziplistNext. When the given
unsigned
char
*
ziplistIndex
(
unsigned
char
*
zl
,
unsigned
int
index
)
{
* index is negative, the list is traversed back to front. When the list
unsigned
char
*
p
=
zl
+
ZIPLIST_HEADER_SIZE
;
* doesn't contain an element at the provided index, NULL is returned. */
unsigned
int
i
=
0
;
unsigned
char
*
ziplistIndex
(
unsigned
char
*
zl
,
int
index
)
{
for
(;
i
<
index
;
i
++
)
{
unsigned
char
*
p
;
if
(
*
p
==
ZIP_END
)
break
;
zlentry
entry
;
p
+=
zipRawEntryLength
(
p
);
if
(
index
<
0
)
{
index
=
(
-
index
)
-
1
;
p
=
ZIPLIST_ENTRY_TAIL
(
zl
);
if
(
p
[
0
]
!=
ZIP_END
)
{
entry
=
zipEntry
(
p
);
while
(
entry
.
prevrawlen
>
0
&&
index
--
)
{
p
-=
entry
.
prevrawlen
;
entry
=
zipEntry
(
p
);
}
}
}
else
{
p
=
ZIPLIST_ENTRY_HEAD
(
zl
);
while
(
p
[
0
]
!=
ZIP_END
&&
index
--
)
{
p
+=
zipRawEntryLength
(
p
);
}
}
}
return
p
;
return
p
[
0
]
==
ZIP_END
||
index
>
0
?
NULL
:
p
;
}
}
/* Return pointer to next entry in ziplist. */
/* Return pointer to next entry in ziplist. */
...
@@ -424,7 +438,7 @@ unsigned char *ziplistNext(unsigned char *p) {
...
@@ -424,7 +438,7 @@ unsigned char *ziplistNext(unsigned char *p) {
* Return 0 if 'p' points to the end of the zipmap, 1 otherwise. */
* Return 0 if 'p' points to the end of the zipmap, 1 otherwise. */
unsigned
int
ziplistGet
(
unsigned
char
*
p
,
char
**
sstr
,
unsigned
int
*
slen
,
long
long
*
sval
)
{
unsigned
int
ziplistGet
(
unsigned
char
*
p
,
char
**
sstr
,
unsigned
int
*
slen
,
long
long
*
sval
)
{
zlentry
entry
;
zlentry
entry
;
if
(
*
p
==
ZIP_END
)
return
0
;
if
(
p
==
NULL
||
p
[
0
]
==
ZIP_END
)
return
0
;
if
(
sstr
)
*
sstr
=
NULL
;
if
(
sstr
)
*
sstr
=
NULL
;
entry
=
zipEntry
(
p
);
entry
=
zipEntry
(
p
);
...
@@ -444,7 +458,7 @@ unsigned int ziplistGet(unsigned char *p, char **sstr, unsigned int *slen, long
...
@@ -444,7 +458,7 @@ unsigned int ziplistGet(unsigned char *p, char **sstr, unsigned int *slen, long
/* 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
=
ziplistIndex
(
zl
,
index
);
unsigned
char
*
p
=
ziplistIndex
(
zl
,
index
);
return
__ziplistDelete
(
zl
,
p
,
num
);
return
p
==
NULL
?
zl
:
__ziplistDelete
(
zl
,
p
,
num
);
}
}
/* Delete a single entry from the ziplist, pointed to by *p.
/* Delete a single entry from the ziplist, pointed to by *p.
...
@@ -590,6 +604,83 @@ int main(int argc, char **argv) {
...
@@ -590,6 +604,83 @@ int main(int argc, char **argv) {
printf
(
"Pop tail: %s (length %ld)
\n
"
,
s
,
sdslen
(
s
));
printf
(
"Pop tail: %s (length %ld)
\n
"
,
s
,
sdslen
(
s
));
ziplistRepr
(
zl
);
ziplistRepr
(
zl
);
printf
(
"Get element at index 3:
\n
"
);
{
zl
=
createList
();
p
=
ziplistIndex
(
zl
,
3
);
if
(
!
ziplistGet
(
p
,
&
entry
,
&
elen
,
&
value
))
{
printf
(
"ERROR: Could not access index 3
\n
"
);
return
1
;
}
if
(
entry
)
{
fwrite
(
entry
,
elen
,
1
,
stdout
);
printf
(
"
\n
"
);
}
else
{
printf
(
"%lld
\n
"
,
value
);
}
printf
(
"
\n
"
);
}
printf
(
"Get element at index 4 (out of range):
\n
"
);
{
zl
=
createList
();
p
=
ziplistIndex
(
zl
,
4
);
if
(
p
==
NULL
)
{
printf
(
"No entry
\n
"
);
}
else
{
printf
(
"ERROR: Out of range index should return NULL, returned offset: %ld
\n
"
,
p
-
zl
);
return
1
;
}
printf
(
"
\n
"
);
}
printf
(
"Get element at index -1 (last element):
\n
"
);
{
zl
=
createList
();
p
=
ziplistIndex
(
zl
,
-
1
);
if
(
!
ziplistGet
(
p
,
&
entry
,
&
elen
,
&
value
))
{
printf
(
"ERROR: Could not access index -1
\n
"
);
return
1
;
}
if
(
entry
)
{
fwrite
(
entry
,
elen
,
1
,
stdout
);
printf
(
"
\n
"
);
}
else
{
printf
(
"%lld
\n
"
,
value
);
}
printf
(
"
\n
"
);
}
printf
(
"Get element at index -4 (first element):
\n
"
);
{
zl
=
createList
();
p
=
ziplistIndex
(
zl
,
-
4
);
if
(
!
ziplistGet
(
p
,
&
entry
,
&
elen
,
&
value
))
{
printf
(
"ERROR: Could not access index -4
\n
"
);
return
1
;
}
if
(
entry
)
{
fwrite
(
entry
,
elen
,
1
,
stdout
);
printf
(
"
\n
"
);
}
else
{
printf
(
"%lld
\n
"
,
value
);
}
printf
(
"
\n
"
);
}
printf
(
"Get element at index -5 (reverse out of range):
\n
"
);
{
zl
=
createList
();
p
=
ziplistIndex
(
zl
,
-
5
);
if
(
p
==
NULL
)
{
printf
(
"No entry
\n
"
);
}
else
{
printf
(
"ERROR: Out of range index should return NULL, returned offset: %ld
\n
"
,
p
-
zl
);
return
1
;
}
printf
(
"
\n
"
);
}
printf
(
"Iterate list from 0 to end:
\n
"
);
printf
(
"Iterate list from 0 to end:
\n
"
);
{
{
zl
=
createList
();
zl
=
createList
();
...
...
ziplist.h
View file @
c03206fd
...
@@ -4,7 +4,7 @@
...
@@ -4,7 +4,7 @@
unsigned
char
*
ziplistNew
(
void
);
unsigned
char
*
ziplistNew
(
void
);
unsigned
char
*
ziplistPush
(
unsigned
char
*
zl
,
char
*
s
,
unsigned
int
slen
,
int
where
);
unsigned
char
*
ziplistPush
(
unsigned
char
*
zl
,
char
*
s
,
unsigned
int
slen
,
int
where
);
unsigned
char
*
ziplistPop
(
unsigned
char
*
zl
,
sds
*
target
,
int
where
);
unsigned
char
*
ziplistPop
(
unsigned
char
*
zl
,
sds
*
target
,
int
where
);
unsigned
char
*
ziplistIndex
(
unsigned
char
*
zl
,
unsigned
int
index
);
unsigned
char
*
ziplistIndex
(
unsigned
char
*
zl
,
int
index
);
unsigned
char
*
ziplistNext
(
unsigned
char
*
p
);
unsigned
char
*
ziplistNext
(
unsigned
char
*
p
);
unsigned
int
ziplistGet
(
unsigned
char
*
p
,
char
**
sstr
,
unsigned
int
*
slen
,
long
long
*
sval
);
unsigned
int
ziplistGet
(
unsigned
char
*
p
,
char
**
sstr
,
unsigned
int
*
slen
,
long
long
*
sval
);
unsigned
char
*
ziplistDelete
(
unsigned
char
*
zl
,
unsigned
char
**
p
);
unsigned
char
*
ziplistDelete
(
unsigned
char
*
zl
,
unsigned
char
**
p
);
...
...
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