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
b287c9bb
Commit
b287c9bb
authored
Mar 08, 2010
by
Pieter Noordhuis
Browse files
use ZMERGE as starting point
parent
cbba7dd7
Changes
3
Hide whitespace changes
Inline
Side-by-side
redis-cli.c
View file @
b287c9bb
...
...
@@ -101,6 +101,8 @@ static struct redisCommand cmdTable[] = {
{
"zincrby"
,
4
,
REDIS_CMD_BULK
},
{
"zrem"
,
3
,
REDIS_CMD_BULK
},
{
"zremrangebyscore"
,
4
,
REDIS_CMD_INLINE
},
{
"zmerge"
,
-
3
,
REDIS_CMD_INLINE
},
{
"zmergeweighed"
,
-
4
,
REDIS_CMD_INLINE
},
{
"zrange"
,
-
4
,
REDIS_CMD_INLINE
},
{
"zrank"
,
3
,
REDIS_CMD_BULK
},
{
"zrangebyscore"
,
-
4
,
REDIS_CMD_INLINE
},
...
...
redis.c
View file @
b287c9bb
...
...
@@ -675,6 +675,8 @@ static void substrCommand(redisClient *c);
static
void
zrankCommand
(
redisClient
*
c
);
static
void
hsetCommand
(
redisClient
*
c
);
static
void
hgetCommand
(
redisClient
*
c
);
static
void
zmergeCommand
(
redisClient
*
c
);
static
void
zmergeweighedCommand
(
redisClient
*
c
);
/*================================= Globals ================================= */
...
...
@@ -722,6 +724,8 @@ static struct redisCommand cmdTable[] = {
{
"zincrby"
,
zincrbyCommand
,
4
,
REDIS_CMD_BULK
|
REDIS_CMD_DENYOOM
,
1
,
1
,
1
},
{
"zrem"
,
zremCommand
,
3
,
REDIS_CMD_BULK
,
1
,
1
,
1
},
{
"zremrangebyscore"
,
zremrangebyscoreCommand
,
4
,
REDIS_CMD_INLINE
,
1
,
1
,
1
},
{
"zmerge"
,
zmergeCommand
,
-
3
,
REDIS_CMD_INLINE
|
REDIS_CMD_DENYOOM
,
2
,
-
1
,
1
},
{
"zmergeweighed"
,
zmergeweighedCommand
,
-
4
,
REDIS_CMD_INLINE
|
REDIS_CMD_DENYOOM
,
2
,
-
2
,
2
},
{
"zrange"
,
zrangeCommand
,
-
4
,
REDIS_CMD_INLINE
,
1
,
1
,
1
},
{
"zrangebyscore"
,
zrangebyscoreCommand
,
-
4
,
REDIS_CMD_INLINE
,
1
,
1
,
1
},
{
"zcount"
,
zcountCommand
,
4
,
REDIS_CMD_INLINE
,
1
,
1
,
1
},
...
...
@@ -5325,6 +5329,105 @@ static void zremrangebyscoreCommand(redisClient *c) {
}
}
/* This command merges 2 or more zsets to a destination. When an element
* does not exist in a certain set, score 0 is assumed. The score for an
* element across sets is summed. */
static
void
zmergeGenericCommand
(
redisClient
*
c
,
int
readweights
)
{
int
i
,
j
,
zsetnum
;
dict
**
srcdict
;
double
*
weights
;
robj
*
dstkey
=
c
->
argv
[
1
],
*
dstobj
;
zset
*
dst
;
dictIterator
*
di
;
dictEntry
*
de
;
zsetnum
=
c
->
argc
-
2
;
if
(
readweights
)
{
/* force number of arguments to be even */
if
(
zsetnum
%
2
>
0
)
{
addReplySds
(
c
,
sdsnew
(
"-ERR wrong number of arguments for ZMERGEWEIGHED
\r\n
"
));
return
;
}
zsetnum
/=
2
;
}
if
(
!
zsetnum
)
{
addReply
(
c
,
shared
.
syntaxerr
);
return
;
}
srcdict
=
zmalloc
(
sizeof
(
dict
*
)
*
zsetnum
);
weights
=
zmalloc
(
sizeof
(
double
)
*
zsetnum
);
for
(
i
=
0
;
i
<
zsetnum
;
i
++
)
{
if
(
readweights
)
{
j
=
2
+
2
*
i
;
weights
[
i
]
=
strtod
(
c
->
argv
[
j
+
1
]
->
ptr
,
NULL
);
}
else
{
j
=
2
+
i
;
weights
[
i
]
=
1
.
0
;
}
robj
*
zsetobj
=
lookupKeyWrite
(
c
->
db
,
c
->
argv
[
j
]);
if
(
!
zsetobj
)
{
srcdict
[
i
]
=
NULL
;
}
else
{
if
(
zsetobj
->
type
!=
REDIS_ZSET
)
{
zfree
(
srcdict
);
zfree
(
weights
);
addReply
(
c
,
shared
.
wrongtypeerr
);
return
;
}
srcdict
[
i
]
=
((
zset
*
)
zsetobj
->
ptr
)
->
dict
;
}
}
dstobj
=
createZsetObject
();
dst
=
dstobj
->
ptr
;
for
(
i
=
0
;
i
<
zsetnum
;
i
++
)
{
if
(
!
srcdict
[
i
])
continue
;
di
=
dictGetIterator
(
srcdict
[
i
]);
while
((
de
=
dictNext
(
di
))
!=
NULL
)
{
/* skip key when already processed */
if
(
dictFind
(
dst
->
dict
,
dictGetEntryKey
(
de
))
!=
NULL
)
continue
;
double
*
score
=
zmalloc
(
sizeof
(
double
));
*
score
=
0
.
0
;
for
(
j
=
0
;
j
<
zsetnum
;
j
++
)
{
if
(
!
srcdict
[
j
])
continue
;
dictEntry
*
other
=
dictFind
(
srcdict
[
j
],
dictGetEntryKey
(
de
));
if
(
other
)
{
*
score
=
*
score
+
weights
[
j
]
*
(
*
(
double
*
)
dictGetEntryVal
(
other
));
}
}
robj
*
o
=
dictGetEntryKey
(
de
);
dictAdd
(
dst
->
dict
,
o
,
score
);
incrRefCount
(
o
);
/* added to dictionary */
zslInsert
(
dst
->
zsl
,
*
score
,
o
);
incrRefCount
(
o
);
/* added to skiplist */
}
dictReleaseIterator
(
di
);
}
deleteKey
(
c
->
db
,
dstkey
);
dictAdd
(
c
->
db
->
dict
,
dstkey
,
dstobj
);
incrRefCount
(
dstkey
);
addReplyLong
(
c
,
dst
->
zsl
->
length
);
server
.
dirty
++
;
zfree
(
srcdict
);
zfree
(
weights
);
}
static
void
zmergeCommand
(
redisClient
*
c
)
{
zmergeGenericCommand
(
c
,
0
);
}
static
void
zmergeweighedCommand
(
redisClient
*
c
)
{
zmergeGenericCommand
(
c
,
1
);
}
static
void
zrangeGenericCommand
(
redisClient
*
c
,
int
reverse
)
{
robj
*
o
;
int
start
=
atoi
(
c
->
argv
[
2
]
->
ptr
);
...
...
test-redis.tcl
View file @
b287c9bb
...
...
@@ -1462,6 +1462,21 @@ proc main {server port} {
list
[
$r
zremrangebyscore zset -inf +inf
]
[
$r
zrange zset 0 -1
]
}
{
5
{}}
test
{
ZMERGE basics
}
{
$r del zseta zsetb zsetc
$r zadd zseta 1 a
$r zadd zseta 2 b
$r zadd zseta 3 c
$r zadd zsetb 1 b
$r zadd zsetb 2 c
$r zadd zsetb 3 d
list
[
$r
zmerge zsetc zseta zsetb
]
[
$r
zrange zsetc 0 -1 withscores
]
}
{
4
{
a 1 b 3 d 3 c 5
}}
test
{
ZMERGEWEIGHED basics
}
{
list
[
$r
zmergeweighed zsetc zseta 2 zsetb 3
]
[
$r
zrange zsetc 0 -1 withscores
]
}
{
4
{
a 2 b 7 d 9 c 12
}}
test
{
SORT against sorted sets
}
{
$r del zset
$r zadd zset 1 a
...
...
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