Skip to content

Commit 10e71b3

Browse files
oranagraantirez
authored andcommitted
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.
1 parent edc0ed1 commit 10e71b3

File tree

1 file changed

+31
-10
lines changed

1 file changed

+31
-10
lines changed

src/db.c

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1305,6 +1305,8 @@ int expireIfNeeded(redisDb *db, robj *key) {
13051305
/* -----------------------------------------------------------------------------
13061306
* API to get key arguments from commands
13071307
* ---------------------------------------------------------------------------*/
1308+
#define MAX_KEYS_BUFFER 65536
1309+
static int getKeysTempBuffer[MAX_KEYS_BUFFER];
13081310

13091311
/* The base case is to use the keys position as given in the command table
13101312
* (firstkey, lastkey, step). */
@@ -1319,7 +1321,12 @@ int *getKeysUsingCommandTable(struct redisCommand *cmd,robj **argv, int argc, in
13191321

13201322
last = cmd->lastkey;
13211323
if (last < 0) last = argc+last;
1322-
keys = zmalloc(sizeof(int)*((last - cmd->firstkey)+1));
1324+
1325+
int count = ((last - cmd->firstkey)+1);
1326+
keys = getKeysTempBuffer;
1327+
if (count > MAX_KEYS_BUFFER)
1328+
keys = zmalloc(sizeof(int)*count);
1329+
13231330
for (j = cmd->firstkey; j <= last; j += cmd->keystep) {
13241331
if (j >= argc) {
13251332
/* Modules commands, and standard commands with a not fixed number
@@ -1329,7 +1336,7 @@ int *getKeysUsingCommandTable(struct redisCommand *cmd,robj **argv, int argc, in
13291336
* return no keys and expect the command implementation to report
13301337
* an arity or syntax error. */
13311338
if (cmd->flags & CMD_MODULE || cmd->arity < 0) {
1332-
zfree(keys);
1339+
getKeysFreeResult(keys);
13331340
*numkeys = 0;
13341341
return NULL;
13351342
} else {
@@ -1365,7 +1372,8 @@ int *getKeysFromCommand(struct redisCommand *cmd, robj **argv, int argc, int *nu
13651372

13661373
/* Free the result of getKeysFromCommand. */
13671374
void getKeysFreeResult(int *result) {
1368-
zfree(result);
1375+
if (result != getKeysTempBuffer)
1376+
zfree(result);
13691377
}
13701378

13711379
/* Helper function to extract keys from following commands:
@@ -1386,7 +1394,9 @@ int *zunionInterGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *nu
13861394
/* Keys in z{union,inter}store come from two places:
13871395
* argv[1] = storage key,
13881396
* argv[3...n] = keys to intersect */
1389-
keys = zmalloc(sizeof(int)*(num+1));
1397+
keys = getKeysTempBuffer;
1398+
if (num+1>MAX_KEYS_BUFFER)
1399+
keys = zmalloc(sizeof(int)*(num+1));
13901400

13911401
/* Add all key positions for argv[3...n] to keys[] */
13921402
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)
14121422
return NULL;
14131423
}
14141424

1415-
keys = zmalloc(sizeof(int)*num);
1425+
keys = getKeysTempBuffer;
1426+
if (num>MAX_KEYS_BUFFER)
1427+
keys = zmalloc(sizeof(int)*num);
1428+
14161429
*numkeys = num;
14171430

14181431
/* 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)
14331446
UNUSED(cmd);
14341447

14351448
num = 0;
1436-
keys = zmalloc(sizeof(int)*2); /* Alloc 2 places for the worst case. */
1449+
keys = getKeysTempBuffer; /* Alloc 2 places for the worst case. */
14371450

14381451
keys[num++] = 1; /* <sort-key> is always present. */
14391452

@@ -1491,7 +1504,10 @@ int *migrateGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkey
14911504
}
14921505
}
14931506

1494-
keys = zmalloc(sizeof(int)*num);
1507+
keys = getKeysTempBuffer;
1508+
if (num>MAX_KEYS_BUFFER)
1509+
keys = zmalloc(sizeof(int)*num);
1510+
14951511
for (i = 0; i < num; i++) keys[i] = first+i;
14961512
*numkeys = num;
14971513
return keys;
@@ -1524,7 +1540,9 @@ int *georadiusGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numk
15241540
* argv[1] = key,
15251541
* argv[5...n] = stored key if present
15261542
*/
1527-
keys = zmalloc(sizeof(int) * num);
1543+
keys = getKeysTempBuffer;
1544+
if (num>MAX_KEYS_BUFFER)
1545+
keys = zmalloc(sizeof(int) * num);
15281546

15291547
/* Add all key positions to keys[] */
15301548
keys[0] = 1;
@@ -1542,7 +1560,7 @@ int *memoryGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys
15421560
UNUSED(cmd);
15431561

15441562
if (argc >= 3 && !strcasecmp(argv[1]->ptr,"usage")) {
1545-
keys = zmalloc(sizeof(int) * 1);
1563+
keys = getKeysTempBuffer;
15461564
keys[0] = 2;
15471565
*numkeys = 1;
15481566
return keys;
@@ -1589,7 +1607,10 @@ int *xreadGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys)
15891607
num /= 2; /* We have half the keys as there are arguments because
15901608
there are also the IDs, one per key. */
15911609

1592-
keys = zmalloc(sizeof(int) * num);
1610+
keys = getKeysTempBuffer;
1611+
if (num>MAX_KEYS_BUFFER)
1612+
keys = zmalloc(sizeof(int) * num);
1613+
15931614
for (i = streams_pos+1; i < argc-num; i++) keys[i-streams_pos-1] = i;
15941615
*numkeys = num;
15951616
return keys;

0 commit comments

Comments
 (0)