Commit 10e71b3d authored by Oran Agra's avatar Oran Agra Committed by antirez
Browse files

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.
parent edc0ed14
......@@ -1305,6 +1305,8 @@ int expireIfNeeded(redisDb *db, robj *key) {
/* -----------------------------------------------------------------------------
* 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
* (firstkey, lastkey, step). */
......@@ -1319,7 +1321,12 @@ int *getKeysUsingCommandTable(struct redisCommand *cmd,robj **argv, int argc, in
last = cmd->lastkey;
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) {
if (j >= argc) {
/* Modules commands, and standard commands with a not fixed number
......@@ -1329,7 +1336,7 @@ int *getKeysUsingCommandTable(struct redisCommand *cmd,robj **argv, int argc, in
* return no keys and expect the command implementation to report
* an arity or syntax error. */
if (cmd->flags & CMD_MODULE || cmd->arity < 0) {
zfree(keys);
getKeysFreeResult(keys);
*numkeys = 0;
return NULL;
} else {
......@@ -1365,6 +1372,7 @@ int *getKeysFromCommand(struct redisCommand *cmd, robj **argv, int argc, int *nu
/* Free the result of getKeysFromCommand. */
void getKeysFreeResult(int *result) {
if (result != getKeysTempBuffer)
zfree(result);
}
......@@ -1386,6 +1394,8 @@ int *zunionInterGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *nu
/* Keys in z{union,inter}store come from two places:
* argv[1] = storage key,
* argv[3...n] = keys to intersect */
keys = getKeysTempBuffer;
if (num+1>MAX_KEYS_BUFFER)
keys = zmalloc(sizeof(int)*(num+1));
/* Add all key positions for argv[3...n] to keys[] */
......@@ -1412,7 +1422,10 @@ int *evalGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys)
return NULL;
}
keys = getKeysTempBuffer;
if (num>MAX_KEYS_BUFFER)
keys = zmalloc(sizeof(int)*num);
*numkeys = num;
/* Add all key positions for argv[3...n] to keys[] */
......@@ -1433,7 +1446,7 @@ int *sortGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys)
UNUSED(cmd);
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. */
......@@ -1491,7 +1504,10 @@ int *migrateGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkey
}
}
keys = getKeysTempBuffer;
if (num>MAX_KEYS_BUFFER)
keys = zmalloc(sizeof(int)*num);
for (i = 0; i < num; i++) keys[i] = first+i;
*numkeys = num;
return keys;
......@@ -1524,6 +1540,8 @@ int *georadiusGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numk
* argv[1] = key,
* argv[5...n] = stored key if present
*/
keys = getKeysTempBuffer;
if (num>MAX_KEYS_BUFFER)
keys = zmalloc(sizeof(int) * num);
/* Add all key positions to keys[] */
......@@ -1542,7 +1560,7 @@ int *memoryGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys
UNUSED(cmd);
if (argc >= 3 && !strcasecmp(argv[1]->ptr,"usage")) {
keys = zmalloc(sizeof(int) * 1);
keys = getKeysTempBuffer;
keys[0] = 2;
*numkeys = 1;
return keys;
......@@ -1589,7 +1607,10 @@ int *xreadGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys)
num /= 2; /* We have half the keys as there are arguments because
there are also the IDs, one per key. */
keys = getKeysTempBuffer;
if (num>MAX_KEYS_BUFFER)
keys = zmalloc(sizeof(int) * num);
for (i = streams_pos+1; i < argc-num; i++) keys[i-streams_pos-1] = i;
*numkeys = num;
return keys;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment