The memory command will eventually be a complete interface for the * memory introspection capabilities of Redis. * * Usage: MEMORY usage */
| 1310 | * |
| 1311 | * Usage: MEMORY usage <key> */ |
| 1312 | void memoryCommand(client *c) { |
| 1313 | if (!strcasecmp(c->argv[1]->ptr,"help") && c->argc == 2) { |
| 1314 | const char *help[] = { |
| 1315 | "DOCTOR", |
| 1316 | " Return memory problems reports.", |
| 1317 | "MALLOC-STATS" |
| 1318 | " Return internal statistics report from the memory allocator.", |
| 1319 | "PURGE", |
| 1320 | " Attempt to purge dirty pages for reclamation by the allocator.", |
| 1321 | "STATS", |
| 1322 | " Return information about the memory usage of the server.", |
| 1323 | "USAGE <key> [SAMPLES <count>]", |
| 1324 | " Return memory in bytes used by <key> and its value. Nested values are", |
| 1325 | " sampled up to <count> times (default: 5).", |
| 1326 | NULL |
| 1327 | }; |
| 1328 | addReplyHelp(c, help); |
| 1329 | } else if (!strcasecmp(c->argv[1]->ptr,"usage") && c->argc >= 3) { |
| 1330 | dictEntry *de; |
| 1331 | long long samples = OBJ_COMPUTE_SIZE_DEF_SAMPLES; |
| 1332 | for (int j = 3; j < c->argc; j++) { |
| 1333 | if (!strcasecmp(c->argv[j]->ptr,"samples") && |
| 1334 | j+1 < c->argc) |
| 1335 | { |
| 1336 | if (getLongLongFromObjectOrReply(c,c->argv[j+1],&samples,NULL) |
| 1337 | == C_ERR) return; |
| 1338 | if (samples < 0) { |
| 1339 | addReplyErrorObject(c,shared.syntaxerr); |
| 1340 | return; |
| 1341 | } |
| 1342 | if (samples == 0) samples = LLONG_MAX; |
| 1343 | j++; /* skip option argument. */ |
| 1344 | } else { |
| 1345 | addReplyErrorObject(c,shared.syntaxerr); |
| 1346 | return; |
| 1347 | } |
| 1348 | } |
| 1349 | if ((de = dictFind(c->db->dict,c->argv[2]->ptr)) == NULL) { |
| 1350 | addReplyNull(c); |
| 1351 | return; |
| 1352 | } |
| 1353 | size_t usage = objectComputeSize(dictGetVal(de),samples); |
| 1354 | usage += sdsZmallocSize(dictGetKey(de)); |
| 1355 | usage += sizeof(dictEntry); |
| 1356 | addReplyLongLong(c,usage); |
| 1357 | } else if (!strcasecmp(c->argv[1]->ptr,"stats") && c->argc == 2) { |
| 1358 | struct redisMemOverhead *mh = getMemoryOverheadData(); |
| 1359 | |
| 1360 | addReplyMapLen(c,25+mh->num_dbs); |
| 1361 | |
| 1362 | addReplyBulkCString(c,"peak.allocated"); |
| 1363 | addReplyLongLong(c,mh->peak_allocated); |
| 1364 | |
| 1365 | addReplyBulkCString(c,"total.allocated"); |
| 1366 | addReplyLongLong(c,mh->total_allocated); |
| 1367 | |
| 1368 | addReplyBulkCString(c,"startup.allocated"); |
| 1369 | addReplyLongLong(c,mh->startup_allocated); |
nothing calls this directly
no test coverage detected