The memory command will eventually be a complete interface for the * memory introspection capabilities of Redis. * * Usage: MEMORY usage */
| 1398 | * |
| 1399 | * Usage: MEMORY usage <key> */ |
| 1400 | void memoryCommand(client *c) { |
| 1401 | if (!strcasecmp(szFromObj(c->argv[1]),"help") && c->argc == 2) { |
| 1402 | const char *help[] = { |
| 1403 | "DOCTOR", |
| 1404 | " Return memory problems reports.", |
| 1405 | "MALLOC-STATS" |
| 1406 | " Return internal statistics report from the memory allocator.", |
| 1407 | "PURGE", |
| 1408 | " Attempt to purge dirty pages for reclamation by the allocator.", |
| 1409 | "STATS", |
| 1410 | " Return information about the memory usage of the server.", |
| 1411 | "USAGE <key> [SAMPLES <count>]", |
| 1412 | " Return memory in bytes used by <key> and its value. Nested values are", |
| 1413 | " sampled up to <count> times (default: 5).", |
| 1414 | NULL |
| 1415 | }; |
| 1416 | addReplyHelp(c, help); |
| 1417 | } else if (!strcasecmp(szFromObj(c->argv[1]),"usage") && c->argc >= 3) { |
| 1418 | long long samples = OBJ_COMPUTE_SIZE_DEF_SAMPLES; |
| 1419 | for (int j = 3; j < c->argc; j++) { |
| 1420 | if (!strcasecmp(szFromObj(c->argv[j]),"samples") && |
| 1421 | j+1 < c->argc) |
| 1422 | { |
| 1423 | if (getLongLongFromObjectOrReply(c,c->argv[j+1],&samples,NULL) |
| 1424 | == C_ERR) return; |
| 1425 | if (samples < 0) { |
| 1426 | addReplyErrorObject(c,shared.syntaxerr); |
| 1427 | return; |
| 1428 | } |
| 1429 | if (samples == 0) samples = LLONG_MAX; |
| 1430 | j++; /* skip option argument. */ |
| 1431 | } else { |
| 1432 | addReplyErrorObject(c,shared.syntaxerr); |
| 1433 | return; |
| 1434 | } |
| 1435 | } |
| 1436 | |
| 1437 | auto itr = c->db->find(c->argv[2]); |
| 1438 | if (itr == nullptr) { |
| 1439 | addReplyNull(c); |
| 1440 | return; |
| 1441 | } |
| 1442 | size_t usage = objectComputeSize(itr.val(),samples); |
| 1443 | usage += sdsZmallocSize(itr.key()); |
| 1444 | usage += sizeof(dictEntry); |
| 1445 | addReplyLongLong(c,usage); |
| 1446 | } else if (!strcasecmp(szFromObj(c->argv[1]),"stats") && c->argc == 2) { |
| 1447 | struct redisMemOverhead *mh = getMemoryOverheadData(); |
| 1448 | |
| 1449 | addReplyMapLen(c,25+mh->num_dbs); |
| 1450 | |
| 1451 | addReplyBulkCString(c,"peak.allocated"); |
| 1452 | addReplyLongLong(c,mh->peak_allocated); |
| 1453 | |
| 1454 | addReplyBulkCString(c,"total.allocated"); |
| 1455 | addReplyLongLong(c,mh->total_allocated); |
| 1456 | |
| 1457 | addReplyBulkCString(c,"startup.allocated"); |
nothing calls this directly
no test coverage detected