Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
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