Object command allows to inspect the internals of a Redis Object. * Usage: OBJECT */
| 1336 | /* Object command allows to inspect the internals of a Redis Object. |
| 1337 | * Usage: OBJECT <refcount|encoding|idletime|freq> <key> */ |
| 1338 | void objectCommand(client *c) { |
| 1339 | robj_roptr o; |
| 1340 | |
| 1341 | if (c->argc == 2 && !strcasecmp(szFromObj(c->argv[1]),"help")) { |
| 1342 | const char *help[] = { |
| 1343 | "ENCODING <key>", |
| 1344 | " Return the kind of internal representation used in order to store the value", |
| 1345 | " associated with a <key>.", |
| 1346 | "FREQ <key>", |
| 1347 | " Return the access frequency index of the <key>. The returned integer is", |
| 1348 | " proportional to the logarithm of the recent access frequency of the key.", |
| 1349 | "IDLETIME <key>", |
| 1350 | " Return the idle time of the <key>, that is the approximated number of", |
| 1351 | " seconds elapsed since the last access to the key.", |
| 1352 | "REFCOUNT <key>", |
| 1353 | " Return the number of references of the value associated with the specified", |
| 1354 | " <key>.", |
| 1355 | NULL |
| 1356 | }; |
| 1357 | addReplyHelp(c, help); |
| 1358 | } else if (!strcasecmp(szFromObj(c->argv[1]),"refcount") && c->argc == 3) { |
| 1359 | if ((o = objectCommandLookupOrReply(c,c->argv[2],shared.null[c->resp])) |
| 1360 | == nullptr) return; |
| 1361 | addReplyLongLong(c,o->getrefcount(std::memory_order_relaxed)); |
| 1362 | } else if (!strcasecmp(szFromObj(c->argv[1]),"encoding") && c->argc == 3) { |
| 1363 | if ((o = objectCommandLookupOrReply(c,c->argv[2],shared.null[c->resp])) |
| 1364 | == nullptr) return; |
| 1365 | addReplyBulkCString(c,strEncoding(o->encoding)); |
| 1366 | } else if (!strcasecmp(szFromObj(c->argv[1]),"idletime") && c->argc == 3) { |
| 1367 | if ((o = objectCommandLookupOrReply(c,c->argv[2],shared.null[c->resp])) |
| 1368 | == nullptr) return; |
| 1369 | if (g_pserver->maxmemory_policy & MAXMEMORY_FLAG_LFU) { |
| 1370 | addReplyError(c,"An LFU maxmemory policy is selected, idle time not tracked. Please note that when switching between policies at runtime LRU and LFU data will take some time to adjust."); |
| 1371 | return; |
| 1372 | } |
| 1373 | addReplyLongLong(c,estimateObjectIdleTime(o)/1000); |
| 1374 | } else if (!strcasecmp(szFromObj(c->argv[1]),"freq") && c->argc == 3) { |
| 1375 | if ((o = objectCommandLookupOrReply(c,c->argv[2],shared.null[c->resp])) |
| 1376 | == nullptr) return; |
| 1377 | if (!(g_pserver->maxmemory_policy & MAXMEMORY_FLAG_LFU)) { |
| 1378 | addReplyError(c,"An LFU maxmemory policy is not selected, access frequency not tracked. Please note that when switching between policies at runtime LRU and LFU data will take some time to adjust."); |
| 1379 | return; |
| 1380 | } |
| 1381 | /* LFUDecrAndReturn should be called |
| 1382 | * in case of the key has not been accessed for a long time, |
| 1383 | * because we update the access time only |
| 1384 | * when the key is read or overwritten. */ |
| 1385 | addReplyLongLong(c,LFUDecrAndReturn(o.unsafe_robjcast())); |
| 1386 | } else if (!strcasecmp(szFromObj(c->argv[1]), "lastmodified") && c->argc == 3) { |
| 1387 | if ((o = objectCommandLookupOrReply(c,c->argv[2],shared.null[c->resp])) |
| 1388 | == nullptr) return; |
| 1389 | uint64_t mvcc = mvccFromObj(o); |
| 1390 | addReplyLongLong(c, (g_pserver->mstime - (mvcc >> MVCC_MS_SHIFT)) / 1000); |
| 1391 | } else { |
| 1392 | addReplySubcommandSyntaxError(c); |
| 1393 | } |
| 1394 | } |
| 1395 |
nothing calls this directly
no test coverage detected