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
6d7d1370
Commit
6d7d1370
authored
Apr 15, 2010
by
Pieter Noordhuis
Browse files
enable hash dereference in SORT on BY and GET
parent
6e9e463f
Changes
1
Show whitespace changes
Inline
Side-by-side
redis.c
View file @
6d7d1370
...
...
@@ -6470,16 +6470,16 @@ static redisSortOperation *createSortOperation(int type, robj *pattern) {
/* Return the value associated to the key with a name obtained
* substituting the first occurence of '*' in 'pattern' with 'subst' */
static
robj
*
lookupKeyByPattern
(
redisDb
*
db
,
robj
*
pattern
,
robj
*
subst
)
{
char
*
p
;
char
*
p
,
*
f
;
sds
spat
,
ssub
;
robj
keyobj
;
int
prefixlen
,
sublen
,
postfixlen
;
robj
keyobj
,
fieldobj
,
*
o
;
int
prefixlen
,
sublen
,
postfixlen
,
fieldlen
;
/* Expoit the internal sds representation to create a sds string allocated on the stack in order to make this function faster */
struct
{
long
len
;
long
free
;
char
buf
[
REDIS_SORTKEY_MAX
+
1
];
}
keyname
;
}
keyname
,
fieldname
;
/* If the pattern is "#" return the substitution object itself in order
* to implement the "SORT ... GET #" feature. */
...
...
@@ -6501,20 +6501,40 @@ static robj *lookupKeyByPattern(redisDb *db, robj *pattern, robj *subst) {
return
NULL
;
}
/* Find out if we're dealing with a hash dereference. */
if
((
f
=
strstr
(
p
+
1
,
"->"
))
!=
NULL
)
{
fieldlen
=
sdslen
(
spat
)
-
(
f
-
spat
);
/* this also copies \0 character */
memcpy
(
fieldname
.
buf
,
f
+
2
,
fieldlen
-
1
);
fieldname
.
len
=
fieldlen
-
2
;
}
else
{
fieldlen
=
0
;
}
prefixlen
=
p
-
spat
;
sublen
=
sdslen
(
ssub
);
postfixlen
=
sdslen
(
spat
)
-
(
prefixlen
+
1
);
postfixlen
=
sdslen
(
spat
)
-
(
prefixlen
+
1
)
-
fieldlen
;
memcpy
(
keyname
.
buf
,
spat
,
prefixlen
);
memcpy
(
keyname
.
buf
+
prefixlen
,
ssub
,
sublen
);
memcpy
(
keyname
.
buf
+
prefixlen
+
sublen
,
p
+
1
,
postfixlen
);
keyname
.
buf
[
prefixlen
+
sublen
+
postfixlen
]
=
'\0'
;
keyname
.
len
=
prefixlen
+
sublen
+
postfixlen
;
initStaticStringObject
(
keyobj
,((
char
*
)
&
keyname
)
+
(
sizeof
(
long
)
*
2
))
decrRefCount
(
subst
);
/* printf("lookup '%s' => %p\n", keyname.buf,de); */
return
lookupKeyRead
(
db
,
&
keyobj
);
/* Lookup substituted key */
initStaticStringObject
(
keyobj
,((
char
*
)
&
keyname
)
+
(
sizeof
(
long
)
*
2
));
o
=
lookupKeyRead
(
db
,
&
keyobj
);
/* Retrieve value from hash by the field name */
if
(
o
!=
NULL
&&
fieldlen
>
0
)
{
if
(
o
->
type
!=
REDIS_HASH
||
fieldname
.
len
<
1
)
{
return
NULL
;
}
initStaticStringObject
(
fieldobj
,((
char
*
)
&
fieldname
)
+
(
sizeof
(
long
)
*
2
));
o
=
hashGet
(
o
,
&
fieldobj
);
}
return
o
;
}
/* sortCompare() is used by qsort in sortCommand(). Given that qsort_r with
...
...
@@ -6683,12 +6703,19 @@ static void sortCommand(redisClient *c) {
/* Now it's time to load the right scores in the sorting vector */
if
(
dontsort
==
0
)
{
for
(
j
=
0
;
j
<
vectorlen
;
j
++
)
{
if
(
sortby
)
{
robj
*
byval
;
if
(
sortby
)
{
/* lookup value to sort by */
byval
=
lookupKeyByPattern
(
c
->
db
,
sortby
,
vector
[
j
].
obj
);
if
(
!
byval
||
byval
->
type
!=
REDIS_STRING
)
continue
;
}
else
{
/* use object itself to sort by */
byval
=
vector
[
j
].
obj
;
}
if
(
alpha
)
{
/* getDecodedObject increments refcount, so the corresponding
* decrRefCount will clean up values coming from a zipmap. */
vector
[
j
].
u
.
cmpobj
=
getDecodedObject
(
byval
);
}
else
{
if
(
byval
->
encoding
==
REDIS_ENCODING_RAW
)
{
...
...
@@ -6702,17 +6729,11 @@ static void sortCommand(redisClient *c) {
}
else
redisAssert
(
1
!=
1
);
}
}
}
else
{
if
(
!
alpha
)
{
if
(
vector
[
j
].
obj
->
encoding
==
REDIS_ENCODING_RAW
)
vector
[
j
].
u
.
score
=
strtod
(
vector
[
j
].
obj
->
ptr
,
NULL
);
else
{
if
(
vector
[
j
].
obj
->
encoding
==
REDIS_ENCODING_INT
)
vector
[
j
].
u
.
score
=
(
long
)
vector
[
j
].
obj
->
ptr
;
else
redisAssert
(
1
!=
1
);
}
/* clean up immediately if this value came from a zipmap */
if
(
byval
->
refcount
==
0
)
{
byval
->
refcount
=
1
;
decrRefCount
(
byval
);
}
}
}
...
...
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