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
a7c5be18
Commit
a7c5be18
authored
Aug 04, 2015
by
antirez
Browse files
Lazyfree: Sorted sets convereted to plain SDS. (several commits squashed)
parent
86d48efb
Changes
10
Expand all
Hide whitespace changes
Inline
Side-by-side
src/aof.c
View file @
a7c5be18
...
@@ -826,7 +826,7 @@ int rewriteSetObject(rio *r, robj *key, robj *o) {
...
@@ -826,7 +826,7 @@ int rewriteSetObject(rio *r, robj *key, robj *o) {
dictEntry
*
de
;
dictEntry
*
de
;
while
((
de
=
dictNext
(
di
))
!=
NULL
)
{
while
((
de
=
dictNext
(
di
))
!=
NULL
)
{
robj
*
eleobj
=
dictGetKey
(
de
);
sds
ele
=
dictGetKey
(
de
);
if
(
count
==
0
)
{
if
(
count
==
0
)
{
int
cmd_items
=
(
items
>
AOF_REWRITE_ITEMS_PER_CMD
)
?
int
cmd_items
=
(
items
>
AOF_REWRITE_ITEMS_PER_CMD
)
?
AOF_REWRITE_ITEMS_PER_CMD
:
items
;
AOF_REWRITE_ITEMS_PER_CMD
:
items
;
...
@@ -835,7 +835,7 @@ int rewriteSetObject(rio *r, robj *key, robj *o) {
...
@@ -835,7 +835,7 @@ int rewriteSetObject(rio *r, robj *key, robj *o) {
if
(
rioWriteBulkString
(
r
,
"SADD"
,
4
)
==
0
)
return
0
;
if
(
rioWriteBulkString
(
r
,
"SADD"
,
4
)
==
0
)
return
0
;
if
(
rioWriteBulkObject
(
r
,
key
)
==
0
)
return
0
;
if
(
rioWriteBulkObject
(
r
,
key
)
==
0
)
return
0
;
}
}
if
(
rioWriteBulk
Object
(
r
,
eleobj
)
==
0
)
return
0
;
if
(
rioWriteBulk
String
(
r
,
ele
,
sdslen
(
ele
)
)
==
0
)
return
0
;
if
(
++
count
==
AOF_REWRITE_ITEMS_PER_CMD
)
count
=
0
;
if
(
++
count
==
AOF_REWRITE_ITEMS_PER_CMD
)
count
=
0
;
items
--
;
items
--
;
}
}
...
@@ -892,7 +892,7 @@ int rewriteSortedSetObject(rio *r, robj *key, robj *o) {
...
@@ -892,7 +892,7 @@ int rewriteSortedSetObject(rio *r, robj *key, robj *o) {
dictEntry
*
de
;
dictEntry
*
de
;
while
((
de
=
dictNext
(
di
))
!=
NULL
)
{
while
((
de
=
dictNext
(
di
))
!=
NULL
)
{
robj
*
eleobj
=
dictGetKey
(
de
);
sds
ele
=
dictGetKey
(
de
);
double
*
score
=
dictGetVal
(
de
);
double
*
score
=
dictGetVal
(
de
);
if
(
count
==
0
)
{
if
(
count
==
0
)
{
...
@@ -904,7 +904,7 @@ int rewriteSortedSetObject(rio *r, robj *key, robj *o) {
...
@@ -904,7 +904,7 @@ int rewriteSortedSetObject(rio *r, robj *key, robj *o) {
if
(
rioWriteBulkObject
(
r
,
key
)
==
0
)
return
0
;
if
(
rioWriteBulkObject
(
r
,
key
)
==
0
)
return
0
;
}
}
if
(
rioWriteBulkDouble
(
r
,
*
score
)
==
0
)
return
0
;
if
(
rioWriteBulkDouble
(
r
,
*
score
)
==
0
)
return
0
;
if
(
rioWriteBulk
Object
(
r
,
eleobj
)
==
0
)
return
0
;
if
(
rioWriteBulk
String
(
r
,
ele
,
sdslen
(
ele
)
)
==
0
)
return
0
;
if
(
++
count
==
AOF_REWRITE_ITEMS_PER_CMD
)
count
=
0
;
if
(
++
count
==
AOF_REWRITE_ITEMS_PER_CMD
)
count
=
0
;
items
--
;
items
--
;
}
}
...
...
src/cluster.c
View file @
a7c5be18
...
@@ -4087,7 +4087,10 @@ void clusterCommand(client *c) {
...
@@ -4087,7 +4087,10 @@ void clusterCommand(client *c) {
keys
=
zmalloc
(
sizeof
(
robj
*
)
*
maxkeys
);
keys
=
zmalloc
(
sizeof
(
robj
*
)
*
maxkeys
);
numkeys
=
getKeysInSlot
(
slot
,
keys
,
maxkeys
);
numkeys
=
getKeysInSlot
(
slot
,
keys
,
maxkeys
);
addReplyMultiBulkLen
(
c
,
numkeys
);
addReplyMultiBulkLen
(
c
,
numkeys
);
for
(
j
=
0
;
j
<
numkeys
;
j
++
)
addReplyBulk
(
c
,
keys
[
j
]);
for
(
j
=
0
;
j
<
numkeys
;
j
++
)
{
addReplyBulk
(
c
,
keys
[
j
]);
decrRefCount
(
keys
[
j
]);
}
zfree
(
keys
);
zfree
(
keys
);
}
else
if
(
!
strcasecmp
(
c
->
argv
[
1
]
->
ptr
,
"forget"
)
&&
c
->
argc
==
3
)
{
}
else
if
(
!
strcasecmp
(
c
->
argv
[
1
]
->
ptr
,
"forget"
)
&&
c
->
argc
==
3
)
{
/* CLUSTER FORGET <NODE ID> */
/* CLUSTER FORGET <NODE ID> */
...
...
src/db.c
View file @
a7c5be18
...
@@ -423,8 +423,8 @@ void scanCallback(void *privdata, const dictEntry *de) {
...
@@ -423,8 +423,8 @@ void scanCallback(void *privdata, const dictEntry *de) {
val
=
dictGetVal
(
de
);
val
=
dictGetVal
(
de
);
incrRefCount
(
val
);
incrRefCount
(
val
);
}
else
if
(
o
->
type
==
OBJ_ZSET
)
{
}
else
if
(
o
->
type
==
OBJ_ZSET
)
{
key
=
dictGetKey
(
de
);
sds
keysds
=
dictGetKey
(
de
);
incrRefCount
(
key
);
key
=
createStringObject
(
keysds
,
sdslen
(
keysds
)
);
val
=
createStringObjectFromLongDouble
(
*
(
double
*
)
dictGetVal
(
de
),
0
);
val
=
createStringObjectFromLongDouble
(
*
(
double
*
)
dictGetVal
(
de
),
0
);
}
else
{
}
else
{
serverPanic
(
"Type not handled in SCAN callback."
);
serverPanic
(
"Type not handled in SCAN callback."
);
...
@@ -1181,14 +1181,13 @@ int *sortGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys)
...
@@ -1181,14 +1181,13 @@ int *sortGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys)
void
slotToKeyAdd
(
robj
*
key
)
{
void
slotToKeyAdd
(
robj
*
key
)
{
unsigned
int
hashslot
=
keyHashSlot
(
key
->
ptr
,
sdslen
(
key
->
ptr
));
unsigned
int
hashslot
=
keyHashSlot
(
key
->
ptr
,
sdslen
(
key
->
ptr
));
zslInsert
(
server
.
cluster
->
slots_to_keys
,
hashslot
,
key
);
sds
sdskey
=
sdsdup
(
key
->
ptr
);
incrRefCount
(
key
);
zslInsert
(
server
.
cluster
->
slots_to_keys
,
hashslot
,
sds
key
);
}
}
void
slotToKeyDel
(
robj
*
key
)
{
void
slotToKeyDel
(
robj
*
key
)
{
unsigned
int
hashslot
=
keyHashSlot
(
key
->
ptr
,
sdslen
(
key
->
ptr
));
unsigned
int
hashslot
=
keyHashSlot
(
key
->
ptr
,
sdslen
(
key
->
ptr
));
zslDelete
(
server
.
cluster
->
slots_to_keys
,
hashslot
,
key
->
ptr
,
NULL
);
zslDelete
(
server
.
cluster
->
slots_to_keys
,
hashslot
,
key
);
}
}
void
slotToKeyFlush
(
void
)
{
void
slotToKeyFlush
(
void
)
{
...
@@ -1196,6 +1195,9 @@ void slotToKeyFlush(void) {
...
@@ -1196,6 +1195,9 @@ void slotToKeyFlush(void) {
server
.
cluster
->
slots_to_keys
=
zslCreate
();
server
.
cluster
->
slots_to_keys
=
zslCreate
();
}
}
/* Pupulate the specified array of objects with keys in the specified slot.
* New objects are returned to represent keys, it's up to the caller to
* decrement the reference count to release the keys names. */
unsigned
int
getKeysInSlot
(
unsigned
int
hashslot
,
robj
**
keys
,
unsigned
int
count
)
{
unsigned
int
getKeysInSlot
(
unsigned
int
hashslot
,
robj
**
keys
,
unsigned
int
count
)
{
zskiplistNode
*
n
;
zskiplistNode
*
n
;
zrangespec
range
;
zrangespec
range
;
...
@@ -1206,7 +1208,7 @@ unsigned int getKeysInSlot(unsigned int hashslot, robj **keys, unsigned int coun
...
@@ -1206,7 +1208,7 @@ unsigned int getKeysInSlot(unsigned int hashslot, robj **keys, unsigned int coun
n
=
zslFirstInRange
(
server
.
cluster
->
slots_to_keys
,
&
range
);
n
=
zslFirstInRange
(
server
.
cluster
->
slots_to_keys
,
&
range
);
while
(
n
&&
n
->
score
==
hashslot
&&
count
--
)
{
while
(
n
&&
n
->
score
==
hashslot
&&
count
--
)
{
keys
[
j
++
]
=
n
->
obj
;
keys
[
j
++
]
=
createStringObject
(
n
->
ele
,
sdslen
(
n
->
ele
))
;
n
=
n
->
level
[
0
].
forward
;
n
=
n
->
level
[
0
].
forward
;
}
}
return
j
;
return
j
;
...
@@ -1224,9 +1226,9 @@ unsigned int delKeysInSlot(unsigned int hashslot) {
...
@@ -1224,9 +1226,9 @@ unsigned int delKeysInSlot(unsigned int hashslot) {
n
=
zslFirstInRange
(
server
.
cluster
->
slots_to_keys
,
&
range
);
n
=
zslFirstInRange
(
server
.
cluster
->
slots_to_keys
,
&
range
);
while
(
n
&&
n
->
score
==
hashslot
)
{
while
(
n
&&
n
->
score
==
hashslot
)
{
robj
*
key
=
n
->
obj
;
sds
sdskey
=
n
->
ele
;
robj
*
key
=
createStringObject
(
sdskey
,
sdslen
(
sdskey
));
n
=
n
->
level
[
0
].
forward
;
/* Go to the next item before freeing it. */
n
=
n
->
level
[
0
].
forward
;
/* Go to the next item before freeing it. */
incrRefCount
(
key
);
/* Protect the object while freeing it. */
dbDelete
(
&
server
.
db
[
0
],
key
);
dbDelete
(
&
server
.
db
[
0
],
key
);
decrRefCount
(
key
);
decrRefCount
(
key
);
j
++
;
j
++
;
...
@@ -1248,7 +1250,7 @@ unsigned int countKeysInSlot(unsigned int hashslot) {
...
@@ -1248,7 +1250,7 @@ unsigned int countKeysInSlot(unsigned int hashslot) {
/* Use rank of first element, if any, to determine preliminary count */
/* Use rank of first element, if any, to determine preliminary count */
if
(
zn
!=
NULL
)
{
if
(
zn
!=
NULL
)
{
rank
=
zslGetRank
(
zsl
,
zn
->
score
,
zn
->
obj
);
rank
=
zslGetRank
(
zsl
,
zn
->
score
,
zn
->
ele
);
count
=
(
zsl
->
length
-
(
rank
-
1
));
count
=
(
zsl
->
length
-
(
rank
-
1
));
/* Find last element in range */
/* Find last element in range */
...
@@ -1256,7 +1258,7 @@ unsigned int countKeysInSlot(unsigned int hashslot) {
...
@@ -1256,7 +1258,7 @@ unsigned int countKeysInSlot(unsigned int hashslot) {
/* Use rank of last element, if any, to determine the actual count */
/* Use rank of last element, if any, to determine the actual count */
if
(
zn
!=
NULL
)
{
if
(
zn
!=
NULL
)
{
rank
=
zslGetRank
(
zsl
,
zn
->
score
,
zn
->
obj
);
rank
=
zslGetRank
(
zsl
,
zn
->
score
,
zn
->
ele
);
count
-=
(
zsl
->
length
-
rank
);
count
-=
(
zsl
->
length
-
rank
);
}
}
}
}
...
...
src/debug.c
View file @
a7c5be18
...
@@ -163,12 +163,9 @@ void computeDatasetDigest(unsigned char *final) {
...
@@ -163,12 +163,9 @@ void computeDatasetDigest(unsigned char *final) {
listTypeReleaseIterator
(
li
);
listTypeReleaseIterator
(
li
);
}
else
if
(
o
->
type
==
OBJ_SET
)
{
}
else
if
(
o
->
type
==
OBJ_SET
)
{
setTypeIterator
*
si
=
setTypeInitIterator
(
o
);
setTypeIterator
*
si
=
setTypeInitIterator
(
o
);
robj
*
ele
;
sds
sdsele
;
sds
sdsele
;
while
((
sdsele
=
setTypeNextObject
(
si
))
!=
NULL
)
{
while
((
sdsele
=
setTypeNextObject
(
si
))
!=
NULL
)
{
ele
=
createObject
(
OBJ_STRING
,
sdsele
);
xorDigest
(
digest
,
sdsele
,
sdslen
(
sdsele
));
xorObjectDigest
(
digest
,
ele
);
decrRefCount
(
ele
);
}
}
setTypeReleaseIterator
(
si
);
setTypeReleaseIterator
(
si
);
}
else
if
(
o
->
type
==
OBJ_ZSET
)
{
}
else
if
(
o
->
type
==
OBJ_ZSET
)
{
...
@@ -210,12 +207,12 @@ void computeDatasetDigest(unsigned char *final) {
...
@@ -210,12 +207,12 @@ void computeDatasetDigest(unsigned char *final) {
dictEntry
*
de
;
dictEntry
*
de
;
while
((
de
=
dictNext
(
di
))
!=
NULL
)
{
while
((
de
=
dictNext
(
di
))
!=
NULL
)
{
robj
*
eleobj
=
dictGetKey
(
de
);
sds
sdsele
=
dictGetKey
(
de
);
double
*
score
=
dictGetVal
(
de
);
double
*
score
=
dictGetVal
(
de
);
snprintf
(
buf
,
sizeof
(
buf
),
"%.17g"
,
*
score
);
snprintf
(
buf
,
sizeof
(
buf
),
"%.17g"
,
*
score
);
memset
(
eledigest
,
0
,
20
);
memset
(
eledigest
,
0
,
20
);
mix
Object
Digest
(
eledigest
,
eleobj
);
mixDigest
(
eledigest
,
sdsele
,
sdslen
(
sdsele
)
);
mixDigest
(
eledigest
,
buf
,
strlen
(
buf
));
mixDigest
(
eledigest
,
buf
,
strlen
(
buf
));
xorDigest
(
digest
,
eledigest
,
20
);
xorDigest
(
digest
,
eledigest
,
20
);
}
}
...
...
src/geo.c
View file @
a7c5be18
...
@@ -112,7 +112,7 @@ int extractLongLatOrReply(client *c, robj **argv,
...
@@ -112,7 +112,7 @@ int extractLongLatOrReply(client *c, robj **argv,
int
longLatFromMember
(
robj
*
zobj
,
robj
*
member
,
double
*
xy
)
{
int
longLatFromMember
(
robj
*
zobj
,
robj
*
member
,
double
*
xy
)
{
double
score
=
0
;
double
score
=
0
;
if
(
zsetScore
(
zobj
,
member
,
&
score
)
==
C_ERR
)
return
C_ERR
;
if
(
zsetScore
(
zobj
,
member
->
ptr
,
&
score
)
==
C_ERR
)
return
C_ERR
;
if
(
!
decodeGeohash
(
score
,
xy
))
return
C_ERR
;
if
(
!
decodeGeohash
(
score
,
xy
))
return
C_ERR
;
return
C_OK
;
return
C_OK
;
}
}
...
@@ -261,16 +261,14 @@ int geoGetPointsInRange(robj *zobj, double min, double max, double lon, double l
...
@@ -261,16 +261,14 @@ int geoGetPointsInRange(robj *zobj, double min, double max, double lon, double l
}
}
while
(
ln
)
{
while
(
ln
)
{
robj
*
o
=
ln
->
obj
;
sds
ele
=
ln
->
ele
;
/* Abort when the node is no longer in range. */
/* Abort when the node is no longer in range. */
if
(
!
zslValueLteMax
(
ln
->
score
,
&
range
))
if
(
!
zslValueLteMax
(
ln
->
score
,
&
range
))
break
;
break
;
member
=
(
o
->
encoding
==
OBJ_ENCODING_INT
)
?
ele
=
sdsdup
(
ele
);
sdsfromlonglong
((
long
)
o
->
ptr
)
:
if
(
geoAppendIfWithinRadius
(
ga
,
lon
,
lat
,
radius
,
ln
->
score
,
ele
)
sdsdup
(
o
->
ptr
);
==
C_ERR
)
sdsfree
(
ele
);
if
(
geoAppendIfWithinRadius
(
ga
,
lon
,
lat
,
radius
,
ln
->
score
,
member
)
==
C_ERR
)
sdsfree
(
member
);
ln
=
ln
->
level
[
0
].
forward
;
ln
=
ln
->
level
[
0
].
forward
;
}
}
}
}
...
@@ -606,7 +604,7 @@ void geohashCommand(client *c) {
...
@@ -606,7 +604,7 @@ void geohashCommand(client *c) {
addReplyMultiBulkLen
(
c
,
c
->
argc
-
2
);
addReplyMultiBulkLen
(
c
,
c
->
argc
-
2
);
for
(
j
=
2
;
j
<
c
->
argc
;
j
++
)
{
for
(
j
=
2
;
j
<
c
->
argc
;
j
++
)
{
double
score
;
double
score
;
if
(
zsetScore
(
zobj
,
c
->
argv
[
j
],
&
score
)
==
C_ERR
)
{
if
(
zsetScore
(
zobj
,
c
->
argv
[
j
]
->
ptr
,
&
score
)
==
C_ERR
)
{
addReply
(
c
,
shared
.
nullbulk
);
addReply
(
c
,
shared
.
nullbulk
);
}
else
{
}
else
{
/* The internal format we use for geocoding is a bit different
/* The internal format we use for geocoding is a bit different
...
@@ -660,7 +658,7 @@ void geoposCommand(client *c) {
...
@@ -660,7 +658,7 @@ void geoposCommand(client *c) {
addReplyMultiBulkLen
(
c
,
c
->
argc
-
2
);
addReplyMultiBulkLen
(
c
,
c
->
argc
-
2
);
for
(
j
=
2
;
j
<
c
->
argc
;
j
++
)
{
for
(
j
=
2
;
j
<
c
->
argc
;
j
++
)
{
double
score
;
double
score
;
if
(
zsetScore
(
zobj
,
c
->
argv
[
j
],
&
score
)
==
C_ERR
)
{
if
(
zsetScore
(
zobj
,
c
->
argv
[
j
]
->
ptr
,
&
score
)
==
C_ERR
)
{
addReply
(
c
,
shared
.
nullmultibulk
);
addReply
(
c
,
shared
.
nullmultibulk
);
}
else
{
}
else
{
/* Decode... */
/* Decode... */
...
@@ -700,8 +698,8 @@ void geodistCommand(client *c) {
...
@@ -700,8 +698,8 @@ void geodistCommand(client *c) {
/* Get the scores. We need both otherwise NULL is returned. */
/* Get the scores. We need both otherwise NULL is returned. */
double
score1
,
score2
,
xyxy
[
4
];
double
score1
,
score2
,
xyxy
[
4
];
if
(
zsetScore
(
zobj
,
c
->
argv
[
2
],
&
score1
)
==
C_ERR
||
if
(
zsetScore
(
zobj
,
c
->
argv
[
2
]
->
ptr
,
&
score1
)
==
C_ERR
||
zsetScore
(
zobj
,
c
->
argv
[
3
],
&
score2
)
==
C_ERR
)
zsetScore
(
zobj
,
c
->
argv
[
3
]
->
ptr
,
&
score2
)
==
C_ERR
)
{
{
addReply
(
c
,
shared
.
nullbulk
);
addReply
(
c
,
shared
.
nullbulk
);
return
;
return
;
...
...
src/rdb.c
View file @
a7c5be18
...
@@ -622,10 +622,11 @@ ssize_t rdbSaveObject(rio *rdb, robj *o) {
...
@@ -622,10 +622,11 @@ ssize_t rdbSaveObject(rio *rdb, robj *o) {
nwritten
+=
n
;
nwritten
+=
n
;
while
((
de
=
dictNext
(
di
))
!=
NULL
)
{
while
((
de
=
dictNext
(
di
))
!=
NULL
)
{
robj
*
eleobj
=
dictGetKey
(
de
);
sds
ele
=
dictGetKey
(
de
);
double
*
score
=
dictGetVal
(
de
);
double
*
score
=
dictGetVal
(
de
);
if
((
n
=
rdbSaveStringObject
(
rdb
,
eleobj
))
==
-
1
)
return
-
1
;
if
((
n
=
rdbSaveRawString
(
rdb
,(
unsigned
char
*
)
ele
,
sdslen
(
ele
)))
==
-
1
)
return
-
1
;
nwritten
+=
n
;
nwritten
+=
n
;
if
((
n
=
rdbSaveDoubleValue
(
rdb
,
*
score
))
==
-
1
)
return
-
1
;
if
((
n
=
rdbSaveDoubleValue
(
rdb
,
*
score
))
==
-
1
)
return
-
1
;
nwritten
+=
n
;
nwritten
+=
n
;
...
@@ -992,7 +993,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb) {
...
@@ -992,7 +993,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb) {
return
NULL
;
return
NULL
;
if
(
o
->
encoding
==
OBJ_ENCODING_INTSET
)
{
if
(
o
->
encoding
==
OBJ_ENCODING_INTSET
)
{
/* Fetch integer value from element */
/* Fetch integer value from element
.
*/
if
(
isSdsRepresentableAsLongLong
(
sdsele
,
&
llval
)
==
C_OK
)
{
if
(
isSdsRepresentableAsLongLong
(
sdsele
,
&
llval
)
==
C_OK
)
{
o
->
ptr
=
intsetAdd
(
o
->
ptr
,
llval
,
NULL
);
o
->
ptr
=
intsetAdd
(
o
->
ptr
,
llval
,
NULL
);
}
else
{
}
else
{
...
@@ -1002,7 +1003,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb) {
...
@@ -1002,7 +1003,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb) {
}
}
/* This will also be called when the set was just converted
/* This will also be called when the set was just converted
* to a regular hash table encoded set */
* to a regular hash table encoded set
.
*/
if
(
o
->
encoding
==
OBJ_ENCODING_HT
)
{
if
(
o
->
encoding
==
OBJ_ENCODING_HT
)
{
dictAdd
((
dict
*
)
o
->
ptr
,
sdsele
,
NULL
);
dictAdd
((
dict
*
)
o
->
ptr
,
sdsele
,
NULL
);
}
else
{
}
else
{
...
@@ -1010,7 +1011,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb) {
...
@@ -1010,7 +1011,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb) {
}
}
}
}
}
else
if
(
rdbtype
==
RDB_TYPE_ZSET
)
{
}
else
if
(
rdbtype
==
RDB_TYPE_ZSET
)
{
/* Read list/set value */
/* Read list/set value
.
*/
size_t
zsetlen
;
size_t
zsetlen
;
size_t
maxelelen
=
0
;
size_t
maxelelen
=
0
;
zset
*
zs
;
zset
*
zs
;
...
@@ -1019,23 +1020,21 @@ robj *rdbLoadObject(int rdbtype, rio *rdb) {
...
@@ -1019,23 +1020,21 @@ robj *rdbLoadObject(int rdbtype, rio *rdb) {
o
=
createZsetObject
();
o
=
createZsetObject
();
zs
=
o
->
ptr
;
zs
=
o
->
ptr
;
/* Load every single element of the
list/
set */
/* Load every single element of the
sorted
set
.
*/
while
(
zsetlen
--
)
{
while
(
zsetlen
--
)
{
robj
*
ele
;
sds
sds
ele
;
double
score
;
double
score
;
zskiplistNode
*
znode
;
zskiplistNode
*
znode
;
if
((
ele
=
rdb
LoadEncode
dStringObject
(
rdb
))
==
NULL
)
return
NULL
;
if
((
sds
ele
=
rdb
GenericLoa
dStringObject
(
rdb
,
RDB_LOAD_SDS
))
==
NULL
)
ele
=
tryObjectEncoding
(
ele
)
;
return
NULL
;
if
(
rdbLoadDoubleValue
(
rdb
,
&
score
)
==
-
1
)
return
NULL
;
if
(
rdbLoadDoubleValue
(
rdb
,
&
score
)
==
-
1
)
return
NULL
;
/* Don't care about integer-encoded strings. */
/* Don't care about integer-encoded strings. */
if
(
sdsEncodedObject
(
ele
)
&&
sdslen
(
ele
->
ptr
)
>
maxelelen
)
if
(
sdslen
(
sdsele
)
>
maxelelen
)
maxelelen
=
sdslen
(
sdsele
);
maxelelen
=
sdslen
(
ele
->
ptr
);
znode
=
zslInsert
(
zs
->
zsl
,
score
,
ele
);
znode
=
zslInsert
(
zs
->
zsl
,
score
,
sdsele
);
dictAdd
(
zs
->
dict
,
ele
,
&
znode
->
score
);
dictAdd
(
zs
->
dict
,
sdsele
,
&
znode
->
score
);
incrRefCount
(
ele
);
/* added to skiplist */
}
}
/* Convert *after* loading, since sorted sets are not stored ordered. */
/* Convert *after* loading, since sorted sets are not stored ordered. */
...
...
src/server.c
View file @
a7c5be18
...
@@ -554,11 +554,11 @@ dictType setDictType = {
...
@@ -554,11 +554,11 @@ dictType setDictType = {
/* Sorted sets hash (note: a skiplist is used in addition to the hash table) */
/* Sorted sets hash (note: a skiplist is used in addition to the hash table) */
dictType
zsetDictType
=
{
dictType
zsetDictType
=
{
dict
EncObj
Hash
,
/* hash function */
dict
Sds
Hash
,
/* hash function */
NULL
,
/* key dup */
NULL
,
/* key dup */
NULL
,
/* val dup */
NULL
,
/* val dup */
dict
EncObj
KeyCompare
,
/* key compare */
dict
Sds
KeyCompare
,
/* key compare */
dictObjectDestructor
,
/* key destructor
*/
NULL
,
/* Note: SDS string shared & freed by skiplist
*/
NULL
/* val destructor */
NULL
/* val destructor */
};
};
...
@@ -1428,8 +1428,8 @@ void createSharedObjects(void) {
...
@@ -1428,8 +1428,8 @@ void createSharedObjects(void) {
* actually used for their value but as a special object meaning
* actually used for their value but as a special object meaning
* respectively the minimum possible string and the maximum possible
* respectively the minimum possible string and the maximum possible
* string in string comparisons for the ZRANGEBYLEX command. */
* string in string comparisons for the ZRANGEBYLEX command. */
shared
.
minstring
=
createStringObject
(
"minstring"
,
9
);
shared
.
minstring
=
sdsnew
(
"minstring"
);
shared
.
maxstring
=
createStringObject
(
"maxstring"
,
9
);
shared
.
maxstring
=
sdsnew
(
"maxstring"
);
}
}
void
initServerConfig
(
void
)
{
void
initServerConfig
(
void
)
{
...
...
src/server.h
View file @
a7c5be18
...
@@ -612,16 +612,17 @@ struct sharedObjectsStruct {
...
@@ -612,16 +612,17 @@ struct sharedObjectsStruct {
*
masterdownerr
,
*
roslaveerr
,
*
execaborterr
,
*
noautherr
,
*
noreplicaserr
,
*
masterdownerr
,
*
roslaveerr
,
*
execaborterr
,
*
noautherr
,
*
noreplicaserr
,
*
busykeyerr
,
*
oomerr
,
*
plus
,
*
messagebulk
,
*
pmessagebulk
,
*
subscribebulk
,
*
busykeyerr
,
*
oomerr
,
*
plus
,
*
messagebulk
,
*
pmessagebulk
,
*
subscribebulk
,
*
unsubscribebulk
,
*
psubscribebulk
,
*
punsubscribebulk
,
*
del
,
*
rpop
,
*
lpop
,
*
unsubscribebulk
,
*
psubscribebulk
,
*
punsubscribebulk
,
*
del
,
*
rpop
,
*
lpop
,
*
lpush
,
*
emptyscan
,
*
minstring
,
*
maxstring
,
*
lpush
,
*
emptyscan
,
*
select
[
PROTO_SHARED_SELECT_CMDS
],
*
select
[
PROTO_SHARED_SELECT_CMDS
],
*
integers
[
OBJ_SHARED_INTEGERS
],
*
integers
[
OBJ_SHARED_INTEGERS
],
*
mbulkhdr
[
OBJ_SHARED_BULKHDR_LEN
],
/* "*<value>\r\n" */
*
mbulkhdr
[
OBJ_SHARED_BULKHDR_LEN
],
/* "*<value>\r\n" */
*
bulkhdr
[
OBJ_SHARED_BULKHDR_LEN
];
/* "$<value>\r\n" */
*
bulkhdr
[
OBJ_SHARED_BULKHDR_LEN
];
/* "$<value>\r\n" */
sds
minstring
,
maxstring
;
};
};
/* ZSETs use a specialized version of Skiplists */
/* ZSETs use a specialized version of Skiplists */
typedef
struct
zskiplistNode
{
typedef
struct
zskiplistNode
{
robj
*
obj
;
sds
ele
;
double
score
;
double
score
;
struct
zskiplistNode
*
backward
;
struct
zskiplistNode
*
backward
;
struct
zskiplistLevel
{
struct
zskiplistLevel
{
...
@@ -1261,15 +1262,15 @@ typedef struct {
...
@@ -1261,15 +1262,15 @@ typedef struct {
/* Struct to hold an inclusive/exclusive range spec by lexicographic comparison. */
/* Struct to hold an inclusive/exclusive range spec by lexicographic comparison. */
typedef
struct
{
typedef
struct
{
robj
*
min
,
*
max
;
/* May be set to shared.(minstring|maxstring) */
sds
min
,
max
;
/* May be set to shared.(minstring|maxstring) */
int
minex
,
maxex
;
/* are min or max exclusive? */
int
minex
,
maxex
;
/* are min or max exclusive? */
}
zlexrangespec
;
}
zlexrangespec
;
zskiplist
*
zslCreate
(
void
);
zskiplist
*
zslCreate
(
void
);
void
zslFree
(
zskiplist
*
zsl
);
void
zslFree
(
zskiplist
*
zsl
);
zskiplistNode
*
zslInsert
(
zskiplist
*
zsl
,
double
score
,
robj
*
obj
);
zskiplistNode
*
zslInsert
(
zskiplist
*
zsl
,
double
score
,
sds
ele
);
unsigned
char
*
zzlInsert
(
unsigned
char
*
zl
,
robj
*
ele
,
double
score
);
unsigned
char
*
zzlInsert
(
unsigned
char
*
zl
,
sds
ele
,
double
score
);
int
zslDelete
(
zskiplist
*
zsl
,
double
score
,
robj
*
obj
);
int
zslDelete
(
zskiplist
*
zsl
,
double
score
,
sds
ele
,
zskiplistNode
**
node
);
zskiplistNode
*
zslFirstInRange
(
zskiplist
*
zsl
,
zrangespec
*
range
);
zskiplistNode
*
zslFirstInRange
(
zskiplist
*
zsl
,
zrangespec
*
range
);
zskiplistNode
*
zslLastInRange
(
zskiplist
*
zsl
,
zrangespec
*
range
);
zskiplistNode
*
zslLastInRange
(
zskiplist
*
zsl
,
zrangespec
*
range
);
double
zzlGetScore
(
unsigned
char
*
sptr
);
double
zzlGetScore
(
unsigned
char
*
sptr
);
...
@@ -1277,8 +1278,8 @@ void zzlNext(unsigned char *zl, unsigned char **eptr, unsigned char **sptr);
...
@@ -1277,8 +1278,8 @@ void zzlNext(unsigned char *zl, unsigned char **eptr, unsigned char **sptr);
void
zzlPrev
(
unsigned
char
*
zl
,
unsigned
char
**
eptr
,
unsigned
char
**
sptr
);
void
zzlPrev
(
unsigned
char
*
zl
,
unsigned
char
**
eptr
,
unsigned
char
**
sptr
);
unsigned
int
zsetLength
(
robj
*
zobj
);
unsigned
int
zsetLength
(
robj
*
zobj
);
void
zsetConvert
(
robj
*
zobj
,
int
encoding
);
void
zsetConvert
(
robj
*
zobj
,
int
encoding
);
int
zsetScore
(
robj
*
zobj
,
robj
*
member
,
double
*
score
);
int
zsetScore
(
robj
*
zobj
,
sds
member
,
double
*
score
);
unsigned
long
zslGetRank
(
zskiplist
*
zsl
,
double
score
,
robj
*
o
);
unsigned
long
zslGetRank
(
zskiplist
*
zsl
,
double
score
,
sds
o
);
/* Core functions */
/* Core functions */
int
freeMemoryIfNeeded
(
void
);
int
freeMemoryIfNeeded
(
void
);
...
...
src/sort.c
View file @
a7c5be18
...
@@ -399,7 +399,7 @@ void sortCommand(client *c) {
...
@@ -399,7 +399,7 @@ void sortCommand(client *c) {
zset
*
zs
=
sortval
->
ptr
;
zset
*
zs
=
sortval
->
ptr
;
zskiplist
*
zsl
=
zs
->
zsl
;
zskiplist
*
zsl
=
zs
->
zsl
;
zskiplistNode
*
ln
;
zskiplistNode
*
ln
;
robj
*
ele
;
sds
sds
ele
;
int
rangelen
=
vectorlen
;
int
rangelen
=
vectorlen
;
/* Check if starting point is trivial, before doing log(N) lookup. */
/* Check if starting point is trivial, before doing log(N) lookup. */
...
@@ -417,8 +417,8 @@ void sortCommand(client *c) {
...
@@ -417,8 +417,8 @@ void sortCommand(client *c) {
while
(
rangelen
--
)
{
while
(
rangelen
--
)
{
serverAssertWithInfo
(
c
,
sortval
,
ln
!=
NULL
);
serverAssertWithInfo
(
c
,
sortval
,
ln
!=
NULL
);
ele
=
ln
->
obj
;
sds
ele
=
ln
->
ele
;
vector
[
j
].
obj
=
ele
;
vector
[
j
].
obj
=
createStringObject
(
sdsele
,
sdslen
(
sdsele
))
;
vector
[
j
].
u
.
score
=
0
;
vector
[
j
].
u
.
score
=
0
;
vector
[
j
].
u
.
cmpobj
=
NULL
;
vector
[
j
].
u
.
cmpobj
=
NULL
;
j
++
;
j
++
;
...
@@ -431,9 +431,11 @@ void sortCommand(client *c) {
...
@@ -431,9 +431,11 @@ void sortCommand(client *c) {
dict
*
set
=
((
zset
*
)
sortval
->
ptr
)
->
dict
;
dict
*
set
=
((
zset
*
)
sortval
->
ptr
)
->
dict
;
dictIterator
*
di
;
dictIterator
*
di
;
dictEntry
*
setele
;
dictEntry
*
setele
;
sds
sdsele
;
di
=
dictGetIterator
(
set
);
di
=
dictGetIterator
(
set
);
while
((
setele
=
dictNext
(
di
))
!=
NULL
)
{
while
((
setele
=
dictNext
(
di
))
!=
NULL
)
{
vector
[
j
].
obj
=
dictGetKey
(
setele
);
sdsele
=
dictGetKey
(
setele
);
vector
[
j
].
obj
=
createStringObject
(
sdsele
,
sdslen
(
sdsele
));
vector
[
j
].
u
.
score
=
0
;
vector
[
j
].
u
.
score
=
0
;
vector
[
j
].
u
.
cmpobj
=
NULL
;
vector
[
j
].
u
.
cmpobj
=
NULL
;
j
++
;
j
++
;
...
...
src/t_zset.c
View file @
a7c5be18
This diff is collapsed.
Click to expand it.
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