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
e19c5c8c
Commit
e19c5c8c
authored
Jun 04, 2020
by
antirez
Browse files
TCC: use threaded SUNION/DIFF only for large sets.
parent
712db71e
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/db.c
View file @
e19c5c8c
...
@@ -1772,7 +1772,9 @@ int lockedClientListMatch(void *a, void *b) {
...
@@ -1772,7 +1772,9 @@ int lockedClientListMatch(void *a, void *b) {
*
*
* When locking fails C_ERR is returned, otherwise C_OK is returned.
* When locking fails C_ERR is returned, otherwise C_OK is returned.
* Note that 'optr' may be populated with NULL if the key that is going
* Note that 'optr' may be populated with NULL if the key that is going
* to be locked is empty.
* to be locked is empty. If 'optr' is NULL, the object is not returned.
* This is often useful since we lookup the key and already have the object
* and later lock the key if needed (for instance if the value is large).
*
*
* Signaling of the need to lock keys is performed using the
* Signaling of the need to lock keys is performed using the
* wouldLockKey() API (XXX: yet to be implemented). Check the function
* wouldLockKey() API (XXX: yet to be implemented). Check the function
...
@@ -1818,7 +1820,7 @@ int lockKey(client *c, robj *key, int locktype, robj **optr) {
...
@@ -1818,7 +1820,7 @@ int lockKey(client *c, robj *key, int locktype, robj **optr) {
* that without crashing. So that command implementations don't
* that without crashing. So that command implementations don't
* have to do complex checks in the command line in case of repeating
* have to do complex checks in the command line in case of repeating
* keys. */
* keys. */
*
optr
=
lk
->
obj
;
if
(
optr
)
*
optr
=
lk
->
obj
;
return
C_OK
;
return
C_OK
;
}
}
incrRefCount
(
key
);
incrRefCount
(
key
);
...
@@ -1832,7 +1834,7 @@ int lockKey(client *c, robj *key, int locktype, robj **optr) {
...
@@ -1832,7 +1834,7 @@ int lockKey(client *c, robj *key, int locktype, robj **optr) {
* blocked handle, we can still track the original ID even if the
* blocked handle, we can still track the original ID even if the
* client is gone. */
* client is gone. */
dictSetUnsignedIntegerVal
(
de
,
c
->
id
);
dictSetUnsignedIntegerVal
(
de
,
c
->
id
);
*
optr
=
lk
->
obj
;
if
(
optr
)
*
optr
=
lk
->
obj
;
return
C_OK
;
return
C_OK
;
}
}
...
...
src/t_set.c
View file @
e19c5c8c
...
@@ -29,6 +29,10 @@
...
@@ -29,6 +29,10 @@
#include "server.h"
#include "server.h"
/* Use threaded execution, when available, if at least one of the sets
* involved is greater or equal to the threshold. */
#define THREADED_SET_SIZE_THRESHOLD 5000
/*-----------------------------------------------------------------------------
/*-----------------------------------------------------------------------------
* Set Commands
* Set Commands
*----------------------------------------------------------------------------*/
*----------------------------------------------------------------------------*/
...
@@ -1093,7 +1097,8 @@ void sunionDiffThreadedHalf(client *c, void *options) {
...
@@ -1093,7 +1097,8 @@ void sunionDiffThreadedHalf(client *c, void *options) {
void
sunionDiffGenericCommand
(
client
*
c
,
robj
**
setkeys
,
int
setnum
,
void
sunionDiffGenericCommand
(
client
*
c
,
robj
**
setkeys
,
int
setnum
,
robj
*
dstkey
,
int
op
,
int
sync
)
{
robj
*
dstkey
,
int
op
,
int
sync
)
{
robj
**
sets
=
zmalloc
(
sizeof
(
robj
*
)
*
setnum
);
robj
**
sets
=
zmalloc
(
sizeof
(
robj
*
)
*
setnum
);
int
threaded
=
(
dstkey
==
NULL
&&
!
sync
);
int
threaded_call_allowed
=
(
dstkey
==
NULL
&&
!
sync
);
int
threaded
=
0
;
for
(
int
j
=
0
;
j
<
setnum
;
j
++
)
{
for
(
int
j
=
0
;
j
<
setnum
;
j
++
)
{
robj
*
setobj
=
dstkey
?
robj
*
setobj
=
dstkey
?
...
@@ -1107,16 +1112,23 @@ void sunionDiffGenericCommand(client *c, robj **setkeys, int setnum,
...
@@ -1107,16 +1112,23 @@ void sunionDiffGenericCommand(client *c, robj **setkeys, int setnum,
zfree
(
sets
);
zfree
(
sets
);
return
;
return
;
}
}
sets
[
j
]
=
setobj
;
if
(
threaded_call_allowed
&&
setTypeSize
(
setobj
)
>=
THREADED_SET_SIZE_THRESHOLD
)
{
threaded
=
1
;
}
}
/* Try to lock the key if this is a threaded execution. If we
/* Try to lock the keys only if this is a threaded execution. If we
* fail we just revert to non threaded execution. */
* fail we just revert to non threaded execution. */
if
(
threaded
)
{
if
(
threaded
)
{
if
(
lockKey
(
c
,
setkeys
[
j
],
LOCKEDKEY_READ
,
&
setobj
)
==
C_ERR
)
{
for
(
int
j
=
0
;
j
<
setnum
;
j
++
)
{
if
(
lockKey
(
c
,
setkeys
[
j
],
LOCKEDKEY_READ
,
NULL
)
==
C_ERR
)
{
unlockAllKeys
(
c
);
unlockAllKeys
(
c
);
threaded
=
0
;
threaded
=
0
;
}
}
}
}
sets
[
j
]
=
setobj
;
}
}
struct
sunionDiffThreadOptions
*
opt
=
zmalloc
(
sizeof
(
*
opt
));
struct
sunionDiffThreadOptions
*
opt
=
zmalloc
(
sizeof
(
*
opt
));
...
@@ -1126,8 +1138,6 @@ void sunionDiffGenericCommand(client *c, robj **setkeys, int setnum,
...
@@ -1126,8 +1138,6 @@ void sunionDiffGenericCommand(client *c, robj **setkeys, int setnum,
opt
->
dstkey
=
dstkey
;
opt
->
dstkey
=
dstkey
;
opt
->
threaded
=
threaded
;
opt
->
threaded
=
threaded
;
/* TODO: Execute in threaded mode only if we have at least a
* large set. */
if
(
threaded
)
{
if
(
threaded
)
{
executeThreadedCommand
(
c
,
sunionDiffThreadedHalf
,
opt
);
executeThreadedCommand
(
c
,
sunionDiffThreadedHalf
,
opt
);
}
else
{
}
else
{
...
...
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