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
ccf96e19
Commit
ccf96e19
authored
Mar 11, 2011
by
Pieter Noordhuis
Browse files
Make zzl API unaware of the robj where the ziplist is stored
parent
8f0a41be
Changes
2
Show whitespace changes
Inline
Side-by-side
src/redis.h
View file @
ccf96e19
...
...
@@ -778,7 +778,7 @@ void backgroundRewriteDoneHandler(int statloc);
zskiplist
*
zslCreate
(
void
);
void
zslFree
(
zskiplist
*
zsl
);
zskiplistNode
*
zslInsert
(
zskiplist
*
zsl
,
double
score
,
robj
*
obj
);
int
zzlInsert
(
robj
*
zobj
,
robj
*
ele
,
double
score
);
unsigned
char
*
zzlInsert
(
unsigned
char
*
zl
,
robj
*
ele
,
double
score
);
unsigned
int
zsetLength
(
robj
*
zobj
);
void
zsetConvert
(
robj
*
zobj
,
int
encoding
);
...
...
src/t_zset.c
View file @
ccf96e19
...
...
@@ -519,8 +519,7 @@ int zzlIsInRange(unsigned char *zl, zrangespec *range) {
/* Find pointer to the first element contained in the specified range.
* Returns NULL when no element is contained in the range. */
unsigned
char
*
zzlFirstInRange
(
robj
*
zobj
,
zrangespec
range
)
{
unsigned
char
*
zl
=
zobj
->
ptr
;
unsigned
char
*
zzlFirstInRange
(
unsigned
char
*
zl
,
zrangespec
range
)
{
unsigned
char
*
eptr
=
ziplistIndex
(
zl
,
0
),
*
sptr
;
double
score
;
...
...
@@ -544,8 +543,7 @@ unsigned char *zzlFirstInRange(robj *zobj, zrangespec range) {
/* Find pointer to the last element contained in the specified range.
* Returns NULL when no element is contained in the range. */
unsigned
char
*
zzlLastInRange
(
robj
*
zobj
,
zrangespec
range
)
{
unsigned
char
*
zl
=
zobj
->
ptr
;
unsigned
char
*
zzlLastInRange
(
unsigned
char
*
zl
,
zrangespec
range
)
{
unsigned
char
*
eptr
=
ziplistIndex
(
zl
,
-
2
),
*
sptr
;
double
score
;
...
...
@@ -572,8 +570,7 @@ unsigned char *zzlLastInRange(robj *zobj, zrangespec range) {
return
NULL
;
}
unsigned
char
*
zzlFind
(
robj
*
zobj
,
robj
*
ele
,
double
*
score
)
{
unsigned
char
*
zl
=
zobj
->
ptr
;
unsigned
char
*
zzlFind
(
unsigned
char
*
zl
,
robj
*
ele
,
double
*
score
)
{
unsigned
char
*
eptr
=
ziplistIndex
(
zl
,
0
),
*
sptr
;
ele
=
getDecodedObject
(
ele
);
...
...
@@ -598,19 +595,16 @@ unsigned char *zzlFind(robj *zobj, robj *ele, double *score) {
/* Delete (element,score) pair from ziplist. Use local copy of eptr because we
* don't want to modify the one given as argument. */
int
zzlDelete
(
robj
*
zobj
,
unsigned
char
*
eptr
)
{
unsigned
char
*
zl
=
zobj
->
ptr
;
unsigned
char
*
zzlDelete
(
unsigned
char
*
zl
,
unsigned
char
*
eptr
)
{
unsigned
char
*
p
=
eptr
;
/* TODO: add function to ziplist API to delete N elements from offset. */
zl
=
ziplistDelete
(
zl
,
&
p
);
zl
=
ziplistDelete
(
zl
,
&
p
);
zobj
->
ptr
=
zl
;
return
REDIS_OK
;
return
zl
;
}
int
zzlInsertAt
(
robj
*
zobj
,
robj
*
ele
,
double
score
,
unsigned
char
*
eptr
)
{
unsigned
char
*
zl
=
zobj
->
ptr
;
unsigned
char
*
zzlInsertAt
(
unsigned
char
*
zl
,
unsigned
char
*
eptr
,
robj
*
ele
,
double
score
)
{
unsigned
char
*
sptr
;
char
scorebuf
[
128
];
int
scorelen
;
...
...
@@ -632,14 +626,12 @@ int zzlInsertAt(robj *zobj, robj *ele, double score, unsigned char *eptr) {
zl
=
ziplistInsert
(
zl
,
sptr
,(
unsigned
char
*
)
scorebuf
,
scorelen
);
}
zobj
->
ptr
=
zl
;
return
REDIS_OK
;
return
zl
;
}
/* Insert (element,score) pair in ziplist. This function assumes the element is
* not yet present in the list. */
int
zzlInsert
(
robj
*
zobj
,
robj
*
ele
,
double
score
)
{
unsigned
char
*
zl
=
zobj
->
ptr
;
unsigned
char
*
zzlInsert
(
unsigned
char
*
zl
,
robj
*
ele
,
double
score
)
{
unsigned
char
*
eptr
=
ziplistIndex
(
zl
,
0
),
*
sptr
;
double
s
;
...
...
@@ -653,12 +645,12 @@ int zzlInsert(robj *zobj, robj *ele, double score) {
/* First element with score larger than score for element to be
* inserted. This means we should take its spot in the list to
* maintain ordering. */
zzlInsertAt
(
z
obj
,
ele
,
score
,
eptr
);
zl
=
zzlInsertAt
(
z
l
,
eptr
,
ele
,
score
);
break
;
}
else
if
(
s
==
score
)
{
/* Ensure lexicographical ordering for elements. */
if
(
zzlCompareElements
(
eptr
,
ele
->
ptr
,
sdslen
(
ele
->
ptr
))
>
0
)
{
zzlInsertAt
(
z
obj
,
ele
,
score
,
eptr
);
zl
=
zzlInsertAt
(
z
l
,
eptr
,
ele
,
score
);
break
;
}
}
...
...
@@ -669,21 +661,21 @@ int zzlInsert(robj *zobj, robj *ele, double score) {
/* Push on tail of list when it was not yet inserted. */
if
(
eptr
==
NULL
)
zzlInsertAt
(
z
obj
,
ele
,
score
,
NULL
);
zl
=
zzlInsertAt
(
z
l
,
NULL
,
ele
,
score
);
decrRefCount
(
ele
);
return
REDIS_OK
;
return
zl
;
}
unsigned
long
zzlDeleteRangeByScore
(
robj
*
zobj
,
zrangespec
range
)
{
unsigned
char
*
zl
=
zobj
->
ptr
;
unsigned
char
*
zzlDeleteRangeByScore
(
unsigned
char
*
zl
,
zrangespec
range
,
unsigned
long
*
deleted
)
{
unsigned
char
*
eptr
,
*
sptr
;
double
score
;
unsigned
long
deleted
=
0
;
unsigned
long
num
=
0
;
eptr
=
zzlFirstInRange
(
zobj
,
range
);
if
(
eptr
==
NULL
)
return
deleted
;
if
(
deleted
!=
NULL
)
*
deleted
=
0
;
eptr
=
zzlFirstInRange
(
zl
,
range
);
if
(
eptr
==
NULL
)
return
zl
;
/* When the tail of the ziplist is deleted, eptr will point to the sentinel
* byte and ziplistNext will return NULL. */
...
...
@@ -693,22 +685,24 @@ unsigned long zzlDeleteRangeByScore(robj *zobj, zrangespec range) {
/* Delete both the element and the score. */
zl
=
ziplistDelete
(
zl
,
&
eptr
);
zl
=
ziplistDelete
(
zl
,
&
eptr
);
deleted
++
;
num
++
;
}
else
{
/* No longer in range. */
break
;
}
}
return
deleted
;
if
(
deleted
!=
NULL
)
*
deleted
=
num
;
return
zl
;
}
/* Delete all the elements with rank between start and end from the skiplist.
* Start and end are inclusive. Note that start and end need to be 1-based */
unsigned
long
zzlDeleteRangeByRank
(
robj
*
zobj
,
unsigned
int
start
,
unsigned
int
end
)
{
unsigned
char
*
zzlDeleteRangeByRank
(
unsigned
char
*
zl
,
unsigned
int
start
,
unsigned
int
end
,
unsigned
long
*
deleted
)
{
unsigned
int
num
=
(
end
-
start
)
+
1
;
zobj
->
ptr
=
ziplistDeleteRange
(
zobj
->
ptr
,
2
*
(
start
-
1
),
2
*
num
);
return
num
;
if
(
deleted
)
*
deleted
=
num
;
zl
=
ziplistDeleteRange
(
zl
,
2
*
(
start
-
1
),
2
*
num
);
return
zl
;
}
/*-----------------------------------------------------------------------------
...
...
@@ -785,13 +779,9 @@ void zsetConvert(robj *zobj, int encoding) {
zfree
(
zs
->
zsl
->
header
);
zfree
(
zs
->
zsl
);
/* Immediately store pointer to ziplist in object because it will
* change because of reallocations when pushing to the ziplist. */
zobj
->
ptr
=
zl
;
while
(
node
)
{
ele
=
getDecodedObject
(
node
->
obj
);
redisAssert
(
zzlInsertAt
(
z
obj
,
ele
,
node
->
score
,
NULL
)
==
REDIS_OK
);
zl
=
zzlInsertAt
(
z
l
,
NULL
,
ele
,
node
->
score
);
decrRefCount
(
ele
);
next
=
node
->
level
[
0
].
forward
;
...
...
@@ -800,6 +790,7 @@ void zsetConvert(robj *zobj, int encoding) {
}
zfree
(
zs
);
zobj
->
ptr
=
zl
;
zobj
->
encoding
=
REDIS_ENCODING_ZIPLIST
;
}
else
{
redisPanic
(
"Unknown sorted set encoding"
);
...
...
@@ -844,7 +835,7 @@ void zaddGenericCommand(redisClient *c, int incr) {
/* Prefer non-encoded element when dealing with ziplists. */
ele
=
c
->
argv
[
3
];
if
((
eptr
=
zzlFind
(
zobj
,
ele
,
&
curscore
))
!=
NULL
)
{
if
((
eptr
=
zzlFind
(
zobj
->
ptr
,
ele
,
&
curscore
))
!=
NULL
)
{
if
(
incr
)
{
score
+=
curscore
;
if
(
isnan
(
score
))
{
...
...
@@ -857,8 +848,8 @@ void zaddGenericCommand(redisClient *c, int incr) {
/* Remove and re-insert when score changed. */
if
(
score
!=
curscore
)
{
redisAssert
(
zzlDelete
(
zobj
,
eptr
)
==
REDIS_OK
);
redisAssert
(
zzlInsert
(
zobj
,
ele
,
score
)
==
REDIS_OK
)
;
zobj
->
ptr
=
zzlDelete
(
zobj
->
ptr
,
eptr
);
zobj
->
ptr
=
zzlInsert
(
zobj
->
ptr
,
ele
,
score
);
signalModifiedKey
(
c
->
db
,
key
);
server
.
dirty
++
;
...
...
@@ -871,7 +862,7 @@ void zaddGenericCommand(redisClient *c, int incr) {
}
else
{
/* Optimize: check if the element is too large or the list becomes
* too long *before* executing zzlInsert. */
redisAssert
(
zzlInsert
(
zobj
,
ele
,
score
)
==
REDIS_OK
)
;
zobj
->
ptr
=
zzlInsert
(
zobj
->
ptr
,
ele
,
score
);
if
(
zzlLength
(
zobj
->
ptr
)
>
server
.
zset_max_ziplist_entries
)
zsetConvert
(
zobj
,
REDIS_ENCODING_RAW
);
if
(
sdslen
(
ele
->
ptr
)
>
server
.
zset_max_ziplist_value
)
...
...
@@ -961,8 +952,8 @@ void zremCommand(redisClient *c) {
if
(
zobj
->
encoding
==
REDIS_ENCODING_ZIPLIST
)
{
unsigned
char
*
eptr
;
if
((
eptr
=
zzlFind
(
zobj
,
ele
,
NULL
))
!=
NULL
)
{
redisAssert
(
zzlDelete
(
zobj
,
eptr
)
==
REDIS_OK
);
if
((
eptr
=
zzlFind
(
zobj
->
ptr
,
ele
,
NULL
))
!=
NULL
)
{
zobj
->
ptr
=
zzlDelete
(
zobj
->
ptr
,
eptr
);
if
(
zzlLength
(
zobj
->
ptr
)
==
0
)
dbDelete
(
c
->
db
,
key
);
}
else
{
addReply
(
c
,
shared
.
czero
);
...
...
@@ -1012,7 +1003,7 @@ void zremrangebyscoreCommand(redisClient *c) {
checkType
(
c
,
zobj
,
REDIS_ZSET
))
return
;
if
(
zobj
->
encoding
==
REDIS_ENCODING_ZIPLIST
)
{
deleted
=
zzlDeleteRangeByScore
(
zobj
,
range
);
zobj
->
ptr
=
zzlDeleteRangeByScore
(
zobj
->
ptr
,
range
,
&
deleted
);
}
else
if
(
zobj
->
encoding
==
REDIS_ENCODING_RAW
)
{
zset
*
zs
=
zobj
->
ptr
;
deleted
=
zslDeleteRangeByScore
(
zs
->
zsl
,
range
,
zs
->
dict
);
...
...
@@ -1057,7 +1048,7 @@ void zremrangebyrankCommand(redisClient *c) {
if
(
zobj
->
encoding
==
REDIS_ENCODING_ZIPLIST
)
{
/* Correct for 1-based rank. */
deleted
=
zzlDeleteRangeByRank
(
zobj
,
start
+
1
,
end
+
1
);
zobj
->
ptr
=
zzlDeleteRangeByRank
(
zobj
->
ptr
,
start
+
1
,
end
+
1
,
&
deleted
);
}
else
if
(
zobj
->
encoding
==
REDIS_ENCODING_RAW
)
{
zset
*
zs
=
zobj
->
ptr
;
...
...
@@ -1372,7 +1363,7 @@ int zuiFind(zsetopsrc *op, zsetopval *val, double *score) {
zuiObjectFromValue
(
val
);
if
(
op
->
encoding
==
REDIS_ENCODING_ZIPLIST
)
{
if
(
zzlFind
(
op
->
subject
,
val
->
ele
,
score
)
!=
NULL
)
{
if
(
zzlFind
(
it
->
zl
.
zl
,
val
->
ele
,
score
)
!=
NULL
)
{
/* Score is already set by zzlFind. */
return
1
;
}
else
{
...
...
@@ -1791,9 +1782,9 @@ void genericZrangebyscoreCommand(redisClient *c, int reverse, int justcount) {
/* If reversed, get the last node in range as starting point. */
if
(
reverse
)
eptr
=
zzlLastInRange
(
z
obj
,
range
);
eptr
=
zzlLastInRange
(
z
l
,
range
);
else
eptr
=
zzlFirstInRange
(
z
obj
,
range
);
eptr
=
zzlFirstInRange
(
z
l
,
range
);
/* No "first" element in the specified interval. */
if
(
eptr
==
NULL
)
{
...
...
@@ -1938,7 +1929,7 @@ void zscoreCommand(redisClient *c) {
checkType
(
c
,
zobj
,
REDIS_ZSET
))
return
;
if
(
zobj
->
encoding
==
REDIS_ENCODING_ZIPLIST
)
{
if
(
zzlFind
(
zobj
,
c
->
argv
[
2
],
&
score
)
!=
NULL
)
if
(
zzlFind
(
zobj
->
ptr
,
c
->
argv
[
2
],
&
score
)
!=
NULL
)
addReplyDouble
(
c
,
score
);
else
addReply
(
c
,
shared
.
nullbulk
);
...
...
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