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) { ...@@ -1305,6 +1305,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). */
...@@ -1319,7 +1321,12 @@ int *getKeysUsingCommandTable(struct redisCommand *cmd,robj **argv, int argc, in ...@@ -1319,7 +1321,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
...@@ -1329,7 +1336,7 @@ int *getKeysUsingCommandTable(struct redisCommand *cmd,robj **argv, int argc, in ...@@ -1329,7 +1336,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 {
...@@ -1365,7 +1372,8 @@ int *getKeysFromCommand(struct redisCommand *cmd, robj **argv, int argc, int *nu ...@@ -1365,7 +1372,8 @@ 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) {
zfree(result); if (result != getKeysTempBuffer)
zfree(result);
} }
/* Helper function to extract keys from following commands: /* Helper function to extract keys from following commands:
...@@ -1386,7 +1394,9 @@ int *zunionInterGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *nu ...@@ -1386,7 +1394,9 @@ 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 = zmalloc(sizeof(int)*(num+1)); keys = getKeysTempBuffer;
if (num+1>MAX_KEYS_BUFFER)
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[] */
for (i = 0; i < num; i++) keys[i] = 3+i; for (i = 0; i < num; i++) keys[i] = 3+i;
...@@ -1412,7 +1422,10 @@ int *evalGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys) ...@@ -1412,7 +1422,10 @@ int *evalGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys)
return NULL; return NULL;
} }
keys = zmalloc(sizeof(int)*num); keys = getKeysTempBuffer;
if (num>MAX_KEYS_BUFFER)
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[] */
...@@ -1433,7 +1446,7 @@ int *sortGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys) ...@@ -1433,7 +1446,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. */
...@@ -1491,7 +1504,10 @@ int *migrateGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkey ...@@ -1491,7 +1504,10 @@ int *migrateGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkey
} }
} }
keys = zmalloc(sizeof(int)*num); keys = getKeysTempBuffer;
if (num>MAX_KEYS_BUFFER)
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;
...@@ -1524,7 +1540,9 @@ int *georadiusGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numk ...@@ -1524,7 +1540,9 @@ 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 = zmalloc(sizeof(int) * num); keys = getKeysTempBuffer;
if (num>MAX_KEYS_BUFFER)
keys = zmalloc(sizeof(int) * num);
/* Add all key positions to keys[] */ /* Add all key positions to keys[] */
keys[0] = 1; keys[0] = 1;
...@@ -1542,7 +1560,7 @@ int *memoryGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys ...@@ -1542,7 +1560,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;
...@@ -1589,7 +1607,10 @@ int *xreadGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys) ...@@ -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 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 = zmalloc(sizeof(int) * num); 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; for (i = streams_pos+1; i < argc-num; i++) keys[i-streams_pos-1] = i;
*numkeys = num; *numkeys = num;
return keys; 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