@@ -1305,6 +1305,8 @@ int expireIfNeeded(redisDb *db, robj *key) {
1305
1305
/* -----------------------------------------------------------------------------
1306
1306
* API to get key arguments from commands
1307
1307
* ---------------------------------------------------------------------------*/
1308
+ #define MAX_KEYS_BUFFER 65536
1309
+ static int getKeysTempBuffer [MAX_KEYS_BUFFER ];
1308
1310
1309
1311
/* The base case is to use the keys position as given in the command table
1310
1312
* (firstkey, lastkey, step). */
@@ -1319,7 +1321,12 @@ int *getKeysUsingCommandTable(struct redisCommand *cmd,robj **argv, int argc, in
1319
1321
1320
1322
last = cmd -> lastkey ;
1321
1323
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
+
1323
1330
for (j = cmd -> firstkey ; j <= last ; j += cmd -> keystep ) {
1324
1331
if (j >= argc ) {
1325
1332
/* 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
1336
* return no keys and expect the command implementation to report
1330
1337
* an arity or syntax error. */
1331
1338
if (cmd -> flags & CMD_MODULE || cmd -> arity < 0 ) {
1332
- zfree (keys );
1339
+ getKeysFreeResult (keys );
1333
1340
* numkeys = 0 ;
1334
1341
return NULL ;
1335
1342
} else {
@@ -1365,7 +1372,8 @@ int *getKeysFromCommand(struct redisCommand *cmd, robj **argv, int argc, int *nu
1365
1372
1366
1373
/* Free the result of getKeysFromCommand. */
1367
1374
void getKeysFreeResult (int * result ) {
1368
- zfree (result );
1375
+ if (result != getKeysTempBuffer )
1376
+ zfree (result );
1369
1377
}
1370
1378
1371
1379
/* Helper function to extract keys from following commands:
@@ -1386,7 +1394,9 @@ int *zunionInterGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *nu
1386
1394
/* Keys in z{union,inter}store come from two places:
1387
1395
* argv[1] = storage key,
1388
1396
* 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 ));
1390
1400
1391
1401
/* Add all key positions for argv[3...n] to keys[] */
1392
1402
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
1422
return NULL ;
1413
1423
}
1414
1424
1415
- keys = zmalloc (sizeof (int )* num );
1425
+ keys = getKeysTempBuffer ;
1426
+ if (num > MAX_KEYS_BUFFER )
1427
+ keys = zmalloc (sizeof (int )* num );
1428
+
1416
1429
* numkeys = num ;
1417
1430
1418
1431
/* 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
1446
UNUSED (cmd );
1434
1447
1435
1448
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. */
1437
1450
1438
1451
keys [num ++ ] = 1 ; /* <sort-key> is always present. */
1439
1452
@@ -1491,7 +1504,10 @@ int *migrateGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkey
1491
1504
}
1492
1505
}
1493
1506
1494
- keys = zmalloc (sizeof (int )* num );
1507
+ keys = getKeysTempBuffer ;
1508
+ if (num > MAX_KEYS_BUFFER )
1509
+ keys = zmalloc (sizeof (int )* num );
1510
+
1495
1511
for (i = 0 ; i < num ; i ++ ) keys [i ] = first + i ;
1496
1512
* numkeys = num ;
1497
1513
return keys ;
@@ -1524,7 +1540,9 @@ int *georadiusGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numk
1524
1540
* argv[1] = key,
1525
1541
* argv[5...n] = stored key if present
1526
1542
*/
1527
- keys = zmalloc (sizeof (int ) * num );
1543
+ keys = getKeysTempBuffer ;
1544
+ if (num > MAX_KEYS_BUFFER )
1545
+ keys = zmalloc (sizeof (int ) * num );
1528
1546
1529
1547
/* Add all key positions to keys[] */
1530
1548
keys [0 ] = 1 ;
@@ -1542,7 +1560,7 @@ int *memoryGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys
1542
1560
UNUSED (cmd );
1543
1561
1544
1562
if (argc >= 3 && !strcasecmp (argv [1 ]-> ptr ,"usage" )) {
1545
- keys = zmalloc ( sizeof ( int ) * 1 ) ;
1563
+ keys = getKeysTempBuffer ;
1546
1564
keys [0 ] = 2 ;
1547
1565
* numkeys = 1 ;
1548
1566
return keys ;
@@ -1589,7 +1607,10 @@ int *xreadGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys)
1589
1607
num /= 2 ; /* We have half the keys as there are arguments because
1590
1608
there are also the IDs, one per key. */
1591
1609
1592
- keys = zmalloc (sizeof (int ) * num );
1610
+ keys = getKeysTempBuffer ;
1611
+ if (num > MAX_KEYS_BUFFER )
1612
+ keys = zmalloc (sizeof (int ) * num );
1613
+
1593
1614
for (i = streams_pos + 1 ; i < argc - num ; i ++ ) keys [i - streams_pos - 1 ] = i ;
1594
1615
* numkeys = num ;
1595
1616
return keys ;
0 commit comments