summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSalvatore Sanfilippo <antirez@gmail.com>2020-03-02 16:48:05 +0100
committerGitHub <noreply@github.com>2020-03-02 16:48:05 +0100
commit7ca81170c7e98a4f70f203dd1afe027efe3aed89 (patch)
treed027841aea735326cf93149397f5b9485c67ebb3
parentc8ae90fef64c829cd1ac50c29e5912807c2577d5 (diff)
parent774d8cd721055b768dbffbf5c6b2fa9d6310126e (diff)
downloadredis-7ca81170c7e98a4f70f203dd1afe027efe3aed89.tar.gz
Merge pull request #6836 from oranagra/opt_get_keys_malloc
Optimize temporary memory allocations for getKeysFromCommand mechanism
-rw-r--r--src/db.c41
1 files changed, 31 insertions, 10 deletions
diff --git a/src/db.c b/src/db.c
index 8a0242d9e..6c5d4b4d4 100644
--- a/src/db.c
+++ b/src/db.c
@@ -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,7 +1372,8 @@ int *getKeysFromCommand(struct redisCommand *cmd, robj **argv, int argc, int *nu
/* Free the result of getKeysFromCommand. */
void getKeysFreeResult(int *result) {
- zfree(result);
+ if (result != getKeysTempBuffer)
+ zfree(result);
}
/* Helper function to extract keys from following commands:
@@ -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:
* argv[1] = storage key,
* 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[] */
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)
return NULL;
}
- keys = zmalloc(sizeof(int)*num);
+ 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 = 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;
*numkeys = num;
return keys;
@@ -1524,7 +1540,9 @@ int *georadiusGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numk
* argv[1] = key,
* 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[] */
keys[0] = 1;
@@ -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 = 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;
*numkeys = num;
return keys;