Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
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) {
return
zl
;
}
/* Returns an offset to use for iterating with ziplistNext. */
unsigned
char
*
ziplistIndex
(
unsigned
char
*
zl
,
unsigned
int
index
)
{
unsigned
char
*
p
=
zl
+
ZIPLIST_HEADER_SIZE
;
unsigned
int
i
=
0
;
for
(;
i
<
index
;
i
++
)
{
if
(
*
p
==
ZIP_END
)
break
;
p
+=
zipRawEntryLength
(
p
);
/* Returns an offset to use for iterating with ziplistNext. When the given
* index is negative, the list is traversed back to front. When the list
* doesn't contain an element at the provided index, NULL is returned. */
unsigned
char
*
ziplistIndex
(
unsigned
char
*
zl
,
int
index
)
{
unsigned
char
*
p
;
zlentry
entry
;
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. */
...
...
@@ -424,7 +438,7 @@ unsigned char *ziplistNext(unsigned char *p) {
* 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
)
{
zlentry
entry
;
if
(
*
p
==
ZIP_END
)
return
0
;
if
(
p
==
NULL
||
p
[
0
]
==
ZIP_END
)
return
0
;
if
(
sstr
)
*
sstr
=
NULL
;
entry
=
zipEntry
(
p
);
...
...
@@ -444,7 +458,7 @@ unsigned int ziplistGet(unsigned char *p, char **sstr, unsigned int *slen, long
/* Delete a range of entries from the ziplist. */
unsigned
char
*
ziplistDeleteRange
(
unsigned
char
*
zl
,
unsigned
int
index
,
unsigned
int
num
)
{
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.
...
...
@@ -590,6 +604,83 @@ int main(int argc, char **argv) {
printf
(
"Pop tail: %s (length %ld)
\n
"
,
s
,
sdslen
(
s
));
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
"
);
{
zl
=
createList
();
...
...
ziplist.h
View file @
c03206fd
...
...
@@ -4,7 +4,7 @@
unsigned
char
*
ziplistNew
(
void
);
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
*
ziplistIndex
(
unsigned
char
*
zl
,
unsigned
int
index
);
unsigned
char
*
ziplistIndex
(
unsigned
char
*
zl
,
int
index
);
unsigned
char
*
ziplistNext
(
unsigned
char
*
p
);
unsigned
int
ziplistGet
(
unsigned
char
*
p
,
char
**
sstr
,
unsigned
int
*
slen
,
long
long
*
sval
);
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