TTL and TYPE LRU access fixed. TOUCH implemented.
This commit is contained in:
parent
cd8e688226
commit
41d804d9dc
61
src/db.c
61
src/db.c
@ -38,7 +38,10 @@
|
|||||||
* C-level DB API
|
* C-level DB API
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
robj *lookupKey(redisDb *db, robj *key) {
|
/* Low level key lookup API, not actually called directly from commands
|
||||||
|
* implementations that should instead rely on lookupKeyRead(),
|
||||||
|
* lookupKeyWrite() and lookupKeyReadWithFlags(). */
|
||||||
|
robj *lookupKey(redisDb *db, robj *key, int flags) {
|
||||||
dictEntry *de = dictFind(db->dict,key->ptr);
|
dictEntry *de = dictFind(db->dict,key->ptr);
|
||||||
if (de) {
|
if (de) {
|
||||||
robj *val = dictGetVal(de);
|
robj *val = dictGetVal(de);
|
||||||
@ -46,15 +49,40 @@ robj *lookupKey(redisDb *db, robj *key) {
|
|||||||
/* Update the access time for the ageing algorithm.
|
/* Update the access time for the ageing algorithm.
|
||||||
* Don't do it if we have a saving child, as this will trigger
|
* Don't do it if we have a saving child, as this will trigger
|
||||||
* a copy on write madness. */
|
* a copy on write madness. */
|
||||||
if (server.rdb_child_pid == -1 && server.aof_child_pid == -1)
|
if (server.rdb_child_pid == -1 &&
|
||||||
|
server.aof_child_pid == -1 &&
|
||||||
|
!(flags & LOOKUP_NOTOUCH))
|
||||||
|
{
|
||||||
val->lru = LRU_CLOCK();
|
val->lru = LRU_CLOCK();
|
||||||
|
}
|
||||||
return val;
|
return val;
|
||||||
} else {
|
} else {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
robj *lookupKeyRead(redisDb *db, robj *key) {
|
/* Lookup a key for read operations, or return NULL if the key is not found
|
||||||
|
* in the specified DB.
|
||||||
|
*
|
||||||
|
* As a side effect of calling this function:
|
||||||
|
* 1. A key gets expired if it reached it's TTL.
|
||||||
|
* 2. The key last access time is updated.
|
||||||
|
* 3. The global keys hits/misses stats are updated (reported in INFO).
|
||||||
|
*
|
||||||
|
* This API should not be used when we write to the key after obtaining
|
||||||
|
* the object linked to the key, but only for read only operations.
|
||||||
|
*
|
||||||
|
* Flags change the behavior of this command:
|
||||||
|
*
|
||||||
|
* LOOKUP_NONE (or zero): no special flags are passed.
|
||||||
|
* LOOKUP_NOTOUCH: don't alter the last access time of the key.
|
||||||
|
*
|
||||||
|
* Note: this function also returns NULL is the key is logically expired
|
||||||
|
* but still existing, in case this is a slave, since this API is called only
|
||||||
|
* for read operations. Even if the key expiry is master-driven, we can
|
||||||
|
* correctly report a key is expired on slaves even if the master is lagging
|
||||||
|
* expiring our key via DELs in the replication link. */
|
||||||
|
robj *lookupKeyReadWithFlags(redisDb *db, robj *key, int flags) {
|
||||||
robj *val;
|
robj *val;
|
||||||
|
|
||||||
if (expireIfNeeded(db,key) == 1) {
|
if (expireIfNeeded(db,key) == 1) {
|
||||||
@ -83,7 +111,7 @@ robj *lookupKeyRead(redisDb *db, robj *key) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val = lookupKey(db,key);
|
val = lookupKey(db,key,flags);
|
||||||
if (val == NULL)
|
if (val == NULL)
|
||||||
server.stat_keyspace_misses++;
|
server.stat_keyspace_misses++;
|
||||||
else
|
else
|
||||||
@ -91,9 +119,20 @@ robj *lookupKeyRead(redisDb *db, robj *key) {
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Like lookupKeyReadWithFlags(), but does not use any flag, which is the
|
||||||
|
* common case. */
|
||||||
|
robj *lookupKeyRead(redisDb *db, robj *key) {
|
||||||
|
return lookupKeyReadWithFlags(db,key,LOOKUP_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lookup a key for write operations, and as a side effect, if needed, expires
|
||||||
|
* the key if its TTL is reached.
|
||||||
|
*
|
||||||
|
* 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 *lookupKeyWrite(redisDb *db, robj *key) {
|
||||||
expireIfNeeded(db,key);
|
expireIfNeeded(db,key);
|
||||||
return lookupKey(db,key);
|
return lookupKey(db,key,LOOKUP_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
robj *lookupKeyReadOrReply(client *c, robj *key, robj *reply) {
|
robj *lookupKeyReadOrReply(client *c, robj *key, robj *reply) {
|
||||||
@ -721,7 +760,7 @@ void typeCommand(client *c) {
|
|||||||
robj *o;
|
robj *o;
|
||||||
char *type;
|
char *type;
|
||||||
|
|
||||||
o = lookupKeyRead(c->db,c->argv[1]);
|
o = lookupKeyReadWithFlags(c->db,c->argv[1],LOOKUP_NOTOUCH);
|
||||||
if (o == NULL) {
|
if (o == NULL) {
|
||||||
type = "none";
|
type = "none";
|
||||||
} else {
|
} else {
|
||||||
@ -1049,7 +1088,7 @@ void ttlGenericCommand(client *c, int output_ms) {
|
|||||||
long long expire, ttl = -1;
|
long long expire, ttl = -1;
|
||||||
|
|
||||||
/* If the key does not exist at all, return -2 */
|
/* If the key does not exist at all, return -2 */
|
||||||
if (lookupKeyRead(c->db,c->argv[1]) == NULL) {
|
if (lookupKeyReadWithFlags(c->db,c->argv[1],LOOKUP_NOTOUCH) == NULL) {
|
||||||
addReplyLongLong(c,-2);
|
addReplyLongLong(c,-2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1091,6 +1130,14 @@ void persistCommand(client *c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TOUCH key1 [key2 key3 ... keyN] */
|
||||||
|
void touchCommand(client *c) {
|
||||||
|
int touched = 0;
|
||||||
|
for (int j = 1; j < c->argc; j++)
|
||||||
|
if (lookupKeyRead(c->db,c->argv[j]) != NULL) touched++;
|
||||||
|
addReplyLongLong(c,touched);
|
||||||
|
}
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* API to get key arguments from commands
|
* API to get key arguments from commands
|
||||||
* ---------------------------------------------------------------------------*/
|
* ---------------------------------------------------------------------------*/
|
||||||
|
@ -250,6 +250,7 @@ struct redisCommand redisCommandTable[] = {
|
|||||||
{"info",infoCommand,-1,"lt",0,NULL,0,0,0,0,0},
|
{"info",infoCommand,-1,"lt",0,NULL,0,0,0,0,0},
|
||||||
{"monitor",monitorCommand,1,"as",0,NULL,0,0,0,0,0},
|
{"monitor",monitorCommand,1,"as",0,NULL,0,0,0,0,0},
|
||||||
{"ttl",ttlCommand,2,"rF",0,NULL,1,1,1,0,0},
|
{"ttl",ttlCommand,2,"rF",0,NULL,1,1,1,0,0},
|
||||||
|
{"touch",touchCommand,-2,"rF",0,NULL,1,1,1,0,0},
|
||||||
{"pttl",pttlCommand,2,"rF",0,NULL,1,1,1,0,0},
|
{"pttl",pttlCommand,2,"rF",0,NULL,1,1,1,0,0},
|
||||||
{"persist",persistCommand,2,"wF",0,NULL,1,1,1,0,0},
|
{"persist",persistCommand,2,"wF",0,NULL,1,1,1,0,0},
|
||||||
{"slaveof",slaveofCommand,3,"ast",0,NULL,0,0,0,0,0},
|
{"slaveof",slaveofCommand,3,"ast",0,NULL,0,0,0,0,0},
|
||||||
|
@ -1533,11 +1533,14 @@ void propagateExpire(redisDb *db, robj *key, int lazy);
|
|||||||
int expireIfNeeded(redisDb *db, robj *key);
|
int expireIfNeeded(redisDb *db, robj *key);
|
||||||
long long getExpire(redisDb *db, robj *key);
|
long long getExpire(redisDb *db, robj *key);
|
||||||
void setExpire(redisDb *db, robj *key, long long when);
|
void setExpire(redisDb *db, robj *key, long long when);
|
||||||
robj *lookupKey(redisDb *db, robj *key);
|
robj *lookupKey(redisDb *db, robj *key, int flags);
|
||||||
robj *lookupKeyRead(redisDb *db, robj *key);
|
robj *lookupKeyRead(redisDb *db, robj *key);
|
||||||
robj *lookupKeyWrite(redisDb *db, robj *key);
|
robj *lookupKeyWrite(redisDb *db, robj *key);
|
||||||
robj *lookupKeyReadOrReply(client *c, robj *key, robj *reply);
|
robj *lookupKeyReadOrReply(client *c, robj *key, robj *reply);
|
||||||
robj *lookupKeyWriteOrReply(client *c, robj *key, robj *reply);
|
robj *lookupKeyWriteOrReply(client *c, robj *key, robj *reply);
|
||||||
|
robj *lookupKeyReadWithFlags(redisDb *db, robj *key, int flags);
|
||||||
|
#define LOOKUP_NONE 0
|
||||||
|
#define LOOKUP_NOTOUCH (1<<0)
|
||||||
void dbAdd(redisDb *db, robj *key, robj *val);
|
void dbAdd(redisDb *db, robj *key, robj *val);
|
||||||
void dbOverwrite(redisDb *db, robj *key, robj *val);
|
void dbOverwrite(redisDb *db, robj *key, robj *val);
|
||||||
void setKey(redisDb *db, robj *key, robj *val);
|
void setKey(redisDb *db, robj *key, robj *val);
|
||||||
@ -1693,6 +1696,7 @@ void pexpireCommand(client *c);
|
|||||||
void pexpireatCommand(client *c);
|
void pexpireatCommand(client *c);
|
||||||
void getsetCommand(client *c);
|
void getsetCommand(client *c);
|
||||||
void ttlCommand(client *c);
|
void ttlCommand(client *c);
|
||||||
|
void touchCommand(client *c);
|
||||||
void pttlCommand(client *c);
|
void pttlCommand(client *c);
|
||||||
void persistCommand(client *c);
|
void persistCommand(client *c);
|
||||||
void slaveofCommand(client *c);
|
void slaveofCommand(client *c);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user