@@ -2208,6 +2208,8 @@ Available flags and their meaning:
22082208
22092209 * ` REDISMODULE_CTX_FLAGS_DEBUG_ENABLED ` : Debug commands are enabled for this
22102210 context.
2211+ * ` REDISMODULE_CTX_FLAGS_TRIM_IN_PROGRESS ` : Trim is in progress due to slot
2212+ migration.
22112213
22122214<span id =" RedisModule_AvoidReplicaTraffic " ></span >
22132215
@@ -2446,6 +2448,217 @@ the absolute Unix timestamp the key should have.
24462448The function returns ` REDISMODULE_OK ` on success or ` REDISMODULE_ERR ` if
24472449the key was not open for writing or is an empty key.
24482450
2451+ <span id =" RedisModule_CreateKeyMetaClass " ></span >
2452+
2453+ ### ` RedisModule_CreateKeyMetaClass `
2454+
2455+ RedisModuleKeyMetaClassId RedisModule_CreateKeyMetaClass(RedisModuleCtx *ctx,;
2456+
2457+ ** Available since:** unreleased
2458+
2459+ Register a new key metadata class exported by the module.
2460+
2461+ Key metadata allows modules to attach up to 8 bytes of metadata to any Redis key,
2462+ regardless of the key's type. This metadata persists across key operations like
2463+ COPY, RENAME, MOVE, and can be saved/loaded from RDB files.
2464+
2465+ The parameters are the following:
2466+
2467+ * ** metaname** : A 9 characters metadata class name that MUST be unique in the Redis
2468+ Modules ecosystem. Use the charset A-Z a-z 0-9, plus the two "-_ " characters.
2469+ A good idea is to use, for example ` <metaname>-<vendor> ` . For example
2470+ "idx-RediSearch" may mean "Index metadata by RediSearch module". To use both
2471+ lower case and upper case letters helps in order to prevent collisions.
2472+
2473+ * ** metaver** : Encoding version, which is the version of the serialization
2474+ that a module used in order to persist metadata. As long as the "metaname"
2475+ matches, the RDB loading will be dispatched to the metadata class callbacks
2476+ whatever 'metaver' is used, however the module can understand if
2477+ the encoding it must load is of an older version of the module.
2478+ For example the module "idx-RediSearch" initially used metaver=0. Later
2479+ after an upgrade, it started to serialize metadata in a different format
2480+ and to register the class with metaver=1. However this module may
2481+ still load old data produced by an older version if the ` rdb_load `
2482+ callback is able to check the metaver value and act accordingly.
2483+ The metaver must be a positive value between 0 and 1023.
2484+
2485+ * ** confPtr** is a pointer to a ` RedisModuleKeyMetaClassConfig ` structure
2486+ that should be populated with the configuration and callbacks, like in
2487+ the following example:
2488+
2489+ RedisModuleKeyMetaClassConfig config = {
2490+ .version = REDISMODULE_KEY_META_VERSION,
2491+ .flags = 1 << REDISMODULE_META_ALLOW_IGNORE,
2492+ .reset_value = 0,
2493+ .copy = myMeta_CopyCallback,
2494+ .rename = myMeta_RenameCallback,
2495+ .move = myMeta_MoveCallback,
2496+ .unlink = myMeta_UnlinkCallback,
2497+ .free = myMeta_FreeCallback,
2498+ .rdb_load = myMeta_RDBLoadCallback,
2499+ .rdb_save = myMeta_RDBSaveCallback,
2500+ .aof_rewrite = myMeta_AOFRewriteCallback,
2501+ .defrag = myMeta_DefragCallback,
2502+ .mem_usage = myMeta_MemUsageCallback,
2503+ .free_effort = myMeta_FreeEffortCallback
2504+ }
2505+
2506+ Redis does NOT take ownership of the config structure itself. The ` confPtr `
2507+ parameter only needs to remain valid during the [ ` RedisModule_CreateKeyMetaClass() ` ] ( #RedisModule_CreateKeyMetaClass ) call
2508+ and can be freed immediately after.
2509+
2510+ * ** version** : Module must set it to ` REDISMODULE_KEY_META_VERSION ` . This field is
2511+ bumped when new fields are added; Redis keeps backward compatibility in
2512+ [ ` RedisModule_CreateKeyMetaClass() ` ] ( #RedisModule_CreateKeyMetaClass ) .
2513+
2514+ * ** flags** : Currently supports ` REDISMODULE_META_ALLOW_IGNORE ` (value 0).
2515+ When set, metadata will be silently ignored during RDB load if the module
2516+ is not available or if ` rdb_load ` callback is NULL. Otherwise, RDB loading
2517+ will fail if metadata is encountered but cannot be loaded.
2518+
2519+ * ** reset_value** : The value to which metadata should be reset when it is being
2520+ "removed" from a key. Typically 0, but can be any 8-byte value. This is
2521+ especially relevant when metadata is a pointer/handler to external resources.
2522+
2523+ IMPORTANT GUARANTEE: Redis only invokes callbacks when meta != ` reset_value ` .
2524+
2525+ * ** copy** : A callback function pointer for COPY command (optional).
2526+ - Return 1 to attach ` meta ` to the new key, or 0 to skip attaching metadata.
2527+ - If NULL, metadata is ignored during copy.
2528+ - The ` meta ` value may be modified in-place to produce a different value
2529+ for the new key.
2530+
2531+ * ** rename** : A callback function pointer for RENAME command (optional).
2532+ - If NULL, then metadata is kept during rename.
2533+ - The ` meta ` value may be modified in-place to produce a different value
2534+ for the new key.
2535+
2536+ * ** move** : A callback function pointer for MOVE command (optional).
2537+ - Return 1 to keep metadata, 0 to drop.
2538+ - If NULL, then metadata is kept during move.
2539+ - The ` meta ` value may be modified in-place to produce a different value
2540+ for the new key.
2541+
2542+ * ** unlink** : A callback function pointer for unlink operations (optional).
2543+ - If not provided, then metadata is ignored during unlink.
2544+ - Indication that key may soon be freed by background thread.
2545+ - Pointer to meta is provided for modification. If the metadata holds a pointer
2546+ or handle to resources and you free them here, you should set ` *meta=reset_value `
2547+ to prevent the free callback from being invoked (Redis skips callbacks when
2548+ meta == reset_value, see reset_value documentation above).
2549+
2550+ * ** free** : A callback function pointer for cleanup (optional).
2551+ Invoked when a key with this metadata is deleted/overwritten/expired,
2552+ or when Redis needs to release per-key metadata during lifecycle operations.
2553+ The module should free any external allocation referenced by ` meta `
2554+ if it uses the 8 bytes as a handle/pointer.
2555+ This callback may run in a background thread and is not protected by GIL.
2556+ It also might be called during RDB loading if the load fails after some
2557+ metadata has been successfully loaded. In this case, keyname will be NULL
2558+ since the key hasn't been created yet.
2559+
2560+ * ** rdb_load** : A callback function pointer for RDB loading (optional).
2561+ - Called during RDB loading when metadata for this class is encountered.
2562+ - Behavior when NULL:
2563+ > If rdb_load is NULL AND REDISMODULE_META_ALLOW_IGNORE flag is set,
2564+ the metadata will be silently ignored during RDB load.
2565+ > If rdb_load is NULL AND the flag is NOT set, RDB loading will fail
2566+ if metadata for this class is encountered.
2567+ - Behavior when class is not registered:
2568+ > If the class was saved with REDISMODULE_META_ALLOW_IGNORE flag but
2569+ is not registered at load time, the metadata will be silently ignored.
2570+ > Otherwise, RDB loading will fail.
2571+ - Callback responsibilities:
2572+ > Read custom serialized data from ` rdb ` using RedisModule_Load* () APIs
2573+ > Deserialize and reconstruct the 8-byte metadata value
2574+ > Write the final 8-byte value into ` *meta `
2575+ > Return appropriate status code (see below)
2576+ > Database ID can be derived from ` rdb ` if needed. The associated key
2577+ will be loaded immediately after this callback returns.
2578+ - Parameters:
2579+ > rdb: RDB I/O context (use RedisModule_Load* () functions to read data)
2580+ > meta: Pointer to 8-byte metadata slot (write your deserialized value here)
2581+ > encver: Encoding version (the metadata class version at save time)
2582+ - Return values:
2583+ > 1: Attach value ` *meta ` to the key (success)
2584+ > 0: Ignore/skip metadata (don't attach, but continue loading - not an error)
2585+ > -1: Error - abort RDB load (e.g., invalid data, version incompatibility)
2586+ Module MUST clean up any allocated metadata before returning -1.
2587+
2588+ * ** rdb_save** : A callback function pointer for RDB saving (optional).
2589+ - If set to NULL, Redis will not save metadata to RDB.
2590+ - Callback should write data using RDB assisting functions: ` RedisModule_Save*() ` .
2591+
2592+ * ** aof_rewrite** : A callback function pointer for AOF rewrite (optional).
2593+ Called during AOF rewrite to emit commands that reconstruct the metadata.
2594+ IMPORTANT: For AOF/RDB persistence to work correctly, metadata classes must be
2595+ registered in ` RedisModule_OnLoad() ` so they are available when loading persisted
2596+ data on server startup.
2597+
2598+ * ** defrag** : A callback function pointer for active defragmentation (optional).
2599+ If the metadata contains pointers, this callback should defragment them.
2600+
2601+ * ** mem_usage** : A callback function pointer for MEMORY USAGE command (optional).
2602+ Should return the memory used by the metadata in bytes.
2603+
2604+ * ** free_effort** : A callback function pointer for lazy free (optional).
2605+ Should return the complexity of freeing the metadata to determine if
2606+ lazy free should be used.
2607+
2608+ Note: the metadata class name "AAAAAAAAA" is reserved and produces an error.
2609+
2610+ If [ ` RedisModule_CreateKeyMetaClass() ` ] ( #RedisModule_CreateKeyMetaClass ) is called outside of ` RedisModule_OnLoad() ` function,
2611+ there is already a metadata class registered with the same name,
2612+ or if the metadata class name or metaver is invalid, a negative value is returned.
2613+ Otherwise the new metadata class is registered into Redis, and a reference of
2614+ type ` RedisModuleKeyMetaClassId ` is returned: the caller of the function should store
2615+ this reference into a global variable to make future use of it in the
2616+ modules metadata API, since a single module may register multiple metadata classes.
2617+ Example code fragment:
2618+
2619+ static RedisModuleKeyMetaClassId IndexMetaClass;
2620+
2621+ int RedisModule_OnLoad(RedisModuleCtx *ctx) {
2622+ // some code here ...
2623+ IndexMetaClass = RedisModule_CreateKeyMetaClass(...);
2624+ }
2625+
2626+ <span id =" RedisModule_ReleaseKeyMetaClass " ></span >
2627+
2628+ ### ` RedisModule_ReleaseKeyMetaClass `
2629+
2630+ int RedisModule_ReleaseKeyMetaClass(RedisModuleKeyMetaClassId id);
2631+
2632+ ** Available since:** unreleased
2633+
2634+ Release a class by its ID. Returns 1 on success, 0 on failure.
2635+
2636+ <span id =" RedisModule_SetKeyMeta " ></span >
2637+
2638+ ### ` RedisModule_SetKeyMeta `
2639+
2640+ int RedisModule_SetKeyMeta(RedisModuleKeyMetaClassId id,
2641+ RedisModuleKey *key,
2642+ uint64_t metadata);
2643+
2644+ ** Available since:** unreleased
2645+
2646+ Set metadata of class id on an opened key. If metadata is already attached,
2647+ it will be overwritten. The caller is responsible for retrieving and freeing
2648+ any existing pointer-based metadata before setting a new value.
2649+
2650+ <span id =" RedisModule_GetKeyMeta " ></span >
2651+
2652+ ### ` RedisModule_GetKeyMeta `
2653+
2654+ int RedisModule_GetKeyMeta(RedisModuleKeyMetaClassId id,
2655+ RedisModuleKey *key,
2656+ uint64_t *metadata);
2657+
2658+ ** Available since:** unreleased
2659+
2660+ Get metadata of class id from an opened key.
2661+
24492662<span id =" RedisModule_ResetDataset " ></span >
24502663
24512664### ` RedisModule_ResetDataset `
@@ -5334,6 +5547,37 @@ With the following effects:
53345547 Slots information will still be propagated across the
53355548 cluster, but without effect.
53365549
5550+ <span id =" RedisModule_ClusterDisableTrim " ></span >
5551+
5552+ ### ` RedisModule_ClusterDisableTrim `
5553+
5554+ int RedisModule_ClusterDisableTrim(RedisModuleCtx *ctx);
5555+
5556+ ** Available since:** unreleased
5557+
5558+ [ ` RedisModule_ClusterDisableTrim ` ] ( #RedisModule_ClusterDisableTrim ) allows a module to temporarily prevent slot trimming
5559+ after a slot migration. This is useful when the module has asynchronous
5560+ operations that rely on keys in migrating slots, which would be trimmed.
5561+
5562+ The module must call [ ` RedisModule_ClusterEnableTrim ` ] ( #RedisModule_ClusterEnableTrim ) once it has completed those
5563+ operations to re-enable trimming.
5564+
5565+ Trimming uses a reference counter: every call to [ ` RedisModule_ClusterDisableTrim ` ] ( #RedisModule_ClusterDisableTrim )
5566+ increments the counter, and every [ ` RedisModule_ClusterEnableTrim ` ] ( #RedisModule_ClusterEnableTrim ) call decrements it.
5567+ Trimming remains disabled as long as the counter is greater than zero.
5568+
5569+ Disable automatic slot trimming.
5570+
5571+ <span id =" RedisModule_ClusterEnableTrim " ></span >
5572+
5573+ ### ` RedisModule_ClusterEnableTrim `
5574+
5575+ int RedisModule_ClusterEnableTrim(RedisModuleCtx *ctx);
5576+
5577+ ** Available since:** unreleased
5578+
5579+ Enable automatic slot trimming. See also comments on [ ` RedisModule_ClusterDisableTrim ` ] ( #RedisModule_ClusterDisableTrim ) .
5580+
53375581<span id =" RedisModule_ClusterKeySlot " ></span >
53385582
53395583### ` RedisModule_ClusterKeySlot `
@@ -5351,7 +5595,7 @@ This function works even if cluster mode is not enabled.
53515595
53525596 unsigned int RedisModule_ClusterKeySlotC(const char *keystr, size_t keylen);
53535597
5354- ** Available since:** unreleased
5598+ ** Available since:** 8.4.0
53555599
53565600Like [ ` RedisModule_ClusterKeySlot ` ] ( #RedisModule_ClusterKeySlot ) , but gets a char pointer and a length.
53575601Returns the cluster slot of a key, similar to the ` CLUSTER KEYSLOT ` command.
@@ -5375,7 +5619,7 @@ a valid slot.
53755619
53765620 int RedisModule_ClusterCanAccessKeysInSlot(int slot);
53775621
5378- ** Available since:** unreleased
5622+ ** Available since:** 8.4.0
53795623
53805624Returns 1 if keys in the specified slot can be accessed by this node, 0 otherwise.
53815625
@@ -5397,7 +5641,7 @@ Returns 0 for:
53975641 const char *fmt,
53985642 ...);
53995643
5400- ** Available since:** unreleased
5644+ ** Available since:** 8.4.0
54015645
54025646Propagate commands along with slot migration.
54035647
@@ -5427,7 +5671,7 @@ On success `REDISMODULE_OK` is returned, otherwise
54275671
54285672 RedisModuleSlotRangeArray *RedisModule_ClusterGetLocalSlotRanges(RedisModuleCtx *ctx);
54295673
5430- ** Available since:** unreleased
5674+ ** Available since:** 8.4.0
54315675
54325676Returns the locally owned slot ranges for the node.
54335677
@@ -5444,7 +5688,7 @@ The returned array must be freed with [`RedisModule_ClusterFreeSlotRanges()`](#R
54445688 void RedisModule_ClusterFreeSlotRanges(RedisModuleCtx *ctx,
54455689 RedisModuleSlotRangeArray *slots);
54465690
5447- ** Available since:** unreleased
5691+ ** Available since:** 8.4.0
54485692
54495693Frees a slot range array returned by [ ` RedisModule_ClusterGetLocalSlotRanges() ` ] ( #RedisModule_ClusterGetLocalSlotRanges ) .
54505694Pass the ` ctx ` pointer only if the array was created with a context.
@@ -7991,7 +8235,8 @@ See [`RedisModule_ConfigSet`](#RedisModule_ConfigSet) for return value.
79918235Set the value of a numeric config.
79928236If the value passed is meant to be a percentage, it should be passed as a
79938237negative value.
7994- For unsigned configs, pass the value and cast to (long long) - internal type checks will handle it.
8238+ For unsigned configs pass the value and cast to (long long) - internal type
8239+ checks will handle it.
79958240
79968241See [ ` RedisModule_ConfigSet ` ] ( #RedisModule_ConfigSet ) for return value.
79978242
@@ -8502,6 +8747,8 @@ There is no guarantee that this info is always available, so this may return -1.
85028747* [ ` RedisModule_CloseKey ` ] ( #RedisModule_CloseKey )
85038748* [ ` RedisModule_ClusterCanAccessKeysInSlot ` ] ( #RedisModule_ClusterCanAccessKeysInSlot )
85048749* [ ` RedisModule_ClusterCanonicalKeyNameInSlot ` ] ( #RedisModule_ClusterCanonicalKeyNameInSlot )
8750+ * [ ` RedisModule_ClusterDisableTrim ` ] ( #RedisModule_ClusterDisableTrim )
8751+ * [ ` RedisModule_ClusterEnableTrim ` ] ( #RedisModule_ClusterEnableTrim )
85058752* [ ` RedisModule_ClusterFreeSlotRanges ` ] ( #RedisModule_ClusterFreeSlotRanges )
85068753* [ ` RedisModule_ClusterGetLocalSlotRanges ` ] ( #RedisModule_ClusterGetLocalSlotRanges )
85078754* [ ` RedisModule_ClusterKeySlot ` ] ( #RedisModule_ClusterKeySlot )
@@ -8528,6 +8775,7 @@ There is no guarantee that this info is always available, so this may return -1.
85288775* [ ` RedisModule_CreateCommand ` ] ( #RedisModule_CreateCommand )
85298776* [ ` RedisModule_CreateDataType ` ] ( #RedisModule_CreateDataType )
85308777* [ ` RedisModule_CreateDict ` ] ( #RedisModule_CreateDict )
8778+ * [ ` RedisModule_CreateKeyMetaClass ` ] ( #RedisModule_CreateKeyMetaClass )
85318779* [ ` RedisModule_CreateModuleUser ` ] ( #RedisModule_CreateModuleUser )
85328780* [ ` RedisModule_CreateString ` ] ( #RedisModule_CreateString )
85338781* [ ` RedisModule_CreateStringFromCallReply ` ] ( #RedisModule_CreateStringFromCallReply )
@@ -8616,6 +8864,7 @@ There is no guarantee that this info is always available, so this may return -1.
86168864* [ ` RedisModule_GetDetachedThreadSafeContext ` ] ( #RedisModule_GetDetachedThreadSafeContext )
86178865* [ ` RedisModule_GetExpire ` ] ( #RedisModule_GetExpire )
86188866* [ ` RedisModule_GetInternalSecret ` ] ( #RedisModule_GetInternalSecret )
8867+ * [ ` RedisModule_GetKeyMeta ` ] ( #RedisModule_GetKeyMeta )
86198868* [ ` RedisModule_GetKeyNameFromDefragCtx ` ] ( #RedisModule_GetKeyNameFromDefragCtx )
86208869* [ ` RedisModule_GetKeyNameFromDigest ` ] ( #RedisModule_GetKeyNameFromDigest )
86218870* [ ` RedisModule_GetKeyNameFromIO ` ] ( #RedisModule_GetKeyNameFromIO )
@@ -8720,6 +8969,7 @@ There is no guarantee that this info is always available, so this may return -1.
87208969* [ ` RedisModule_RegisterInfoFunc ` ] ( #RedisModule_RegisterInfoFunc )
87218970* [ ` RedisModule_RegisterNumericConfig ` ] ( #RedisModule_RegisterNumericConfig )
87228971* [ ` RedisModule_RegisterStringConfig ` ] ( #RedisModule_RegisterStringConfig )
8972+ * [ ` RedisModule_ReleaseKeyMetaClass ` ] ( #RedisModule_ReleaseKeyMetaClass )
87238973* [ ` RedisModule_Replicate ` ] ( #RedisModule_Replicate )
87248974* [ ` RedisModule_ReplicateVerbatim ` ] ( #RedisModule_ReplicateVerbatim )
87258975* [ ` RedisModule_ReplySetArrayLength ` ] ( #RedisModule_ReplySetArrayLength )
@@ -8779,6 +9029,7 @@ There is no guarantee that this info is always available, so this may return -1.
87799029* [ ` RedisModule_SetContextUser ` ] ( #RedisModule_SetContextUser )
87809030* [ ` RedisModule_SetDisconnectCallback ` ] ( #RedisModule_SetDisconnectCallback )
87819031* [ ` RedisModule_SetExpire ` ] ( #RedisModule_SetExpire )
9032+ * [ ` RedisModule_SetKeyMeta ` ] ( #RedisModule_SetKeyMeta )
87829033* [ ` RedisModule_SetLFU ` ] ( #RedisModule_SetLFU )
87839034* [ ` RedisModule_SetLRU ` ] ( #RedisModule_SetLRU )
87849035* [ ` RedisModule_SetModuleOptions ` ] ( #RedisModule_SetModuleOptions )
0 commit comments