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
a03611e1
Commit
a03611e1
authored
May 31, 2010
by
Pieter Noordhuis
Browse files
update SORT to work with the dual list encoding
parent
1cd92e7f
Changes
1
Hide whitespace changes
Inline
Side-by-side
redis.c
View file @
a03611e1
...
@@ -7210,7 +7210,7 @@ static int sortCompare(const void *s1, const void *s2) {
...
@@ -7210,7 +7210,7 @@ static int sortCompare(const void *s1, const void *s2) {
* is optimized for speed and a bit less for readability */
* is optimized for speed and a bit less for readability */
static
void
sortCommand
(
redisClient
*
c
)
{
static
void
sortCommand
(
redisClient
*
c
)
{
list
*
operations
;
list
*
operations
;
int
outputlen
=
0
;
unsigned
int
outputlen
=
0
;
int
desc
=
0
,
alpha
=
0
;
int
desc
=
0
,
alpha
=
0
;
int
limit_start
=
0
,
limit_count
=
-
1
,
start
,
end
;
int
limit_start
=
0
,
limit_count
=
-
1
,
start
,
end
;
int
j
,
dontsort
=
0
,
vectorlen
;
int
j
,
dontsort
=
0
,
vectorlen
;
...
@@ -7280,7 +7280,7 @@ static void sortCommand(redisClient *c) {
...
@@ -7280,7 +7280,7 @@ static void sortCommand(redisClient *c) {
/* Load the sorting vector with all the objects to sort */
/* Load the sorting vector with all the objects to sort */
switch
(
sortval
->
type
)
{
switch
(
sortval
->
type
)
{
case
REDIS_LIST
:
vectorlen
=
l
ist
Length
(
(
list
*
)
sortval
->
ptr
);
break
;
case
REDIS_LIST
:
vectorlen
=
lLength
(
sortval
);
break
;
case
REDIS_SET
:
vectorlen
=
dictSize
((
dict
*
)
sortval
->
ptr
);
break
;
case
REDIS_SET
:
vectorlen
=
dictSize
((
dict
*
)
sortval
->
ptr
);
break
;
case
REDIS_ZSET
:
vectorlen
=
dictSize
(((
zset
*
)
sortval
->
ptr
)
->
dict
);
break
;
case
REDIS_ZSET
:
vectorlen
=
dictSize
(((
zset
*
)
sortval
->
ptr
)
->
dict
);
break
;
default:
vectorlen
=
0
;
redisPanic
(
"Bad SORT type"
);
/* Avoid GCC warning */
default:
vectorlen
=
0
;
redisPanic
(
"Bad SORT type"
);
/* Avoid GCC warning */
...
@@ -7289,18 +7289,15 @@ static void sortCommand(redisClient *c) {
...
@@ -7289,18 +7289,15 @@ static void sortCommand(redisClient *c) {
j
=
0
;
j
=
0
;
if
(
sortval
->
type
==
REDIS_LIST
)
{
if
(
sortval
->
type
==
REDIS_LIST
)
{
list
*
list
=
sortval
->
ptr
;
lIterator
*
li
=
lInitIterator
(
sortval
,
0
,
REDIS_TAIL
);
listNode
*
ln
;
lEntry
entry
;
listIter
li
;
while
(
lNext
(
li
,
&
entry
))
{
vector
[
j
].
obj
=
lGet
(
&
entry
);
listRewind
(
list
,
&
li
);
while
((
ln
=
listNext
(
&
li
)))
{
robj
*
ele
=
ln
->
value
;
vector
[
j
].
obj
=
ele
;
vector
[
j
].
u
.
score
=
0
;
vector
[
j
].
u
.
score
=
0
;
vector
[
j
].
u
.
cmpobj
=
NULL
;
vector
[
j
].
u
.
cmpobj
=
NULL
;
j
++
;
j
++
;
}
}
lReleaseIterator
(
li
);
}
else
{
}
else
{
dict
*
set
;
dict
*
set
;
dictIterator
*
di
;
dictIterator
*
di
;
...
@@ -7410,8 +7407,12 @@ static void sortCommand(redisClient *c) {
...
@@ -7410,8 +7407,12 @@ static void sortCommand(redisClient *c) {
}
}
}
}
}
else
{
}
else
{
robj
*
listObject
=
createListObject
();
robj
*
sobj
;
list
*
listPtr
=
(
list
*
)
listObject
->
ptr
;
if
(
outputlen
>
server
.
list_max_ziplist_entries
)
{
sobj
=
createListObject
();
}
else
{
sobj
=
createZiplistObject
();
}
/* STORE option specified, set the sorting result as a List object */
/* STORE option specified, set the sorting result as a List object */
for
(
j
=
start
;
j
<=
end
;
j
++
)
{
for
(
j
=
start
;
j
<=
end
;
j
++
)
{
...
@@ -7419,31 +7420,30 @@ static void sortCommand(redisClient *c) {
...
@@ -7419,31 +7420,30 @@ static void sortCommand(redisClient *c) {
listIter
li
;
listIter
li
;
if
(
!
getop
)
{
if
(
!
getop
)
{
listAddNodeTail
(
listPtr
,
vector
[
j
].
obj
);
lPush
(
sobj
,
vector
[
j
].
obj
,
REDIS_TAIL
);
incrRefCount
(
vector
[
j
].
obj
);
}
else
{
}
listRewind
(
operations
,
&
li
);
listRewind
(
operations
,
&
li
);
while
((
ln
=
listNext
(
&
li
)))
{
while
((
ln
=
listNext
(
&
li
)))
{
redisSortOperation
*
sop
=
ln
->
value
;
redisSortOperation
*
sop
=
ln
->
value
;
robj
*
val
=
lookupKeyByPattern
(
c
->
db
,
sop
->
pattern
,
robj
*
val
=
lookupKeyByPattern
(
c
->
db
,
sop
->
pattern
,
vector
[
j
].
obj
);
vector
[
j
].
obj
);
if
(
sop
->
type
==
REDIS_SORT_GET
)
{
if
(
sop
->
type
==
REDIS_SORT_GET
)
{
if
(
!
val
)
{
if
(
!
val
)
val
=
createStringObject
(
""
,
0
);
listAddNodeTail
(
listPtr
,
createStringObject
(
""
,
0
));
/* lPush does an incrRefCount, so we should take care
* care of the incremented refcount caused by either
* lookupKeyByPattern or createStringObject("",0) */
lPush
(
sobj
,
val
,
REDIS_TAIL
);
decrRefCount
(
val
);
}
else
{
}
else
{
/* We should do a incrRefCount on val because it is
/* always fails */
* added to the list, but also a decrRefCount because
redisAssert
(
sop
->
type
==
REDIS_SORT_GET
);
* it is returned by lookupKeyByPattern. This results
* in doing nothing at all. */
listAddNodeTail
(
listPtr
,
val
);
}
}
}
else
{
redisAssert
(
sop
->
type
==
REDIS_SORT_GET
);
/* always fails */
}
}
}
}
}
}
if
(
dictReplace
(
c
->
db
->
dict
,
storekey
,
listObject
))
{
if
(
dictReplace
(
c
->
db
->
dict
,
storekey
,
sobj
))
{
incrRefCount
(
storekey
);
incrRefCount
(
storekey
);
}
}
/* Note: we add 1 because the DB is dirty anyway since even if the
/* Note: we add 1 because the DB is dirty anyway since even if the
...
@@ -7454,6 +7454,9 @@ static void sortCommand(redisClient *c) {
...
@@ -7454,6 +7454,9 @@ static void sortCommand(redisClient *c) {
}
}
/* Cleanup */
/* Cleanup */
if
(
sortval
->
type
==
REDIS_LIST
)
for
(
j
=
0
;
j
<
vectorlen
;
j
++
)
decrRefCount
(
vector
[
j
].
obj
);
decrRefCount
(
sortval
);
decrRefCount
(
sortval
);
listRelease
(
operations
);
listRelease
(
operations
);
for
(
j
=
0
;
j
<
vectorlen
;
j
++
)
{
for
(
j
=
0
;
j
<
vectorlen
;
j
++
)
{
...
...
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