summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/db.c8
-rw-r--r--src/module.c39
-rw-r--r--src/object.c5
-rw-r--r--src/redismodule.h8
-rw-r--r--src/server.h3
5 files changed, 57 insertions, 6 deletions
diff --git a/src/db.c b/src/db.c
index 2c0a0cdd3..14f163a8f 100644
--- a/src/db.c
+++ b/src/db.c
@@ -151,9 +151,13 @@ robj *lookupKeyRead(redisDb *db, robj *key) {
*
* Returns the linked value object if the key exists or NULL if the key
* does not exist in the specified DB. */
-robj *lookupKeyWrite(redisDb *db, robj *key) {
+robj *lookupKeyWriteWithFlags(redisDb *db, robj *key, int flags) {
expireIfNeeded(db,key);
- return lookupKey(db,key,LOOKUP_NONE);
+ return lookupKey(db,key,flags);
+}
+
+robj *lookupKeyWrite(redisDb *db, robj *key) {
+ return lookupKeyWriteWithFlags(db, key, LOOKUP_NONE);
}
robj *lookupKeyReadOrReply(client *c, robj *key, robj *reply) {
diff --git a/src/module.c b/src/module.c
index 2a1bda879..09cf6ac7a 100644
--- a/src/module.c
+++ b/src/module.c
@@ -1830,11 +1830,12 @@ int RM_SelectDb(RedisModuleCtx *ctx, int newid) {
void *RM_OpenKey(RedisModuleCtx *ctx, robj *keyname, int mode) {
RedisModuleKey *kp;
robj *value;
+ int flags = mode & REDISMODULE_OPEN_KEY_NOTOUCH? LOOKUP_NOTOUCH: 0;
if (mode & REDISMODULE_WRITE) {
- value = lookupKeyWrite(ctx->client->db,keyname);
+ value = lookupKeyWriteWithFlags(ctx->client->db,keyname, flags);
} else {
- value = lookupKeyRead(ctx->client->db,keyname);
+ value = lookupKeyReadWithFlags(ctx->client->db,keyname, flags);
if (value == NULL) {
return NULL;
}
@@ -6397,6 +6398,38 @@ size_t moduleCount(void) {
return dictSize(modules);
}
+/* Set the key LRU/LFU depending on server.maxmemory_policy.
+ * The lru_idle arg is idle time in seconds, and is only relevant if the
+ * eviction policy is LRU based.
+ * The lfu_freq arg is a logarithmic counter that provides an indication of
+ * the access frequencyonly (must be <= 255) and is only relevant if the
+ * eviction policy is LFU based.
+ * Either or both of them may be <0, in that case, nothing is set. */
+/* return value is an indication if the lru field was updated or not. */
+int RM_SetLRUOrLFU(RedisModuleKey *key, long long lfu_freq, long long lru_idle) {
+ if (!key->value)
+ return REDISMODULE_ERR;
+ if (objectSetLRUOrLFU(key->value, lfu_freq, lru_idle, lru_idle>=0 ? LRU_CLOCK() : 0))
+ return REDISMODULE_OK;
+ return REDISMODULE_ERR;
+}
+
+/* Gets the key LRU or LFU (depending on the current eviction policy).
+ * One will be set to the appropiate return value, and the other will be set to -1.
+ * see RedisModule_SetLRUOrLFU for units and ranges.
+ * return value is an indication of success. */
+int RM_GetLRUOrLFU(RedisModuleKey *key, long long *lfu_freq, long long *lru_idle) {
+ *lru_idle = *lfu_freq = -1;
+ if (!key->value)
+ return REDISMODULE_ERR;
+ if (server.maxmemory_policy & MAXMEMORY_FLAG_LFU) {
+ *lfu_freq = LFUDecrAndReturn(key->value);
+ } else {
+ *lru_idle = estimateObjectIdleTime(key->value)/1000;
+ }
+ return REDISMODULE_OK;
+}
+
/* Register all the APIs we export. Keep this function at the end of the
* file so that's easy to seek it to add new entries. */
void moduleRegisterCoreAPI(void) {
@@ -6589,4 +6622,6 @@ void moduleRegisterCoreAPI(void) {
REGISTER_API(InfoAddFieldULongLong);
REGISTER_API(GetClientInfoById);
REGISTER_API(SubscribeToServerEvent);
+ REGISTER_API(SetLRUOrLFU);
+ REGISTER_API(GetLRUOrLFU);
}
diff --git a/src/object.c b/src/object.c
index 70022f897..47b21ae1f 100644
--- a/src/object.c
+++ b/src/object.c
@@ -1209,12 +1209,13 @@ sds getMemoryDoctorReport(void) {
* The lru_idle and lru_clock args are only relevant if policy
* is MAXMEMORY_FLAG_LRU.
* Either or both of them may be <0, in that case, nothing is set. */
-void objectSetLRUOrLFU(robj *val, long long lfu_freq, long long lru_idle,
+int objectSetLRUOrLFU(robj *val, long long lfu_freq, long long lru_idle,
long long lru_clock) {
if (server.maxmemory_policy & MAXMEMORY_FLAG_LFU) {
if (lfu_freq >= 0) {
serverAssert(lfu_freq <= 255);
val->lru = (LFUGetTimeInMinutes()<<8) | lfu_freq;
+ return 1;
}
} else if (lru_idle >= 0) {
/* Provided LRU idle time is in seconds. Scale
@@ -1231,7 +1232,9 @@ void objectSetLRUOrLFU(robj *val, long long lfu_freq, long long lru_idle,
if (lru_abs < 0)
lru_abs = (lru_clock+(LRU_CLOCK_MAX/2)) % LRU_CLOCK_MAX;
val->lru = lru_abs;
+ return 1;
}
+ return 0;
}
/* ======================= The OBJECT and MEMORY commands =================== */
diff --git a/src/redismodule.h b/src/redismodule.h
index 7053840b2..96e9fb4fa 100644
--- a/src/redismodule.h
+++ b/src/redismodule.h
@@ -18,6 +18,10 @@
#define REDISMODULE_READ (1<<0)
#define REDISMODULE_WRITE (1<<1)
+/* RedisModule_OpenKey extra flags for the 'mode' argument.
+ * Avoid touching the LRU/LFU of the key when opened. */
+#define REDISMODULE_OPEN_KEY_NOTOUCH (1<<16)
+
#define REDISMODULE_LIST_HEAD 0
#define REDISMODULE_LIST_TAIL 1
@@ -503,6 +507,8 @@ int REDISMODULE_API_FUNC(RedisModule_InfoAddFieldDouble)(RedisModuleInfoCtx *ctx
int REDISMODULE_API_FUNC(RedisModule_InfoAddFieldLongLong)(RedisModuleInfoCtx *ctx, char *field, long long value);
int REDISMODULE_API_FUNC(RedisModule_InfoAddFieldULongLong)(RedisModuleInfoCtx *ctx, char *field, unsigned long long value);
int REDISMODULE_API_FUNC(RedisModule_SubscribeToServerEvent)(RedisModuleCtx *ctx, RedisModuleEvent event, RedisModuleEventCallback callback);
+int REDISMODULE_API_FUNC(RedisModule_SetLRUOrLFU)(RedisModuleKey *key, long long lfu_freq, long long lru_idle);
+int REDISMODULE_API_FUNC(RedisModule_GetLRUOrLFU)(RedisModuleKey *key, long long *lfu_freq, long long *lru_idle);
/* Experimental APIs */
#ifdef REDISMODULE_EXPERIMENTAL_API
@@ -703,6 +709,8 @@ static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int
REDISMODULE_GET_API(InfoAddFieldULongLong);
REDISMODULE_GET_API(GetClientInfoById);
REDISMODULE_GET_API(SubscribeToServerEvent);
+ REDISMODULE_GET_API(SetLRUOrLFU);
+ REDISMODULE_GET_API(GetLRUOrLFU);
#ifdef REDISMODULE_EXPERIMENTAL_API
REDISMODULE_GET_API(GetThreadSafeContext);
diff --git a/src/server.h b/src/server.h
index 97672d727..30b25a918 100644
--- a/src/server.h
+++ b/src/server.h
@@ -2079,9 +2079,10 @@ robj *lookupKeyWrite(redisDb *db, robj *key);
robj *lookupKeyReadOrReply(client *c, robj *key, robj *reply);
robj *lookupKeyWriteOrReply(client *c, robj *key, robj *reply);
robj *lookupKeyReadWithFlags(redisDb *db, robj *key, int flags);
+robj *lookupKeyWriteWithFlags(redisDb *db, robj *key, int flags);
robj *objectCommandLookup(client *c, robj *key);
robj *objectCommandLookupOrReply(client *c, robj *key, robj *reply);
-void objectSetLRUOrLFU(robj *val, long long lfu_freq, long long lru_idle,
+int objectSetLRUOrLFU(robj *val, long long lfu_freq, long long lru_idle,
long long lru_clock);
#define LOOKUP_NONE 0
#define LOOKUP_NOTOUCH (1<<0)