Modify mem_usage2 module callback to enable to take sample_size argument (#9612)

This is useful for approximating size computation of complex module types.
Note that the mem_usage2 callback is new and has not been released yet, which is why we can modify it.
This commit is contained in:
Hanna Fadida 2021-10-17 17:31:06 +03:00 committed by GitHub
parent e7864a2b70
commit 61bb044156
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 15 additions and 13 deletions

View File

@ -5227,13 +5227,14 @@ robj *moduleTypeDupOrReply(client *c, robj *fromkey, robj *tokey, int todb, robj
* NOTE: The value is passed as a `void**` and the function is expected to update the
* pointer if the top-level value pointer is defragmented and consequently changes.
*
* * **mem_usage2**: Similar to `mem_usage`, but provides the `RedisModuleKeyOptCtx` parameter
* * **mem_usage2**: Similar to `mem_usage`, but provides the `RedisModuleKeyOptCtx` parameter
* so that meta information such as key name and db id can be obtained, and
* the `sample_size` for size estimation (see MEMORY USAGE command).
* * **free_effort2**: Similar to `free_effort`, but provides the `RedisModuleKeyOptCtx` parameter
* so that meta information such as key name and db id can be obtained.
* * **free_effort2**: Similar to `free_effort`, but provides the `RedisModuleKeyOptCtx` parameter
* * **unlink2**: Similar to `unlink`, but provides the `RedisModuleKeyOptCtx` parameter
* so that meta information such as key name and db id can be obtained.
* * **unlink2**: Similar to `unlink`, but provides the `RedisModuleKeyOptCtx` parameter
* so that meta information such as key name and db id can be obtained.
* * **copy2**: Similar to `copy`, but provides the `RedisModuleKeyOptCtx` parameter
* * **copy2**: Similar to `copy`, but provides the `RedisModuleKeyOptCtx` parameter
* so that meta information such as key names and db ids can be obtained.
*
* Note: the module name "AAAAAAAAA" is reserved and produces an error, it
@ -9313,14 +9314,14 @@ size_t moduleGetFreeEffort(robj *key, robj *val, int dbid) {
/* Return the memory usage of the module, it will automatically choose to call
* `mem_usage` or `mem_usage2`, and the default return value is 0. */
size_t moduleGetMemUsage(robj *key, robj *val, int dbid) {
size_t moduleGetMemUsage(robj *key, robj *val, size_t sample_size, int dbid) {
moduleValue *mv = val->ptr;
moduleType *mt = mv->type;
size_t size = 0;
/* We prefer to use the enhanced version. */
if (mt->mem_usage2 != NULL) {
RedisModuleKeyOptCtx ctx = {key, NULL, dbid, -1};
size = mt->mem_usage2(&ctx,mv->value);
size = mt->mem_usage2(&ctx, mv->value, sample_size);
} else if (mt->mem_usage != NULL) {
size = mt->mem_usage(mv->value);
}

View File

@ -1127,7 +1127,7 @@ size_t objectComputeSize(robj *key, robj *o, size_t sample_size, int dbid) {
raxStop(&ri);
}
} else if (o->type == OBJ_MODULE) {
asize = moduleGetMemUsage(key, o, dbid);
asize = moduleGetMemUsage(key, o, sample_size, dbid);
} else {
serverPanic("Unknown object type");
}
@ -1487,7 +1487,7 @@ void memoryCommand(client *c) {
" Return information about the memory usage of the server.",
"USAGE <key> [SAMPLES <count>]",
" Return memory in bytes used by <key> and its value. Nested values are",
" sampled up to <count> times (default: 5).",
" sampled up to <count> times (default: 5, 0 means sample all).",
NULL
};
addReplyHelp(c, help);

View File

@ -543,7 +543,7 @@ typedef int (*RedisModuleTypeAuxLoadFunc)(RedisModuleIO *rdb, int encver, int wh
typedef void (*RedisModuleTypeAuxSaveFunc)(RedisModuleIO *rdb, int when);
typedef void (*RedisModuleTypeRewriteFunc)(RedisModuleIO *aof, RedisModuleString *key, void *value);
typedef size_t (*RedisModuleTypeMemUsageFunc)(const void *value);
typedef size_t (*RedisModuleTypeMemUsageFunc2)(RedisModuleKeyOptCtx *ctx, const void *value);
typedef size_t (*RedisModuleTypeMemUsageFunc2)(RedisModuleKeyOptCtx *ctx, const void *value, size_t sample_size);
typedef void (*RedisModuleTypeDigestFunc)(RedisModuleDigest *digest, void *value);
typedef void (*RedisModuleTypeFreeFunc)(void *value);
typedef size_t (*RedisModuleTypeFreeEffortFunc)(RedisModuleString *key, const void *value);

View File

@ -583,7 +583,7 @@ typedef void *(*moduleTypeCopyFunc)(struct redisObject *fromkey, struct redisObj
typedef int (*moduleTypeDefragFunc)(struct RedisModuleDefragCtx *ctx, struct redisObject *key, void **value);
typedef void (*RedisModuleInfoFunc)(struct RedisModuleInfoCtx *ctx, int for_crash_report);
typedef void (*RedisModuleDefragFunc)(struct RedisModuleDefragCtx *ctx);
typedef size_t (*moduleTypeMemUsageFunc2)(struct RedisModuleKeyOptCtx *ctx, const void *value);
typedef size_t (*moduleTypeMemUsageFunc2)(struct RedisModuleKeyOptCtx *ctx, const void *value, size_t sample_size);
typedef void (*moduleTypeFreeFunc2)(struct RedisModuleKeyOptCtx *ctx, void *value);
typedef size_t (*moduleTypeFreeEffortFunc2)(struct RedisModuleKeyOptCtx *ctx, const void *value);
typedef void (*moduleTypeUnlinkFunc2)(struct RedisModuleKeyOptCtx *ctx, void *value);
@ -1975,7 +1975,7 @@ int moduleClientIsBlockedOnKeys(client *c);
void moduleNotifyUserChanged(client *c);
void moduleNotifyKeyUnlink(robj *key, robj *val, int dbid);
size_t moduleGetFreeEffort(robj *key, robj *val, int dbid);
size_t moduleGetMemUsage(robj *key, robj *val, int dbid);
size_t moduleGetMemUsage(robj *key, robj *val, size_t sample_size, int dbid);
robj *moduleTypeDupOrReply(client *c, robj *fromkey, robj *tokey, int todb, robj *value);
int moduleDefragValue(robj *key, robj *obj, long *defragged, int dbid);
int moduleLateDefrag(robj *key, robj *value, unsigned long *cursor, long long endtime, long long *defragged, int dbid);

View File

@ -657,8 +657,9 @@ void *MemAllocCopy2(RedisModuleKeyOptCtx *ctx, const void *value) {
return new;
}
size_t MemAllocMemUsage2(RedisModuleKeyOptCtx *ctx, const void *value) {
size_t MemAllocMemUsage2(RedisModuleKeyOptCtx *ctx, const void *value, size_t sample_size) {
REDISMODULE_NOT_USED(ctx);
REDISMODULE_NOT_USED(sample_size);
uint64_t size = 0;
MemAllocObject *o = (MemAllocObject *)value;