Optimize temporary memory allocations for getKeysFromCommand mechanism
now that we may use it more often (ACL), these excessive calls to malloc and free can become an overhead.
This commit is contained in:
parent
44ac202fbf
commit
774d8cd721
29
src/db.c
29
src/db.c
@ -1292,6 +1292,8 @@ int expireIfNeeded(redisDb *db, robj *key) {
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* API to get key arguments from commands
|
* API to get key arguments from commands
|
||||||
* ---------------------------------------------------------------------------*/
|
* ---------------------------------------------------------------------------*/
|
||||||
|
#define MAX_KEYS_BUFFER 65536
|
||||||
|
static int getKeysTempBuffer[MAX_KEYS_BUFFER];
|
||||||
|
|
||||||
/* The base case is to use the keys position as given in the command table
|
/* The base case is to use the keys position as given in the command table
|
||||||
* (firstkey, lastkey, step). */
|
* (firstkey, lastkey, step). */
|
||||||
@ -1306,7 +1308,12 @@ int *getKeysUsingCommandTable(struct redisCommand *cmd,robj **argv, int argc, in
|
|||||||
|
|
||||||
last = cmd->lastkey;
|
last = cmd->lastkey;
|
||||||
if (last < 0) last = argc+last;
|
if (last < 0) last = argc+last;
|
||||||
keys = zmalloc(sizeof(int)*((last - cmd->firstkey)+1));
|
|
||||||
|
int count = ((last - cmd->firstkey)+1);
|
||||||
|
keys = getKeysTempBuffer;
|
||||||
|
if (count > MAX_KEYS_BUFFER)
|
||||||
|
keys = zmalloc(sizeof(int)*count);
|
||||||
|
|
||||||
for (j = cmd->firstkey; j <= last; j += cmd->keystep) {
|
for (j = cmd->firstkey; j <= last; j += cmd->keystep) {
|
||||||
if (j >= argc) {
|
if (j >= argc) {
|
||||||
/* Modules commands, and standard commands with a not fixed number
|
/* Modules commands, and standard commands with a not fixed number
|
||||||
@ -1316,7 +1323,7 @@ int *getKeysUsingCommandTable(struct redisCommand *cmd,robj **argv, int argc, in
|
|||||||
* return no keys and expect the command implementation to report
|
* return no keys and expect the command implementation to report
|
||||||
* an arity or syntax error. */
|
* an arity or syntax error. */
|
||||||
if (cmd->flags & CMD_MODULE || cmd->arity < 0) {
|
if (cmd->flags & CMD_MODULE || cmd->arity < 0) {
|
||||||
zfree(keys);
|
getKeysFreeResult(keys);
|
||||||
*numkeys = 0;
|
*numkeys = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
@ -1352,6 +1359,7 @@ int *getKeysFromCommand(struct redisCommand *cmd, robj **argv, int argc, int *nu
|
|||||||
|
|
||||||
/* Free the result of getKeysFromCommand. */
|
/* Free the result of getKeysFromCommand. */
|
||||||
void getKeysFreeResult(int *result) {
|
void getKeysFreeResult(int *result) {
|
||||||
|
if (result != getKeysTempBuffer)
|
||||||
zfree(result);
|
zfree(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1373,6 +1381,8 @@ int *zunionInterGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *nu
|
|||||||
/* Keys in z{union,inter}store come from two places:
|
/* Keys in z{union,inter}store come from two places:
|
||||||
* argv[1] = storage key,
|
* argv[1] = storage key,
|
||||||
* argv[3...n] = keys to intersect */
|
* argv[3...n] = keys to intersect */
|
||||||
|
keys = getKeysTempBuffer;
|
||||||
|
if (num+1>MAX_KEYS_BUFFER)
|
||||||
keys = zmalloc(sizeof(int)*(num+1));
|
keys = zmalloc(sizeof(int)*(num+1));
|
||||||
|
|
||||||
/* Add all key positions for argv[3...n] to keys[] */
|
/* Add all key positions for argv[3...n] to keys[] */
|
||||||
@ -1399,7 +1409,10 @@ int *evalGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
keys = getKeysTempBuffer;
|
||||||
|
if (num>MAX_KEYS_BUFFER)
|
||||||
keys = zmalloc(sizeof(int)*num);
|
keys = zmalloc(sizeof(int)*num);
|
||||||
|
|
||||||
*numkeys = num;
|
*numkeys = num;
|
||||||
|
|
||||||
/* Add all key positions for argv[3...n] to keys[] */
|
/* Add all key positions for argv[3...n] to keys[] */
|
||||||
@ -1420,7 +1433,7 @@ int *sortGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys)
|
|||||||
UNUSED(cmd);
|
UNUSED(cmd);
|
||||||
|
|
||||||
num = 0;
|
num = 0;
|
||||||
keys = zmalloc(sizeof(int)*2); /* Alloc 2 places for the worst case. */
|
keys = getKeysTempBuffer; /* Alloc 2 places for the worst case. */
|
||||||
|
|
||||||
keys[num++] = 1; /* <sort-key> is always present. */
|
keys[num++] = 1; /* <sort-key> is always present. */
|
||||||
|
|
||||||
@ -1478,7 +1491,10 @@ int *migrateGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkey
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
keys = getKeysTempBuffer;
|
||||||
|
if (num>MAX_KEYS_BUFFER)
|
||||||
keys = zmalloc(sizeof(int)*num);
|
keys = zmalloc(sizeof(int)*num);
|
||||||
|
|
||||||
for (i = 0; i < num; i++) keys[i] = first+i;
|
for (i = 0; i < num; i++) keys[i] = first+i;
|
||||||
*numkeys = num;
|
*numkeys = num;
|
||||||
return keys;
|
return keys;
|
||||||
@ -1511,6 +1527,8 @@ int *georadiusGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numk
|
|||||||
* argv[1] = key,
|
* argv[1] = key,
|
||||||
* argv[5...n] = stored key if present
|
* argv[5...n] = stored key if present
|
||||||
*/
|
*/
|
||||||
|
keys = getKeysTempBuffer;
|
||||||
|
if (num>MAX_KEYS_BUFFER)
|
||||||
keys = zmalloc(sizeof(int) * num);
|
keys = zmalloc(sizeof(int) * num);
|
||||||
|
|
||||||
/* Add all key positions to keys[] */
|
/* Add all key positions to keys[] */
|
||||||
@ -1529,7 +1547,7 @@ int *memoryGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys
|
|||||||
UNUSED(cmd);
|
UNUSED(cmd);
|
||||||
|
|
||||||
if (argc >= 3 && !strcasecmp(argv[1]->ptr,"usage")) {
|
if (argc >= 3 && !strcasecmp(argv[1]->ptr,"usage")) {
|
||||||
keys = zmalloc(sizeof(int) * 1);
|
keys = getKeysTempBuffer;
|
||||||
keys[0] = 2;
|
keys[0] = 2;
|
||||||
*numkeys = 1;
|
*numkeys = 1;
|
||||||
return keys;
|
return keys;
|
||||||
@ -1576,7 +1594,10 @@ int *xreadGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys)
|
|||||||
num /= 2; /* We have half the keys as there are arguments because
|
num /= 2; /* We have half the keys as there are arguments because
|
||||||
there are also the IDs, one per key. */
|
there are also the IDs, one per key. */
|
||||||
|
|
||||||
|
keys = getKeysTempBuffer;
|
||||||
|
if (num>MAX_KEYS_BUFFER)
|
||||||
keys = zmalloc(sizeof(int) * num);
|
keys = zmalloc(sizeof(int) * num);
|
||||||
|
|
||||||
for (i = streams_pos+1; i < argc-num; i++) keys[i-streams_pos-1] = i;
|
for (i = streams_pos+1; i < argc-num; i++) keys[i-streams_pos-1] = i;
|
||||||
*numkeys = num;
|
*numkeys = num;
|
||||||
return keys;
|
return keys;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user