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
f9c6f39b
Commit
f9c6f39b
authored
Sep 22, 2011
by
antirez
Browse files
merge conflicts resolved
parents
7c748c06
041d8e2a
Changes
9
Expand all
Hide whitespace changes
Inline
Side-by-side
src/Makefile
View file @
f9c6f39b
...
@@ -61,7 +61,7 @@ QUIET_CC = @printf ' %b %b\n' $(CCCOLOR)CC$(ENDCOLOR) $(SRCCOLOR)$@$(ENDCOLOR
...
@@ -61,7 +61,7 @@ QUIET_CC = @printf ' %b %b\n' $(CCCOLOR)CC$(ENDCOLOR) $(SRCCOLOR)$@$(ENDCOLOR
QUIET_LINK
=
@printf
' %b %b\n'
$(LINKCOLOR)
LINK
$(ENDCOLOR)
$(BINCOLOR)$@$(ENDCOLOR)
;
QUIET_LINK
=
@printf
' %b %b\n'
$(LINKCOLOR)
LINK
$(ENDCOLOR)
$(BINCOLOR)$@$(ENDCOLOR)
;
endif
endif
OBJ
=
adlist.o ae.o anet.o dict.o redis.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o ziplist.o release.o networking.o util.o object.o db.o replication.o rdb.o t_string.o t_list.o t_set.o t_zset.o t_hash.o config.o aof.o pubsub.o multi.o debug.o sort.o intset.o syncio.o cluster.o crc16.o endian.o slowlog.o scripting.o bio.o
OBJ
=
adlist.o ae.o anet.o dict.o redis.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o ziplist.o release.o networking.o util.o object.o db.o replication.o rdb.o t_string.o t_list.o t_set.o t_zset.o t_hash.o config.o aof.o pubsub.o multi.o debug.o sort.o intset.o syncio.o cluster.o crc16.o endian.o slowlog.o scripting.o bio.o
rio.o
BENCHOBJ
=
ae.o anet.o redis-benchmark.o sds.o adlist.o zmalloc.o
BENCHOBJ
=
ae.o anet.o redis-benchmark.o sds.o adlist.o zmalloc.o
CLIOBJ
=
anet.o sds.o adlist.o redis-cli.o zmalloc.o release.o
CLIOBJ
=
anet.o sds.o adlist.o redis-cli.o zmalloc.o release.o
CHECKDUMPOBJ
=
redis-check-dump.o lzf_c.o lzf_d.o
CHECKDUMPOBJ
=
redis-check-dump.o lzf_c.o lzf_d.o
...
@@ -130,6 +130,7 @@ replication.o: replication.c redis.h fmacros.h config.h ae.h sds.h dict.h \
...
@@ -130,6 +130,7 @@ replication.o: replication.c redis.h fmacros.h config.h ae.h sds.h dict.h \
scripting.o
:
scripting.c redis.h fmacros.h config.h ae.h sds.h dict.h
\
scripting.o
:
scripting.c redis.h fmacros.h config.h ae.h sds.h dict.h
\
adlist.h zmalloc.h anet.h zipmap.h ziplist.h intset.h version.h util.h
\
adlist.h zmalloc.h anet.h zipmap.h ziplist.h intset.h version.h util.h
\
sha1.h
sha1.h
rio.o
:
rio.c sds.h
sds.o
:
sds.c sds.h zmalloc.h
sds.o
:
sds.c sds.h zmalloc.h
sha1.o
:
sha1.c sha1.h config.h
sha1.o
:
sha1.c sha1.h config.h
slowlog.o
:
slowlog.c redis.h fmacros.h config.h ae.h sds.h dict.h
\
slowlog.o
:
slowlog.c redis.h fmacros.h config.h ae.h sds.h dict.h
\
...
...
src/aof.c
View file @
f9c6f39b
#include "redis.h"
#include "redis.h"
#include "bio.h"
#include "bio.h"
#include "rio.h"
#include <signal.h>
#include <signal.h>
#include <fcntl.h>
#include <fcntl.h>
...
@@ -386,11 +387,26 @@ fmterr:
...
@@ -386,11 +387,26 @@ fmterr:
exit
(
1
);
exit
(
1
);
}
}
/* Delegate writing an object to writing a bulk string or bulk long long.
* This is not placed in rio.c since that adds the redis.h dependency. */
int
rioWriteBulkObject
(
rio
*
r
,
robj
*
obj
)
{
/* Avoid using getDecodedObject to help copy-on-write (we are often
* in a child process when this function is called). */
if
(
obj
->
encoding
==
REDIS_ENCODING_INT
)
{
return
rioWriteBulkLongLong
(
r
,(
long
)
obj
->
ptr
);
}
else
if
(
obj
->
encoding
==
REDIS_ENCODING_RAW
)
{
return
rioWriteBulkString
(
r
,
obj
->
ptr
,
sdslen
(
obj
->
ptr
));
}
else
{
redisPanic
(
"Unknown string encoding"
);
}
}
/* Write a sequence of commands able to fully rebuild the dataset into
/* Write a sequence of commands able to fully rebuild the dataset into
* "filename". Used both by REWRITEAOF and BGREWRITEAOF. */
* "filename". Used both by REWRITEAOF and BGREWRITEAOF. */
int
rewriteAppendOnlyFile
(
char
*
filename
)
{
int
rewriteAppendOnlyFile
(
char
*
filename
)
{
dictIterator
*
di
=
NULL
;
dictIterator
*
di
=
NULL
;
dictEntry
*
de
;
dictEntry
*
de
;
rio
aof
;
FILE
*
fp
;
FILE
*
fp
;
char
tmpfile
[
256
];
char
tmpfile
[
256
];
int
j
;
int
j
;
...
@@ -404,6 +420,8 @@ int rewriteAppendOnlyFile(char *filename) {
...
@@ -404,6 +420,8 @@ int rewriteAppendOnlyFile(char *filename) {
redisLog
(
REDIS_WARNING
,
"Failed rewriting the append only file: %s"
,
strerror
(
errno
));
redisLog
(
REDIS_WARNING
,
"Failed rewriting the append only file: %s"
,
strerror
(
errno
));
return
REDIS_ERR
;
return
REDIS_ERR
;
}
}
aof
=
rioInitWithFile
(
fp
);
for
(
j
=
0
;
j
<
server
.
dbnum
;
j
++
)
{
for
(
j
=
0
;
j
<
server
.
dbnum
;
j
++
)
{
char
selectcmd
[]
=
"*2
\r\n
$6
\r\n
SELECT
\r\n
"
;
char
selectcmd
[]
=
"*2
\r\n
$6
\r\n
SELECT
\r\n
"
;
redisDb
*
db
=
server
.
db
+
j
;
redisDb
*
db
=
server
.
db
+
j
;
...
@@ -416,8 +434,8 @@ int rewriteAppendOnlyFile(char *filename) {
...
@@ -416,8 +434,8 @@ int rewriteAppendOnlyFile(char *filename) {
}
}
/* SELECT the new DB */
/* SELECT the new DB */
if
(
fw
rite
(
selectcmd
,
sizeof
(
selectcmd
)
-
1
,
1
,
fp
)
==
0
)
goto
werr
;
if
(
rioW
rite
(
&
aof
,
selectcmd
,
sizeof
(
selectcmd
)
-
1
)
==
0
)
goto
werr
;
if
(
fw
riteBulkLongLong
(
f
p
,
j
)
==
0
)
goto
werr
;
if
(
rioW
riteBulkLongLong
(
&
ao
f
,
j
)
==
0
)
goto
werr
;
/* Iterate this DB writing every entry */
/* Iterate this DB writing every entry */
while
((
de
=
dictNext
(
di
))
!=
NULL
)
{
while
((
de
=
dictNext
(
di
))
!=
NULL
)
{
...
@@ -435,10 +453,10 @@ int rewriteAppendOnlyFile(char *filename) {
...
@@ -435,10 +453,10 @@ int rewriteAppendOnlyFile(char *filename) {
if
(
o
->
type
==
REDIS_STRING
)
{
if
(
o
->
type
==
REDIS_STRING
)
{
/* Emit a SET command */
/* Emit a SET command */
char
cmd
[]
=
"*3
\r\n
$3
\r\n
SET
\r\n
"
;
char
cmd
[]
=
"*3
\r\n
$3
\r\n
SET
\r\n
"
;
if
(
fw
rite
(
cmd
,
sizeof
(
cmd
)
-
1
,
1
,
fp
)
==
0
)
goto
werr
;
if
(
rioW
rite
(
&
aof
,
cmd
,
sizeof
(
cmd
)
-
1
)
==
0
)
goto
werr
;
/* Key and value */
/* Key and value */
if
(
fw
riteBulkObject
(
f
p
,
&
key
)
==
0
)
goto
werr
;
if
(
rioW
riteBulkObject
(
&
ao
f
,
&
key
)
==
0
)
goto
werr
;
if
(
fw
riteBulkObject
(
f
p
,
o
)
==
0
)
goto
werr
;
if
(
rioW
riteBulkObject
(
&
ao
f
,
o
)
==
0
)
goto
werr
;
}
else
if
(
o
->
type
==
REDIS_LIST
)
{
}
else
if
(
o
->
type
==
REDIS_LIST
)
{
/* Emit the RPUSHes needed to rebuild the list */
/* Emit the RPUSHes needed to rebuild the list */
char
cmd
[]
=
"*3
\r\n
$5
\r\n
RPUSH
\r\n
"
;
char
cmd
[]
=
"*3
\r\n
$5
\r\n
RPUSH
\r\n
"
;
...
@@ -450,13 +468,13 @@ int rewriteAppendOnlyFile(char *filename) {
...
@@ -450,13 +468,13 @@ int rewriteAppendOnlyFile(char *filename) {
long
long
vlong
;
long
long
vlong
;
while
(
ziplistGet
(
p
,
&
vstr
,
&
vlen
,
&
vlong
))
{
while
(
ziplistGet
(
p
,
&
vstr
,
&
vlen
,
&
vlong
))
{
if
(
fw
rite
(
cmd
,
sizeof
(
cmd
)
-
1
,
1
,
fp
)
==
0
)
goto
werr
;
if
(
rioW
rite
(
&
aof
,
cmd
,
sizeof
(
cmd
)
-
1
)
==
0
)
goto
werr
;
if
(
fw
riteBulkObject
(
f
p
,
&
key
)
==
0
)
goto
werr
;
if
(
rioW
riteBulkObject
(
&
ao
f
,
&
key
)
==
0
)
goto
werr
;
if
(
vstr
)
{
if
(
vstr
)
{
if
(
fw
riteBulkString
(
f
p
,(
char
*
)
vstr
,
vlen
)
==
0
)
if
(
rioW
riteBulkString
(
&
ao
f
,(
char
*
)
vstr
,
vlen
)
==
0
)
goto
werr
;
goto
werr
;
}
else
{
}
else
{
if
(
fw
riteBulkLongLong
(
f
p
,
vlong
)
==
0
)
if
(
rioW
riteBulkLongLong
(
&
ao
f
,
vlong
)
==
0
)
goto
werr
;
goto
werr
;
}
}
p
=
ziplistNext
(
zl
,
p
);
p
=
ziplistNext
(
zl
,
p
);
...
@@ -470,9 +488,9 @@ int rewriteAppendOnlyFile(char *filename) {
...
@@ -470,9 +488,9 @@ int rewriteAppendOnlyFile(char *filename) {
while
((
ln
=
listNext
(
&
li
)))
{
while
((
ln
=
listNext
(
&
li
)))
{
robj
*
eleobj
=
listNodeValue
(
ln
);
robj
*
eleobj
=
listNodeValue
(
ln
);
if
(
fw
rite
(
cmd
,
sizeof
(
cmd
)
-
1
,
1
,
fp
)
==
0
)
goto
werr
;
if
(
rioW
rite
(
&
aof
,
cmd
,
sizeof
(
cmd
)
-
1
)
==
0
)
goto
werr
;
if
(
fw
riteBulkObject
(
f
p
,
&
key
)
==
0
)
goto
werr
;
if
(
rioW
riteBulkObject
(
&
ao
f
,
&
key
)
==
0
)
goto
werr
;
if
(
fw
riteBulkObject
(
f
p
,
eleobj
)
==
0
)
goto
werr
;
if
(
rioW
riteBulkObject
(
&
ao
f
,
eleobj
)
==
0
)
goto
werr
;
}
}
}
else
{
}
else
{
redisPanic
(
"Unknown list encoding"
);
redisPanic
(
"Unknown list encoding"
);
...
@@ -485,18 +503,18 @@ int rewriteAppendOnlyFile(char *filename) {
...
@@ -485,18 +503,18 @@ int rewriteAppendOnlyFile(char *filename) {
int
ii
=
0
;
int
ii
=
0
;
int64_t
llval
;
int64_t
llval
;
while
(
intsetGet
(
o
->
ptr
,
ii
++
,
&
llval
))
{
while
(
intsetGet
(
o
->
ptr
,
ii
++
,
&
llval
))
{
if
(
fw
rite
(
cmd
,
sizeof
(
cmd
)
-
1
,
1
,
fp
)
==
0
)
goto
werr
;
if
(
rioW
rite
(
&
aof
,
cmd
,
sizeof
(
cmd
)
-
1
)
==
0
)
goto
werr
;
if
(
fw
riteBulkObject
(
f
p
,
&
key
)
==
0
)
goto
werr
;
if
(
rioW
riteBulkObject
(
&
ao
f
,
&
key
)
==
0
)
goto
werr
;
if
(
fw
riteBulkLongLong
(
f
p
,
llval
)
==
0
)
goto
werr
;
if
(
rioW
riteBulkLongLong
(
&
ao
f
,
llval
)
==
0
)
goto
werr
;
}
}
}
else
if
(
o
->
encoding
==
REDIS_ENCODING_HT
)
{
}
else
if
(
o
->
encoding
==
REDIS_ENCODING_HT
)
{
dictIterator
*
di
=
dictGetIterator
(
o
->
ptr
);
dictIterator
*
di
=
dictGetIterator
(
o
->
ptr
);
dictEntry
*
de
;
dictEntry
*
de
;
while
((
de
=
dictNext
(
di
))
!=
NULL
)
{
while
((
de
=
dictNext
(
di
))
!=
NULL
)
{
robj
*
eleobj
=
dictGetEntryKey
(
de
);
robj
*
eleobj
=
dictGetEntryKey
(
de
);
if
(
fw
rite
(
cmd
,
sizeof
(
cmd
)
-
1
,
1
,
fp
)
==
0
)
goto
werr
;
if
(
rioW
rite
(
&
aof
,
cmd
,
sizeof
(
cmd
)
-
1
)
==
0
)
goto
werr
;
if
(
fw
riteBulkObject
(
f
p
,
&
key
)
==
0
)
goto
werr
;
if
(
rioW
riteBulkObject
(
&
ao
f
,
&
key
)
==
0
)
goto
werr
;
if
(
fw
riteBulkObject
(
f
p
,
eleobj
)
==
0
)
goto
werr
;
if
(
rioW
riteBulkObject
(
&
ao
f
,
eleobj
)
==
0
)
goto
werr
;
}
}
dictReleaseIterator
(
di
);
dictReleaseIterator
(
di
);
}
else
{
}
else
{
...
@@ -523,14 +541,14 @@ int rewriteAppendOnlyFile(char *filename) {
...
@@ -523,14 +541,14 @@ int rewriteAppendOnlyFile(char *filename) {
redisAssert
(
ziplistGet
(
eptr
,
&
vstr
,
&
vlen
,
&
vll
));
redisAssert
(
ziplistGet
(
eptr
,
&
vstr
,
&
vlen
,
&
vll
));
score
=
zzlGetScore
(
sptr
);
score
=
zzlGetScore
(
sptr
);
if
(
fw
rite
(
cmd
,
sizeof
(
cmd
)
-
1
,
1
,
fp
)
==
0
)
goto
werr
;
if
(
rioW
rite
(
&
aof
,
cmd
,
sizeof
(
cmd
)
-
1
)
==
0
)
goto
werr
;
if
(
fw
riteBulkObject
(
f
p
,
&
key
)
==
0
)
goto
werr
;
if
(
rioW
riteBulkObject
(
&
ao
f
,
&
key
)
==
0
)
goto
werr
;
if
(
fw
riteBulkDouble
(
f
p
,
score
)
==
0
)
goto
werr
;
if
(
rioW
riteBulkDouble
(
&
ao
f
,
score
)
==
0
)
goto
werr
;
if
(
vstr
!=
NULL
)
{
if
(
vstr
!=
NULL
)
{
if
(
fw
riteBulkString
(
f
p
,(
char
*
)
vstr
,
vlen
)
==
0
)
if
(
rioW
riteBulkString
(
&
ao
f
,(
char
*
)
vstr
,
vlen
)
==
0
)
goto
werr
;
goto
werr
;
}
else
{
}
else
{
if
(
fw
riteBulkLongLong
(
f
p
,
vll
)
==
0
)
if
(
rioW
riteBulkLongLong
(
&
ao
f
,
vll
)
==
0
)
goto
werr
;
goto
werr
;
}
}
zzlNext
(
zl
,
&
eptr
,
&
sptr
);
zzlNext
(
zl
,
&
eptr
,
&
sptr
);
...
@@ -544,10 +562,10 @@ int rewriteAppendOnlyFile(char *filename) {
...
@@ -544,10 +562,10 @@ int rewriteAppendOnlyFile(char *filename) {
robj
*
eleobj
=
dictGetEntryKey
(
de
);
robj
*
eleobj
=
dictGetEntryKey
(
de
);
double
*
score
=
dictGetEntryVal
(
de
);
double
*
score
=
dictGetEntryVal
(
de
);
if
(
fw
rite
(
cmd
,
sizeof
(
cmd
)
-
1
,
1
,
fp
)
==
0
)
goto
werr
;
if
(
rioW
rite
(
&
aof
,
cmd
,
sizeof
(
cmd
)
-
1
)
==
0
)
goto
werr
;
if
(
fw
riteBulkObject
(
f
p
,
&
key
)
==
0
)
goto
werr
;
if
(
rioW
riteBulkObject
(
&
ao
f
,
&
key
)
==
0
)
goto
werr
;
if
(
fw
riteBulkDouble
(
f
p
,
*
score
)
==
0
)
goto
werr
;
if
(
rioW
riteBulkDouble
(
&
ao
f
,
*
score
)
==
0
)
goto
werr
;
if
(
fw
riteBulkObject
(
f
p
,
eleobj
)
==
0
)
goto
werr
;
if
(
rioW
riteBulkObject
(
&
ao
f
,
eleobj
)
==
0
)
goto
werr
;
}
}
dictReleaseIterator
(
di
);
dictReleaseIterator
(
di
);
}
else
{
}
else
{
...
@@ -563,11 +581,11 @@ int rewriteAppendOnlyFile(char *filename) {
...
@@ -563,11 +581,11 @@ int rewriteAppendOnlyFile(char *filename) {
unsigned
int
flen
,
vlen
;
unsigned
int
flen
,
vlen
;
while
((
p
=
zipmapNext
(
p
,
&
field
,
&
flen
,
&
val
,
&
vlen
))
!=
NULL
)
{
while
((
p
=
zipmapNext
(
p
,
&
field
,
&
flen
,
&
val
,
&
vlen
))
!=
NULL
)
{
if
(
fw
rite
(
cmd
,
sizeof
(
cmd
)
-
1
,
1
,
fp
)
==
0
)
goto
werr
;
if
(
rioW
rite
(
&
aof
,
cmd
,
sizeof
(
cmd
)
-
1
)
==
0
)
goto
werr
;
if
(
fw
riteBulkObject
(
f
p
,
&
key
)
==
0
)
goto
werr
;
if
(
rioW
riteBulkObject
(
&
ao
f
,
&
key
)
==
0
)
goto
werr
;
if
(
fw
riteBulkString
(
f
p
,(
char
*
)
field
,
flen
)
==
0
)
if
(
rioW
riteBulkString
(
&
ao
f
,(
char
*
)
field
,
flen
)
==
0
)
goto
werr
;
goto
werr
;
if
(
fw
riteBulkString
(
f
p
,(
char
*
)
val
,
vlen
)
==
0
)
if
(
rioW
riteBulkString
(
&
ao
f
,(
char
*
)
val
,
vlen
)
==
0
)
goto
werr
;
goto
werr
;
}
}
}
else
{
}
else
{
...
@@ -578,10 +596,10 @@ int rewriteAppendOnlyFile(char *filename) {
...
@@ -578,10 +596,10 @@ int rewriteAppendOnlyFile(char *filename) {
robj
*
field
=
dictGetEntryKey
(
de
);
robj
*
field
=
dictGetEntryKey
(
de
);
robj
*
val
=
dictGetEntryVal
(
de
);
robj
*
val
=
dictGetEntryVal
(
de
);
if
(
fw
rite
(
cmd
,
sizeof
(
cmd
)
-
1
,
1
,
fp
)
==
0
)
goto
werr
;
if
(
rioW
rite
(
&
aof
,
cmd
,
sizeof
(
cmd
)
-
1
)
==
0
)
goto
werr
;
if
(
fw
riteBulkObject
(
f
p
,
&
key
)
==
0
)
goto
werr
;
if
(
rioW
riteBulkObject
(
&
ao
f
,
&
key
)
==
0
)
goto
werr
;
if
(
fw
riteBulkObject
(
f
p
,
field
)
==
0
)
goto
werr
;
if
(
rioW
riteBulkObject
(
&
ao
f
,
field
)
==
0
)
goto
werr
;
if
(
fw
riteBulkObject
(
f
p
,
val
)
==
0
)
goto
werr
;
if
(
rioW
riteBulkObject
(
&
ao
f
,
val
)
==
0
)
goto
werr
;
}
}
dictReleaseIterator
(
di
);
dictReleaseIterator
(
di
);
}
}
...
@@ -593,9 +611,9 @@ int rewriteAppendOnlyFile(char *filename) {
...
@@ -593,9 +611,9 @@ int rewriteAppendOnlyFile(char *filename) {
char
cmd
[]
=
"*3
\r\n
$8
\r\n
EXPIREAT
\r\n
"
;
char
cmd
[]
=
"*3
\r\n
$8
\r\n
EXPIREAT
\r\n
"
;
/* If this key is already expired skip it */
/* If this key is already expired skip it */
if
(
expiretime
<
now
)
continue
;
if
(
expiretime
<
now
)
continue
;
if
(
fw
rite
(
cmd
,
sizeof
(
cmd
)
-
1
,
1
,
fp
)
==
0
)
goto
werr
;
if
(
rioW
rite
(
&
aof
,
cmd
,
sizeof
(
cmd
)
-
1
)
==
0
)
goto
werr
;
if
(
fw
riteBulkObject
(
f
p
,
&
key
)
==
0
)
goto
werr
;
if
(
rioW
riteBulkObject
(
&
ao
f
,
&
key
)
==
0
)
goto
werr
;
if
(
fw
riteBulkLongLong
(
f
p
,
expiretime
)
==
0
)
goto
werr
;
if
(
rioW
riteBulkLongLong
(
&
ao
f
,
expiretime
)
==
0
)
goto
werr
;
}
}
}
}
dictReleaseIterator
(
di
);
dictReleaseIterator
(
di
);
...
...
src/cluster.c
View file @
f9c6f39b
...
@@ -1383,11 +1383,10 @@ void clusterCommand(redisClient *c) {
...
@@ -1383,11 +1383,10 @@ void clusterCommand(redisClient *c) {
/* RESTORE key ttl serialized-value */
/* RESTORE key ttl serialized-value */
void
restoreCommand
(
redisClient
*
c
)
{
void
restoreCommand
(
redisClient
*
c
)
{
FILE
*
fp
;
char
buf
[
64
];
robj
*
o
;
unsigned
char
*
data
;
long
ttl
;
long
ttl
;
rio
payload
;
int
type
;
robj
*
obj
;
/* Make sure this key does not already exist here... */
/* Make sure this key does not already exist here... */
if
(
lookupKeyWrite
(
c
->
db
,
c
->
argv
[
1
])
!=
NULL
)
{
if
(
lookupKeyWrite
(
c
->
db
,
c
->
argv
[
1
])
!=
NULL
)
{
...
@@ -1403,44 +1402,16 @@ void restoreCommand(redisClient *c) {
...
@@ -1403,44 +1402,16 @@ void restoreCommand(redisClient *c) {
return
;
return
;
}
}
/* rdbLoadObject() only works against file descriptors so we need to
payload
=
rioInitWithBuffer
(
c
->
argv
[
3
]
->
ptr
);
* dump the serialized object into a file and reload. */
if
(((
type
=
rdbLoadObjectType
(
&
payload
))
==
-
1
)
||
snprintf
(
buf
,
sizeof
(
buf
),
"redis-restore-%d.tmp"
,
getpid
());
((
obj
=
rdbLoadObject
(
type
,
&
payload
))
==
NULL
))
fp
=
fopen
(
buf
,
"w+"
);
if
(
!
fp
)
{
redisLog
(
REDIS_WARNING
,
"Can't open tmp file for RESTORE: %s"
,
strerror
(
errno
));
addReplyErrorFormat
(
c
,
"RESTORE failed, tmp file creation error: %s"
,
strerror
(
errno
));
return
;
}
unlink
(
buf
);
/* Write the actual data and rewind the file */
data
=
(
unsigned
char
*
)
c
->
argv
[
3
]
->
ptr
;
if
(
fwrite
(
data
+
1
,
sdslen
((
sds
)
data
)
-
1
,
1
,
fp
)
!=
1
)
{
redisLog
(
REDIS_WARNING
,
"Can't write against tmp file for RESTORE: %s"
,
strerror
(
errno
));
addReplyError
(
c
,
"RESTORE failed, tmp file I/O error."
);
fclose
(
fp
);
return
;
}
rewind
(
fp
);
/* Finally create the object from the serialized dump and
* store it at the specified key. */
if
((
data
[
0
]
>
4
&&
data
[
0
]
<
9
)
||
data
[
0
]
>
11
||
(
o
=
rdbLoadObject
(
data
[
0
],
fp
))
==
NULL
)
{
{
addReplyError
(
c
,
"Bad data format."
);
addReplyError
(
c
,
"Bad data format"
);
fclose
(
fp
);
return
;
return
;
}
}
fclose
(
fp
);
/* Create the key and set the TTL if any */
/* Create the key and set the TTL if any */
dbAdd
(
c
->
db
,
c
->
argv
[
1
],
o
);
dbAdd
(
c
->
db
,
c
->
argv
[
1
],
o
bj
);
if
(
ttl
)
setExpire
(
c
->
db
,
c
->
argv
[
1
],
time
(
NULL
)
+
ttl
);
if
(
ttl
)
setExpire
(
c
->
db
,
c
->
argv
[
1
],
time
(
NULL
)
+
ttl
);
addReply
(
c
,
shared
.
ok
);
addReply
(
c
,
shared
.
ok
);
}
}
...
@@ -1450,12 +1421,9 @@ void migrateCommand(redisClient *c) {
...
@@ -1450,12 +1421,9 @@ void migrateCommand(redisClient *c) {
int
fd
;
int
fd
;
long
timeout
;
long
timeout
;
long
dbid
;
long
dbid
;
char
buf
[
64
];
FILE
*
fp
;
time_t
ttl
;
time_t
ttl
;
robj
*
o
;
robj
*
o
;
unsigned
char
type
;
rio
cmd
,
payload
;
off_t
payload_len
;
/* Sanity check */
/* Sanity check */
if
(
getLongFromObjectOrReply
(
c
,
c
->
argv
[
5
],
&
timeout
,
NULL
)
!=
REDIS_OK
)
if
(
getLongFromObjectOrReply
(
c
,
c
->
argv
[
5
],
&
timeout
,
NULL
)
!=
REDIS_OK
)
...
@@ -1485,54 +1453,41 @@ void migrateCommand(redisClient *c) {
...
@@ -1485,54 +1453,41 @@ void migrateCommand(redisClient *c) {
return
;
return
;
}
}
/* Create temp file */
cmd
=
rioInitWithBuffer
(
sdsempty
());
snprintf
(
buf
,
sizeof
(
buf
),
"redis-migrate-%d.tmp"
,
getpid
());
redisAssert
(
rioWriteBulkCount
(
&
cmd
,
'*'
,
2
));
fp
=
fopen
(
buf
,
"w+"
);
redisAssert
(
rioWriteBulkString
(
&
cmd
,
"SELECT"
,
6
));
if
(
!
fp
)
{
redisAssert
(
rioWriteBulkLongLong
(
&
cmd
,
dbid
));
redisLog
(
REDIS_WARNING
,
"Can't open tmp file for MIGRATE: %s"
,
strerror
(
errno
));
addReplyErrorFormat
(
c
,
"MIGRATE failed, tmp file creation error: %s."
,
strerror
(
errno
));
return
;
}
unlink
(
buf
);
/* Build the SELECT + RESTORE query writing it in our temp file. */
if
(
fwriteBulkCount
(
fp
,
'*'
,
2
)
==
0
)
goto
file_wr_err
;
if
(
fwriteBulkString
(
fp
,
"SELECT"
,
6
)
==
0
)
goto
file_wr_err
;
if
(
fwriteBulkLongLong
(
fp
,
dbid
)
==
0
)
goto
file_wr_err
;
ttl
=
getExpire
(
c
->
db
,
c
->
argv
[
3
]);
ttl
=
getExpire
(
c
->
db
,
c
->
argv
[
3
]);
type
=
o
->
type
;
redisAssert
(
rioWriteBulkCount
(
&
cmd
,
'*'
,
4
))
;
if
(
fwriteBulkCount
(
fp
,
'*'
,
4
)
==
0
)
goto
file_wr_err
;
redisAssert
(
rioWriteBulkString
(
&
cmd
,
"RESTORE"
,
7
))
;
if
(
fwriteBulkString
(
fp
,
"RESTORE"
,
7
)
==
0
)
goto
file_wr_err
;
redisAssert
(
c
->
argv
[
3
]
->
encoding
==
REDIS_ENCODING_RAW
)
;
if
(
fwriteBulkObject
(
fp
,
c
->
argv
[
3
])
==
0
)
goto
file_wr_err
;
redisAssert
(
rioWriteBulkString
(
&
cmd
,
c
->
argv
[
3
]
->
ptr
,
sdslen
(
c
->
argv
[
3
]
->
ptr
)))
;
if
(
fw
riteBulkLongLong
(
fp
,
(
ttl
==
-
1
)
?
0
:
ttl
)
==
0
)
goto
file_wr_err
;
redisAssert
(
rioW
riteBulkLongLong
(
&
cmd
,
(
ttl
==
-
1
)
?
0
:
ttl
)
)
;
/* Finally the last argument that is the serailized object payload
/* Finally the last argument that is the serailized object payload
* in the form: <type><rdb-serailized-object>. */
* in the form: <type><rdb-serialized-object>. */
payload_len
=
rdbSavedObjectLen
(
o
);
payload
=
rioInitWithBuffer
(
sdsempty
());
if
(
fwriteBulkCount
(
fp
,
'$'
,
payload_len
+
1
)
==
0
)
goto
file_wr_err
;
redisAssert
(
rdbSaveObjectType
(
&
payload
,
o
));
if
(
fwrite
(
&
type
,
1
,
1
,
fp
)
==
0
)
goto
file_wr_err
;
redisAssert
(
rdbSaveObject
(
&
payload
,
o
)
!=
-
1
);
if
(
rdbSaveObject
(
fp
,
o
)
==
-
1
)
goto
file_wr_err
;
redisAssert
(
rioWriteBulkString
(
&
cmd
,
payload
.
io
.
buffer
.
ptr
,
sdslen
(
payload
.
io
.
buffer
.
ptr
)));
if
(
fwrite
(
"
\r\n
"
,
2
,
1
,
fp
)
==
0
)
goto
file_wr_err
;
sdsfree
(
payload
.
io
.
buffer
.
ptr
);
/* Tranfer the query to the other node */
/* Tranfer the query to the other node in 64K chunks. */
rewind
(
fp
);
{
{
char
buf
[
4096
];
sds
buf
=
cmd
.
io
.
buffer
.
ptr
;
size_t
nread
;
size_t
pos
=
0
,
towrite
;
int
nwritten
=
0
;
while
((
nread
=
fread
(
buf
,
1
,
sizeof
(
buf
),
fp
))
!=
0
)
{
int
nwritten
;
while
((
towrite
=
sdslen
(
buf
)
-
pos
)
>
0
)
{
towrite
=
(
towrite
>
(
64
*
1024
)
?
(
64
*
1024
)
:
towrite
);
nwritten
=
syncWrite
(
fd
,
buf
,
nread
,
timeout
);
nwritten
=
syncWrite
(
fd
,
buf
+
nwritten
,
towrite
,
timeout
);
if
(
nwritten
!=
(
signed
)
nread
)
goto
socket_wr_err
;
if
(
nwritten
!=
(
signed
)
towrite
)
goto
socket_wr_err
;
pos
+=
nwritten
;
}
}
if
(
ferror
(
fp
))
goto
file_rd_err
;
}
}
/* Read back the reply */
/* Read back the reply
.
*/
{
{
char
buf1
[
1024
];
char
buf1
[
1024
];
char
buf2
[
1024
];
char
buf2
[
1024
];
...
@@ -1541,7 +1496,7 @@ void migrateCommand(redisClient *c) {
...
@@ -1541,7 +1496,7 @@ void migrateCommand(redisClient *c) {
if
(
syncReadLine
(
fd
,
buf1
,
sizeof
(
buf1
),
timeout
)
<=
0
)
if
(
syncReadLine
(
fd
,
buf1
,
sizeof
(
buf1
),
timeout
)
<=
0
)
goto
socket_rd_err
;
goto
socket_rd_err
;
if
(
syncReadLine
(
fd
,
buf2
,
sizeof
(
buf2
),
timeout
)
<=
0
)
if
(
syncReadLine
(
fd
,
buf2
,
sizeof
(
buf2
),
timeout
)
<=
0
)
goto
socket_rd_err
;
goto
socket_rd_err
;
if
(
buf1
[
0
]
==
'-'
||
buf2
[
0
]
==
'-'
)
{
if
(
buf1
[
0
]
==
'-'
||
buf2
[
0
]
==
'-'
)
{
addReplyErrorFormat
(
c
,
"Target instance replied with error: %s"
,
addReplyErrorFormat
(
c
,
"Target instance replied with error: %s"
,
(
buf1
[
0
]
==
'-'
)
?
buf1
+
1
:
buf2
+
1
);
(
buf1
[
0
]
==
'-'
)
?
buf1
+
1
:
buf2
+
1
);
...
@@ -1550,25 +1505,8 @@ void migrateCommand(redisClient *c) {
...
@@ -1550,25 +1505,8 @@ void migrateCommand(redisClient *c) {
addReply
(
c
,
shared
.
ok
);
addReply
(
c
,
shared
.
ok
);
}
}
}
}
fclose
(
fp
);
close
(
fd
);
return
;
file_wr_err:
sdsfree
(
cmd
.
io
.
buffer
.
ptr
);
redisLog
(
REDIS_WARNING
,
"Can't write on tmp file for MIGRATE: %s"
,
strerror
(
errno
));
addReplyErrorFormat
(
c
,
"MIGRATE failed, tmp file write error: %s."
,
strerror
(
errno
));
fclose
(
fp
);
close
(
fd
);
return
;
file_rd_err:
redisLog
(
REDIS_WARNING
,
"Can't read from tmp file for MIGRATE: %s"
,
strerror
(
errno
));
addReplyErrorFormat
(
c
,
"MIGRATE failed, tmp file read error: %s."
,
strerror
(
errno
));
fclose
(
fp
);
close
(
fd
);
close
(
fd
);
return
;
return
;
...
@@ -1577,7 +1515,7 @@ socket_wr_err:
...
@@ -1577,7 +1515,7 @@ socket_wr_err:
strerror
(
errno
));
strerror
(
errno
));
addReplyErrorFormat
(
c
,
"MIGRATE failed, writing to target node: %s."
,
addReplyErrorFormat
(
c
,
"MIGRATE failed, writing to target node: %s."
,
strerror
(
errno
));
strerror
(
errno
));
fclose
(
fp
);
sdsfree
(
cmd
.
io
.
buffer
.
ptr
);
close
(
fd
);
close
(
fd
);
return
;
return
;
...
@@ -1586,7 +1524,7 @@ socket_rd_err:
...
@@ -1586,7 +1524,7 @@ socket_rd_err:
strerror
(
errno
));
strerror
(
errno
));
addReplyErrorFormat
(
c
,
"MIGRATE failed, reading from target node: %s."
,
addReplyErrorFormat
(
c
,
"MIGRATE failed, reading from target node: %s."
,
strerror
(
errno
));
strerror
(
errno
));
fclose
(
fp
);
sdsfree
(
cmd
.
io
.
buffer
.
ptr
);
close
(
fd
);
close
(
fd
);
return
;
return
;
}
}
...
@@ -1595,74 +1533,26 @@ socket_rd_err:
...
@@ -1595,74 +1533,26 @@ socket_rd_err:
* DUMP is actually not used by Redis Cluster but it is the obvious
* DUMP is actually not used by Redis Cluster but it is the obvious
* complement of RESTORE and can be useful for different applications. */
* complement of RESTORE and can be useful for different applications. */
void
dumpCommand
(
redisClient
*
c
)
{
void
dumpCommand
(
redisClient
*
c
)
{
char
buf
[
64
];
FILE
*
fp
;
robj
*
o
,
*
dumpobj
;
robj
*
o
,
*
dumpobj
;
sds
dump
=
NULL
;
rio
payload
;
off_t
payload_len
;
unsigned
int
type
;
/* Check if the key is here. */
/* Check if the key is here. */
if
((
o
=
lookupKeyRead
(
c
->
db
,
c
->
argv
[
1
]))
==
NULL
)
{
if
((
o
=
lookupKeyRead
(
c
->
db
,
c
->
argv
[
1
]))
==
NULL
)
{
addReply
(
c
,
shared
.
nullbulk
);
addReply
(
c
,
shared
.
nullbulk
);
return
;
return
;
}
}
/* Create temp file */
/* Serialize the object in a RDB-like format. It consist of an object type
snprintf
(
buf
,
sizeof
(
buf
),
"redis-dump-%d.tmp"
,
getpid
());
* byte followed by the serialized object. This is understood by RESTORE. */
fp
=
fopen
(
buf
,
"w+"
);
payload
=
rioInitWithBuffer
(
sdsempty
());
if
(
!
fp
)
{
redisAssert
(
rdbSaveObjectType
(
&
payload
,
o
));
redisLog
(
REDIS_WARNING
,
"Can't open tmp file for MIGRATE: %s"
,
redisAssert
(
rdbSaveObject
(
&
payload
,
o
));
strerror
(
errno
));
addReplyErrorFormat
(
c
,
"DUMP failed, tmp file creation error: %s."
,
strerror
(
errno
));
return
;
}
unlink
(
buf
);
/* Dump the serailized object and read it back in memory.
* We prefix it with a one byte containing the type ID.
* This is the serialization format understood by RESTORE. */
if
(
rdbSaveObject
(
fp
,
o
)
==
-
1
)
goto
file_wr_err
;
payload_len
=
ftello
(
fp
);
if
(
fseeko
(
fp
,
0
,
SEEK_SET
)
==
-
1
)
goto
file_rd_err
;
dump
=
sdsnewlen
(
NULL
,
payload_len
+
1
);
if
(
payload_len
&&
fread
(
dump
+
1
,
payload_len
,
1
,
fp
)
!=
1
)
goto
file_rd_err
;
fclose
(
fp
);
type
=
o
->
type
;
if
(
type
==
REDIS_LIST
&&
o
->
encoding
==
REDIS_ENCODING_ZIPLIST
)
type
=
REDIS_LIST_ZIPLIST
;
else
if
(
type
==
REDIS_HASH
&&
o
->
encoding
==
REDIS_ENCODING_ZIPMAP
)
type
=
REDIS_HASH_ZIPMAP
;
else
if
(
type
==
REDIS_SET
&&
o
->
encoding
==
REDIS_ENCODING_INTSET
)
type
=
REDIS_SET_INTSET
;
else
type
=
o
->
type
;
dump
[
0
]
=
type
;
/* Transfer to the client */
/* Transfer to the client */
dumpobj
=
createObject
(
REDIS_STRING
,
dump
);
dumpobj
=
createObject
(
REDIS_STRING
,
payload
.
io
.
buffer
.
ptr
);
addReplyBulk
(
c
,
dumpobj
);
addReplyBulk
(
c
,
dumpobj
);
decrRefCount
(
dumpobj
);
decrRefCount
(
dumpobj
);
return
;
return
;
file_wr_err:
redisLog
(
REDIS_WARNING
,
"Can't write on tmp file for DUMP: %s"
,
strerror
(
errno
));
addReplyErrorFormat
(
c
,
"DUMP failed, tmp file write error: %s."
,
strerror
(
errno
));
sdsfree
(
dump
);
fclose
(
fp
);
return
;
file_rd_err:
redisLog
(
REDIS_WARNING
,
"Can't read from tmp file for DUMP: %s"
,
strerror
(
errno
));
addReplyErrorFormat
(
c
,
"DUMP failed, tmp file read error: %s."
,
strerror
(
errno
));
sdsfree
(
dump
);
fclose
(
fp
);
return
;
}
}
/* -----------------------------------------------------------------------------
/* -----------------------------------------------------------------------------
...
...
src/rdb.c
View file @
f9c6f39b
This diff is collapsed.
Click to expand it.
src/rdb.h
0 → 100644
View file @
f9c6f39b
#ifndef __REDIS_RDB_H
#define __REDIS_RDB_H
#include <stdio.h>
#include "rio.h"
/* TBD: include only necessary headers. */
#include "redis.h"
/* Defines related to the dump file format. To store 32 bits lengths for short
* keys requires a lot of space, so we check the most significant 2 bits of
* the first byte to interpreter the length:
*
* 00|000000 => if the two MSB are 00 the len is the 6 bits of this byte
* 01|000000 00000000 => 01, the len is 14 byes, 6 bits + 8 bits of next byte
* 10|000000 [32 bit integer] => if it's 01, a full 32 bit len will follow
* 11|000000 this means: specially encoded object will follow. The six bits
* number specify the kind of object that follows.
* See the REDIS_RDB_ENC_* defines.
*
* Lenghts up to 63 are stored using a single byte, most DB keys, and may
* values, will fit inside. */
#define REDIS_RDB_6BITLEN 0
#define REDIS_RDB_14BITLEN 1
#define REDIS_RDB_32BITLEN 2
#define REDIS_RDB_ENCVAL 3
#define REDIS_RDB_LENERR UINT_MAX
/* When a length of a string object stored on disk has the first two bits
* set, the remaining two bits specify a special encoding for the object
* accordingly to the following defines: */
#define REDIS_RDB_ENC_INT8 0
/* 8 bit signed integer */
#define REDIS_RDB_ENC_INT16 1
/* 16 bit signed integer */
#define REDIS_RDB_ENC_INT32 2
/* 32 bit signed integer */
#define REDIS_RDB_ENC_LZF 3
/* string compressed with FASTLZ */
/* Dup object types to RDB object types. Only reason is readability (are we
* dealing with RDB types or with in-memory object types?). */
#define REDIS_RDB_TYPE_STRING 0
#define REDIS_RDB_TYPE_LIST 1
#define REDIS_RDB_TYPE_SET 2
#define REDIS_RDB_TYPE_ZSET 3
#define REDIS_RDB_TYPE_HASH 4
/* Object types for encoded objects. */
#define REDIS_RDB_TYPE_HASH_ZIPMAP 9
#define REDIS_RDB_TYPE_LIST_ZIPLIST 10
#define REDIS_RDB_TYPE_SET_INTSET 11
#define REDIS_RDB_TYPE_ZSET_ZIPLIST 12
/* Test if a type is an object type. */
#define rdbIsObjectType(t) ((t >= 0 && t <= 4) || (t >= 9 && t <= 12))
/* Special RDB opcodes (saved/loaded with rdbSaveType/rdbLoadType). */
#define REDIS_RDB_OPCODE_EXPIRETIME 253
#define REDIS_RDB_OPCODE_SELECTDB 254
#define REDIS_RDB_OPCODE_EOF 255
/* Test if a type is an opcode. */
#define rdbIsOpcode(t) (t >= 253 && t <= 255)
int
rdbSaveType
(
rio
*
rdb
,
unsigned
char
type
);
int
rdbLoadType
(
rio
*
rdb
);
int
rdbSaveTime
(
rio
*
rdb
,
time_t
t
);
time_t
rdbLoadTime
(
rio
*
rdb
);
int
rdbSaveLen
(
rio
*
rdb
,
uint32_t
len
);
uint32_t
rdbLoadLen
(
rio
*
rdb
,
int
*
isencoded
);
int
rdbSaveObjectType
(
rio
*
rdb
,
robj
*
o
);
int
rdbLoadObjectType
(
rio
*
rdb
);
int
rdbLoad
(
char
*
filename
);
int
rdbSaveBackground
(
char
*
filename
);
void
rdbRemoveTempFile
(
pid_t
childpid
);
int
rdbSave
(
char
*
filename
);
int
rdbSaveObject
(
rio
*
rdb
,
robj
*
o
);
off_t
rdbSavedObjectLen
(
robj
*
o
);
off_t
rdbSavedObjectPages
(
robj
*
o
);
robj
*
rdbLoadObject
(
int
type
,
rio
*
rdb
);
void
backgroundSaveDoneHandler
(
int
exitcode
,
int
bysignal
);
int
rdbSaveKeyValuePair
(
rio
*
rdb
,
robj
*
key
,
robj
*
val
,
time_t
expireitme
,
time_t
now
);
robj
*
rdbLoadStringObject
(
rio
*
rdb
);
#endif
src/redis.h
View file @
f9c6f39b
...
@@ -77,12 +77,6 @@
...
@@ -77,12 +77,6 @@
#define REDIS_HASH 4
#define REDIS_HASH 4
#define REDIS_VMPOINTER 8
#define REDIS_VMPOINTER 8
/* Object types only used for persistence in .rdb files */
#define REDIS_HASH_ZIPMAP 9
#define REDIS_LIST_ZIPLIST 10
#define REDIS_SET_INTSET 11
#define REDIS_ZSET_ZIPLIST 12
/* Objects encoding. Some kind of objects like Strings and Hashes can be
/* Objects encoding. Some kind of objects like Strings and Hashes can be
* internally represented in multiple ways. The 'encoding' field of the object
* internally represented in multiple ways. The 'encoding' field of the object
* is set to one of this fields for this object. */
* is set to one of this fields for this object. */
...
@@ -836,11 +830,6 @@ unsigned long estimateObjectIdleTime(robj *o);
...
@@ -836,11 +830,6 @@ unsigned long estimateObjectIdleTime(robj *o);
int
syncWrite
(
int
fd
,
char
*
ptr
,
ssize_t
size
,
int
timeout
);
int
syncWrite
(
int
fd
,
char
*
ptr
,
ssize_t
size
,
int
timeout
);
int
syncRead
(
int
fd
,
char
*
ptr
,
ssize_t
size
,
int
timeout
);
int
syncRead
(
int
fd
,
char
*
ptr
,
ssize_t
size
,
int
timeout
);
int
syncReadLine
(
int
fd
,
char
*
ptr
,
ssize_t
size
,
int
timeout
);
int
syncReadLine
(
int
fd
,
char
*
ptr
,
ssize_t
size
,
int
timeout
);
int
fwriteBulkString
(
FILE
*
fp
,
char
*
s
,
unsigned
long
len
);
int
fwriteBulkDouble
(
FILE
*
fp
,
double
d
);
int
fwriteBulkLongLong
(
FILE
*
fp
,
long
long
l
);
int
fwriteBulkObject
(
FILE
*
fp
,
robj
*
obj
);
int
fwriteBulkCount
(
FILE
*
fp
,
char
prefix
,
int
count
);
/* Replication */
/* Replication */
void
replicationFeedSlaves
(
list
*
slaves
,
int
dictid
,
robj
**
argv
,
int
argc
);
void
replicationFeedSlaves
(
list
*
slaves
,
int
dictid
,
robj
**
argv
,
int
argc
);
...
@@ -854,21 +843,7 @@ void loadingProgress(off_t pos);
...
@@ -854,21 +843,7 @@ void loadingProgress(off_t pos);
void
stopLoading
(
void
);
void
stopLoading
(
void
);
/* RDB persistence */
/* RDB persistence */
int
rdbLoad
(
char
*
filename
);
#include "rdb.h"
int
rdbSaveBackground
(
char
*
filename
);
void
rdbRemoveTempFile
(
pid_t
childpid
);
int
rdbSave
(
char
*
filename
);
int
rdbSaveObject
(
FILE
*
fp
,
robj
*
o
);
off_t
rdbSavedObjectLen
(
robj
*
o
);
off_t
rdbSavedObjectPages
(
robj
*
o
);
robj
*
rdbLoadObject
(
int
type
,
FILE
*
fp
);
void
backgroundSaveDoneHandler
(
int
exitcode
,
int
bysignal
);
int
rdbSaveKeyValuePair
(
FILE
*
fp
,
robj
*
key
,
robj
*
val
,
time_t
expireitme
,
time_t
now
);
int
rdbLoadType
(
FILE
*
fp
);
time_t
rdbLoadTime
(
FILE
*
fp
);
robj
*
rdbLoadStringObject
(
FILE
*
fp
);
int
rdbSaveType
(
FILE
*
fp
,
unsigned
char
type
);
int
rdbSaveLen
(
FILE
*
fp
,
uint32_t
len
);
/* AOF persistence */
/* AOF persistence */
void
flushAppendOnlyFile
(
int
force
);
void
flushAppendOnlyFile
(
int
force
);
...
...
src/rio.c
0 → 100644
View file @
f9c6f39b
#include <string.h>
#include "rio.h"
#include "util.h"
/* Returns 1 or 0 for success/failure. */
static
size_t
rioBufferWrite
(
rio
*
r
,
const
void
*
buf
,
size_t
len
)
{
r
->
io
.
buffer
.
ptr
=
sdscatlen
(
r
->
io
.
buffer
.
ptr
,(
char
*
)
buf
,
len
);
r
->
io
.
buffer
.
pos
+=
len
;
return
len
;
}
/* Returns 1 or 0 for success/failure. */
static
size_t
rioBufferRead
(
rio
*
r
,
void
*
buf
,
size_t
len
)
{
if
(
sdslen
(
r
->
io
.
buffer
.
ptr
)
-
r
->
io
.
buffer
.
pos
<
len
)
return
0
;
memcpy
(
buf
,
r
->
io
.
buffer
.
ptr
+
r
->
io
.
buffer
.
pos
,
len
);
r
->
io
.
buffer
.
pos
+=
len
;
return
1
;
}
/* Returns read/write position in buffer. */
static
off_t
rioBufferTell
(
rio
*
r
)
{
return
r
->
io
.
buffer
.
pos
;
}
/* Returns 1 or 0 for success/failure. */
static
size_t
rioFileWrite
(
rio
*
r
,
const
void
*
buf
,
size_t
len
)
{
return
fwrite
(
buf
,
len
,
1
,
r
->
io
.
file
.
fp
);
}
/* Returns 1 or 0 for success/failure. */
static
size_t
rioFileRead
(
rio
*
r
,
void
*
buf
,
size_t
len
)
{
return
fread
(
buf
,
len
,
1
,
r
->
io
.
file
.
fp
);
}
/* Returns read/write position in file. */
static
off_t
rioFileTell
(
rio
*
r
)
{
return
ftello
(
r
->
io
.
file
.
fp
);
}
static
const
rio
rioBufferIO
=
{
rioBufferRead
,
rioBufferWrite
,
rioBufferTell
,
{
{
NULL
,
0
}
}
/* union for io-specific vars */
};
static
const
rio
rioFileIO
=
{
rioFileRead
,
rioFileWrite
,
rioFileTell
,
{
{
NULL
,
0
}
}
/* union for io-specific vars */
};
rio
rioInitWithFile
(
FILE
*
fp
)
{
rio
r
=
rioFileIO
;
r
.
io
.
file
.
fp
=
fp
;
return
r
;
}
rio
rioInitWithBuffer
(
sds
s
)
{
rio
r
=
rioBufferIO
;
r
.
io
.
buffer
.
ptr
=
s
;
r
.
io
.
buffer
.
pos
=
0
;
return
r
;
}
/* Write multi bulk count in the format: "*<count>\r\n". */
size_t
rioWriteBulkCount
(
rio
*
r
,
char
prefix
,
int
count
)
{
char
cbuf
[
128
];
int
clen
;
cbuf
[
0
]
=
prefix
;
clen
=
1
+
ll2string
(
cbuf
+
1
,
sizeof
(
cbuf
)
-
1
,
count
);
cbuf
[
clen
++
]
=
'\r'
;
cbuf
[
clen
++
]
=
'\n'
;
if
(
rioWrite
(
r
,
cbuf
,
clen
)
==
0
)
return
0
;
return
clen
;
}
/* Write binary-safe string in the format: "$<count>\r\n<payload>\r\n". */
size_t
rioWriteBulkString
(
rio
*
r
,
const
char
*
buf
,
size_t
len
)
{
size_t
nwritten
;
if
((
nwritten
=
rioWriteBulkCount
(
r
,
'$'
,
len
))
==
0
)
return
0
;
if
(
len
>
0
&&
rioWrite
(
r
,
buf
,
len
)
==
0
)
return
0
;
if
(
rioWrite
(
r
,
"
\r\n
"
,
2
)
==
0
)
return
0
;
return
nwritten
+
len
+
2
;
}
/* Write a long long value in format: "$<count>\r\n<payload>\r\n". */
size_t
rioWriteBulkLongLong
(
rio
*
r
,
long
long
l
)
{
char
lbuf
[
32
];
unsigned
int
llen
;
llen
=
ll2string
(
lbuf
,
sizeof
(
lbuf
),
l
);
return
rioWriteBulkString
(
r
,
lbuf
,
llen
);
}
/* Write a double value in the format: "$<count>\r\n<payload>\r\n" */
size_t
rioWriteBulkDouble
(
rio
*
r
,
double
d
)
{
char
dbuf
[
128
];
unsigned
int
dlen
;
dlen
=
snprintf
(
dbuf
,
sizeof
(
dbuf
),
"%.17g"
,
d
);
return
rioWriteBulkString
(
r
,
dbuf
,
dlen
);
}
src/rio.h
0 → 100644
View file @
f9c6f39b
#ifndef __REDIS_RIO_H
#define __REDIS_RIO_H
#include <stdio.h>
#include "sds.h"
struct
_rio
{
/* Backend functions. Both read and write should return 0 for short reads
* or writes, identical to the return values of fread/fwrite. */
size_t
(
*
read
)(
struct
_rio
*
,
void
*
buf
,
size_t
len
);
size_t
(
*
write
)(
struct
_rio
*
,
const
void
*
buf
,
size_t
len
);
off_t
(
*
tell
)(
struct
_rio
*
);
/* Backend-specific vars. */
union
{
struct
{
sds
ptr
;
off_t
pos
;
}
buffer
;
struct
{
FILE
*
fp
;
}
file
;
}
io
;
};
typedef
struct
_rio
rio
;
#define rioWrite(rio,buf,len) ((rio)->write((rio),(buf),(len)))
#define rioRead(rio,buf,len) ((rio)->read((rio),(buf),(len)))
rio
rioInitWithFile
(
FILE
*
fp
);
rio
rioInitWithBuffer
(
sds
s
);
size_t
rioWriteBulkCount
(
rio
*
r
,
char
prefix
,
int
count
);
size_t
rioWriteBulkString
(
rio
*
r
,
const
char
*
buf
,
size_t
len
);
size_t
rioWriteBulkLongLong
(
rio
*
r
,
long
long
l
);
size_t
rioWriteBulkDouble
(
rio
*
r
,
double
d
);
#endif
src/syncio.c
View file @
f9c6f39b
...
@@ -99,70 +99,3 @@ int syncReadLine(int fd, char *ptr, ssize_t size, int timeout) {
...
@@ -99,70 +99,3 @@ int syncReadLine(int fd, char *ptr, ssize_t size, int timeout) {
}
}
return
nread
;
return
nread
;
}
}
/* ----------------- Blocking sockets I/O with timeouts --------------------- */
/* Write binary-safe string into a file in the bulkformat
* $<count>\r\n<payload>\r\n */
int
fwriteBulkString
(
FILE
*
fp
,
char
*
s
,
unsigned
long
len
)
{
char
cbuf
[
128
];
int
clen
;
cbuf
[
0
]
=
'$'
;
clen
=
1
+
ll2string
(
cbuf
+
1
,
sizeof
(
cbuf
)
-
1
,
len
);
cbuf
[
clen
++
]
=
'\r'
;
cbuf
[
clen
++
]
=
'\n'
;
if
(
fwrite
(
cbuf
,
clen
,
1
,
fp
)
==
0
)
return
0
;
if
(
len
>
0
&&
fwrite
(
s
,
len
,
1
,
fp
)
==
0
)
return
0
;
if
(
fwrite
(
"
\r\n
"
,
2
,
1
,
fp
)
==
0
)
return
0
;
return
1
;
}
/* Write a multi bulk count in the form "*<count>\r\n" */
int
fwriteBulkCount
(
FILE
*
fp
,
char
prefix
,
int
count
)
{
char
cbuf
[
128
];
int
clen
;
cbuf
[
0
]
=
prefix
;
clen
=
1
+
ll2string
(
cbuf
+
1
,
sizeof
(
cbuf
)
-
1
,
count
);
cbuf
[
clen
++
]
=
'\r'
;
cbuf
[
clen
++
]
=
'\n'
;
if
(
fwrite
(
cbuf
,
clen
,
1
,
fp
)
==
0
)
return
0
;
return
1
;
}
/* Write a double value in bulk format $<count>\r\n<payload>\r\n */
int
fwriteBulkDouble
(
FILE
*
fp
,
double
d
)
{
char
buf
[
128
],
dbuf
[
128
];
snprintf
(
dbuf
,
sizeof
(
dbuf
),
"%.17g
\r\n
"
,
d
);
snprintf
(
buf
,
sizeof
(
buf
),
"$%lu
\r\n
"
,(
unsigned
long
)
strlen
(
dbuf
)
-
2
);
if
(
fwrite
(
buf
,
strlen
(
buf
),
1
,
fp
)
==
0
)
return
0
;
if
(
fwrite
(
dbuf
,
strlen
(
dbuf
),
1
,
fp
)
==
0
)
return
0
;
return
1
;
}
/* Write a long value in bulk format $<count>\r\n<payload>\r\n */
int
fwriteBulkLongLong
(
FILE
*
fp
,
long
long
l
)
{
char
bbuf
[
128
],
lbuf
[
128
];
unsigned
int
blen
,
llen
;
llen
=
ll2string
(
lbuf
,
32
,
l
);
blen
=
snprintf
(
bbuf
,
sizeof
(
bbuf
),
"$%u
\r\n
%s
\r\n
"
,
llen
,
lbuf
);
if
(
fwrite
(
bbuf
,
blen
,
1
,
fp
)
==
0
)
return
0
;
return
1
;
}
/* Delegate writing an object to writing a bulk string or bulk long long. */
int
fwriteBulkObject
(
FILE
*
fp
,
robj
*
obj
)
{
/* Avoid using getDecodedObject to help copy-on-write (we are often
* in a child process when this function is called). */
if
(
obj
->
encoding
==
REDIS_ENCODING_INT
)
{
return
fwriteBulkLongLong
(
fp
,(
long
)
obj
->
ptr
);
}
else
if
(
obj
->
encoding
==
REDIS_ENCODING_RAW
)
{
return
fwriteBulkString
(
fp
,
obj
->
ptr
,
sdslen
(
obj
->
ptr
));
}
else
{
redisPanic
(
"Unknown string encoding"
);
}
}
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