Merge pull request #6836 from oranagra/opt_get_keys_malloc
Optimize temporary memory allocations for getKeysFromCommand mechanism
This commit is contained in:
commit
4bf77ffe33
41
src/db.c
41
src/db.c
@ -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
|
|||||||
|
|
||||||
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
|
|||||||
* 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
|
|||||||
|
|
||||||
/* 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
|
|||||||
/* 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)
|
|||||||
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)
|
|||||||
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
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
|||||||
* 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
|
|||||||
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)
|
|||||||
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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user