Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
bb32ede5
Commit
bb32ede5
authored
Apr 03, 2009
by
antirez
Browse files
persistent EXPIRE
parent
0c66a471
Changes
1
Hide whitespace changes
Inline
Side-by-side
redis.c
View file @
bb32ede5
...
@@ -89,6 +89,7 @@
...
@@ -89,6 +89,7 @@
#define REDIS_HASH 3
#define REDIS_HASH 3
/* Object types only used for dumping to disk */
/* Object types only used for dumping to disk */
#define REDIS_EXPIRETIME 253
#define REDIS_SELECTDB 254
#define REDIS_SELECTDB 254
#define REDIS_EOF 255
#define REDIS_EOF 255
...
@@ -288,6 +289,8 @@ static int removeExpire(redisDb *db, robj *key);
...
@@ -288,6 +289,8 @@ static int removeExpire(redisDb *db, robj *key);
static int expireIfNeeded(redisDb *db, robj *key);
static int expireIfNeeded(redisDb *db, robj *key);
static int deleteIfVolatile(redisDb *db, robj *key);
static int deleteIfVolatile(redisDb *db, robj *key);
static int deleteKey(redisDb *db, robj *key);
static int deleteKey(redisDb *db, robj *key);
static time_t getExpire(redisDb *db, robj *key);
static int setExpire(redisDb *db, robj *key, time_t when);
static void authCommand(redisClient *c);
static void authCommand(redisClient *c);
static void pingCommand(redisClient *c);
static void pingCommand(redisClient *c);
...
@@ -1585,6 +1588,12 @@ static int rdbSaveType(FILE *fp, unsigned char type) {
...
@@ -1585,6 +1588,12 @@ static int rdbSaveType(FILE *fp, unsigned char type) {
return 0;
return 0;
}
}
static int rdbSaveTime(FILE *fp, time_t t) {
int32_t t32 = (int32_t) t;
if (fwrite(&t32,4,1,fp) == 0) return -1;
return 0;
}
/* check rdbLoadLen() comments for more info */
/* check rdbLoadLen() comments for more info */
static int rdbSaveLen(FILE *fp, uint32_t len) {
static int rdbSaveLen(FILE *fp, uint32_t len) {
unsigned char buf[2];
unsigned char buf[2];
...
@@ -1713,6 +1722,7 @@ static int rdbSave(char *filename) {
...
@@ -1713,6 +1722,7 @@ static int rdbSave(char *filename) {
FILE *fp;
FILE *fp;
char tmpfile[256];
char tmpfile[256];
int j;
int j;
time_t now = time(NULL);
snprintf(tmpfile,256,"temp-%d.%ld.rdb",(int)time(NULL),(long int)random());
snprintf(tmpfile,256,"temp-%d.%ld.rdb",(int)time(NULL),(long int)random());
fp = fopen(tmpfile,"w");
fp = fopen(tmpfile,"w");
...
@@ -1722,7 +1732,8 @@ static int rdbSave(char *filename) {
...
@@ -1722,7 +1732,8 @@ static int rdbSave(char *filename) {
}
}
if (fwrite("REDIS0001",9,1,fp) == 0) goto werr;
if (fwrite("REDIS0001",9,1,fp) == 0) goto werr;
for (j = 0; j < server.dbnum; j++) {
for (j = 0; j < server.dbnum; j++) {
dict *d = server.db[j].dict;
redisDb *db = server.db+j;
dict *d = db->dict;
if (dictSize(d) == 0) continue;
if (dictSize(d) == 0) continue;
di = dictGetIterator(d);
di = dictGetIterator(d);
if (!di) {
if (!di) {
...
@@ -1738,7 +1749,16 @@ static int rdbSave(char *filename) {
...
@@ -1738,7 +1749,16 @@ static int rdbSave(char *filename) {
while((de = dictNext(di)) != NULL) {
while((de = dictNext(di)) != NULL) {
robj *key = dictGetEntryKey(de);
robj *key = dictGetEntryKey(de);
robj *o = dictGetEntryVal(de);
robj *o = dictGetEntryVal(de);
time_t expiretime = getExpire(db,key);
/* Save the expire time */
if (expiretime != -1) {
/* If this key is already expired skip it */
if (expiretime < now) continue;
if (rdbSaveType(fp,REDIS_EXPIRETIME) == -1) goto werr;
if (rdbSaveTime(fp,expiretime) == -1) goto werr;
}
/* Save the key and associated value */
if (rdbSaveType(fp,o->type) == -1) goto werr;
if (rdbSaveType(fp,o->type) == -1) goto werr;
if (rdbSaveStringObject(fp,key) == -1) goto werr;
if (rdbSaveStringObject(fp,key) == -1) goto werr;
if (o->type == REDIS_STRING) {
if (o->type == REDIS_STRING) {
...
@@ -1831,6 +1851,12 @@ static int rdbLoadType(FILE *fp) {
...
@@ -1831,6 +1851,12 @@ static int rdbLoadType(FILE *fp) {
return type;
return type;
}
}
static time_t rdbLoadTime(FILE *fp) {
int32_t t32;
if (fread(&t32,4,1,fp) == 0) return -1;
return (time_t) t32;
}
/* Load an encoded length from the DB, see the REDIS_RDB_* defines on the top
/* Load an encoded length from the DB, see the REDIS_RDB_* defines on the top
* of this file for a description of how this are stored on disk.
* of this file for a description of how this are stored on disk.
*
*
...
@@ -1942,11 +1968,12 @@ static int rdbLoad(char *filename) {
...
@@ -1942,11 +1968,12 @@ static int rdbLoad(char *filename) {
FILE *fp;
FILE *fp;
robj *keyobj = NULL;
robj *keyobj = NULL;
uint32_t dbid;
uint32_t dbid;
int type;
int type, retval, rdbver;
int retval;
dict *d = server.db[0].dict;
dict *d = server.db[0].dict;
redisDb *db = server.db+0;
char buf[1024];
char buf[1024];
int rdbver;
time_t expiretime = -1, now = time(NULL);
fp = fopen(filename,"r");
fp = fopen(filename,"r");
if (!fp) return REDIS_ERR;
if (!fp) return REDIS_ERR;
if (fread(buf,9,1,fp) == 0) goto eoferr;
if (fread(buf,9,1,fp) == 0) goto eoferr;
...
@@ -1967,6 +1994,11 @@ static int rdbLoad(char *filename) {
...
@@ -1967,6 +1994,11 @@ static int rdbLoad(char *filename) {
/* Read type. */
/* Read type. */
if ((type = rdbLoadType(fp)) == -1) goto eoferr;
if ((type = rdbLoadType(fp)) == -1) goto eoferr;
if (type == REDIS_EXPIRETIME) {
if ((expiretime = rdbLoadTime(fp)) == -1) goto eoferr;
/* We read the time so we need to read the object type again */
if ((type = rdbLoadType(fp)) == -1) goto eoferr;
}
if (type == REDIS_EOF) break;
if (type == REDIS_EOF) break;
/* Handle SELECT DB opcode as a special case */
/* Handle SELECT DB opcode as a special case */
if (type == REDIS_SELECTDB) {
if (type == REDIS_SELECTDB) {
...
@@ -1976,7 +2008,8 @@ static int rdbLoad(char *filename) {
...
@@ -1976,7 +2008,8 @@ static int rdbLoad(char *filename) {
redisLog(REDIS_WARNING,"FATAL: Data file was created with a Redis server configured to handle more than %d databases. Exiting\n", server.dbnum);
redisLog(REDIS_WARNING,"FATAL: Data file was created with a Redis server configured to handle more than %d databases. Exiting\n", server.dbnum);
exit(1);
exit(1);
}
}
d = server.db[dbid].dict;
db = server.db+dbid;
d = db->dict;
continue;
continue;
}
}
/* Read key */
/* Read key */
...
@@ -2014,6 +2047,13 @@ static int rdbLoad(char *filename) {
...
@@ -2014,6 +2047,13 @@ static int rdbLoad(char *filename) {
redisLog(REDIS_WARNING,"Loading DB, duplicated key (%s) found! Unrecoverable error, exiting now.", keyobj->ptr);
redisLog(REDIS_WARNING,"Loading DB, duplicated key (%s) found! Unrecoverable error, exiting now.", keyobj->ptr);
exit(1);
exit(1);
}
}
/* Set the expire time if needed */
if (expiretime != -1) {
setExpire(db,keyobj,expiretime);
/* Delete this key if already expired */
if (expiretime < now) deleteKey(db,keyobj);
expiretime = -1;
}
keyobj = o = NULL;
keyobj = o = NULL;
}
}
fclose(fp);
fclose(fp);
...
@@ -3208,6 +3248,18 @@ static int setExpire(redisDb *db, robj *key, time_t when) {
...
@@ -3208,6 +3248,18 @@ static int setExpire(redisDb *db, robj *key, time_t when) {
}
}
}
}
/* Return the expire time of the specified key, or -1 if no expire
* is associated with this key (i.e. the key is non volatile) */
static time_t getExpire(redisDb *db, robj *key) {
dictEntry *de;
/* No expire? return ASAP */
if (dictSize(db->expires) == 0 ||
(de = dictFind(db->expires,key)) == NULL) return -1;
return (time_t) dictGetEntryVal(de);
}
static int expireIfNeeded(redisDb *db, robj *key) {
static int expireIfNeeded(redisDb *db, robj *key) {
time_t when;
time_t when;
dictEntry *de;
dictEntry *de;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment