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
307868e1
Commit
307868e1
authored
Jun 14, 2011
by
antirez
Browse files
DB API refactoring. The changes were designed together with Pieter Noordhuis.
parent
322ad086
Changes
5
Hide whitespace changes
Inline
Side-by-side
src/db.c
View file @
307868e1
...
@@ -67,34 +67,43 @@ robj *lookupKeyWriteOrReply(redisClient *c, robj *key, robj *reply) {
...
@@ -67,34 +67,43 @@ robj *lookupKeyWriteOrReply(redisClient *c, robj *key, robj *reply) {
return
o
;
return
o
;
}
}
/* Add the key to the DB. If the key already exists REDIS_ERR is returned,
/* Add the key to the DB. It's up to the caller to increment the reference
* otherwise REDIS_OK is returned, and the caller should increment the
* counte of the value if needed.
* refcount of 'val'. */
*
int
dbAdd
(
redisDb
*
db
,
robj
*
key
,
robj
*
val
)
{
* The program is aborted if the key already exists. */
/* Perform a lookup before adding the key, as we need to copy the
void
dbAdd
(
redisDb
*
db
,
robj
*
key
,
robj
*
val
)
{
* key value. */
sds
copy
=
sdsdup
(
key
->
ptr
);
if
(
dictFind
(
db
->
dict
,
key
->
ptr
)
!=
NULL
)
{
int
retval
=
dictAdd
(
db
->
dict
,
copy
,
val
);
return
REDIS_ERR
;
redisAssert
(
retval
==
REDIS_OK
);
}
else
{
sds
copy
=
sdsdup
(
key
->
ptr
);
dictAdd
(
db
->
dict
,
copy
,
val
);
return
REDIS_OK
;
}
}
}
/* If the key does not exist, this is just like dbAdd(). Otherwise
/* Overwrite an existing key with a new value. Incrementing the reference
* the value associated to the key is replaced with the new one.
* count of the new value is up to the caller.
* This function does not modify the expire time of the existing key.
*
*
* On update (key already existed) 0 is returned. Otherwise 1. */
* The program is aborted if the key was not already present. */
int
dbReplace
(
redisDb
*
db
,
robj
*
key
,
robj
*
val
)
{
void
dbOverwrite
(
redisDb
*
db
,
robj
*
key
,
robj
*
val
)
{
if
(
dictFind
(
db
->
dict
,
key
->
ptr
)
==
NULL
)
{
struct
dictEntry
*
de
=
dictFind
(
db
->
dict
,
key
->
ptr
);
sds
copy
=
sdsdup
(
key
->
ptr
);
dictAdd
(
db
->
dict
,
copy
,
val
);
redisAssert
(
de
!=
NULL
);
return
1
;
dictReplace
(
db
->
dict
,
key
->
ptr
,
val
);
}
/* High level Set operation. This function can be used in order to set
* a key, whatever it was existing or not, to a new object.
*
* 1) The ref count of the value object is incremented.
* 2) clients WATCHing for the destination key notified.
* 3) The expire time of the key is reset (the key is made persistent). */
void
setKey
(
redisDb
*
db
,
robj
*
key
,
robj
*
val
)
{
if
(
lookupKeyWrite
(
db
,
key
)
==
NULL
)
{
dbAdd
(
db
,
key
,
val
);
}
else
{
}
else
{
dictReplace
(
db
->
dict
,
key
->
ptr
,
val
);
dbOverwrite
(
db
,
key
,
val
);
return
0
;
}
}
incrRefCount
(
val
);
removeExpire
(
db
,
key
);
touchWatchedKey
(
db
,
key
);
}
}
int
dbExists
(
redisDb
*
db
,
robj
*
key
)
{
int
dbExists
(
redisDb
*
db
,
robj
*
key
)
{
...
@@ -326,13 +335,15 @@ void renameGenericCommand(redisClient *c, int nx) {
...
@@ -326,13 +335,15 @@ void renameGenericCommand(redisClient *c, int nx) {
return
;
return
;
incrRefCount
(
o
);
incrRefCount
(
o
);
if
(
dbAdd
(
c
->
db
,
c
->
argv
[
2
]
,
o
)
=
=
REDIS_ERR
)
{
if
(
lookupKeyWrite
(
c
->
db
,
c
->
argv
[
2
])
!
=
NULL
)
{
if
(
nx
)
{
if
(
nx
)
{
decrRefCount
(
o
);
decrRefCount
(
o
);
addReply
(
c
,
shared
.
czero
);
addReply
(
c
,
shared
.
czero
);
return
;
return
;
}
}
dbReplace
(
c
->
db
,
c
->
argv
[
2
],
o
);
dbOverwrite
(
c
->
db
,
c
->
argv
[
2
],
o
);
}
else
{
dbAdd
(
c
->
db
,
c
->
argv
[
2
],
o
);
}
}
dbDelete
(
c
->
db
,
c
->
argv
[
1
]);
dbDelete
(
c
->
db
,
c
->
argv
[
1
]);
touchWatchedKey
(
c
->
db
,
c
->
argv
[
1
]);
touchWatchedKey
(
c
->
db
,
c
->
argv
[
1
]);
...
@@ -378,11 +389,12 @@ void moveCommand(redisClient *c) {
...
@@ -378,11 +389,12 @@ void moveCommand(redisClient *c) {
return
;
return
;
}
}
/*
Try to add the element to
the target DB */
/*
Return zero if the key already exists in
the target DB */
if
(
dbAdd
(
dst
,
c
->
argv
[
1
]
,
o
)
=
=
REDIS_ERR
)
{
if
(
lookupKeyWrite
(
dst
,
c
->
argv
[
1
])
!
=
NULL
)
{
addReply
(
c
,
shared
.
czero
);
addReply
(
c
,
shared
.
czero
);
return
;
return
;
}
}
dbAdd
(
dst
,
c
->
argv
[
1
],
o
);
incrRefCount
(
o
);
incrRefCount
(
o
);
/* OK! key moved, free the entry in the source DB */
/* OK! key moved, free the entry in the source DB */
...
...
src/rdb.c
View file @
307868e1
...
@@ -929,7 +929,7 @@ void stopLoading(void) {
...
@@ -929,7 +929,7 @@ void stopLoading(void) {
int
rdbLoad
(
char
*
filename
)
{
int
rdbLoad
(
char
*
filename
)
{
FILE
*
fp
;
FILE
*
fp
;
uint32_t
dbid
;
uint32_t
dbid
;
int
type
,
retval
,
rdbver
;
int
type
,
rdbver
;
int
swap_all_values
=
0
;
int
swap_all_values
=
0
;
redisDb
*
db
=
server
.
db
+
0
;
redisDb
*
db
=
server
.
db
+
0
;
char
buf
[
1024
];
char
buf
[
1024
];
...
@@ -995,11 +995,8 @@ int rdbLoad(char *filename) {
...
@@ -995,11 +995,8 @@ int rdbLoad(char *filename) {
continue
;
continue
;
}
}
/* Add the new object in the hash table */
/* Add the new object in the hash table */
retval
=
dbAdd
(
db
,
key
,
val
);
dbAdd
(
db
,
key
,
val
);
if
(
retval
==
REDIS_ERR
)
{
redisLog
(
REDIS_WARNING
,
"Loading DB, duplicated key (%s) found! Unrecoverable error, exiting now."
,
key
->
ptr
);
exit
(
1
);
}
/* Set the expire time if needed */
/* Set the expire time if needed */
if
(
expiretime
!=
-
1
)
setExpire
(
db
,
key
,
expiretime
);
if
(
expiretime
!=
-
1
)
setExpire
(
db
,
key
,
expiretime
);
...
...
src/redis.h
View file @
307868e1
...
@@ -902,8 +902,9 @@ robj *lookupKeyRead(redisDb *db, robj *key);
...
@@ -902,8 +902,9 @@ robj *lookupKeyRead(redisDb *db, robj *key);
robj
*
lookupKeyWrite
(
redisDb
*
db
,
robj
*
key
);
robj
*
lookupKeyWrite
(
redisDb
*
db
,
robj
*
key
);
robj
*
lookupKeyReadOrReply
(
redisClient
*
c
,
robj
*
key
,
robj
*
reply
);
robj
*
lookupKeyReadOrReply
(
redisClient
*
c
,
robj
*
key
,
robj
*
reply
);
robj
*
lookupKeyWriteOrReply
(
redisClient
*
c
,
robj
*
key
,
robj
*
reply
);
robj
*
lookupKeyWriteOrReply
(
redisClient
*
c
,
robj
*
key
,
robj
*
reply
);
int
dbAdd
(
redisDb
*
db
,
robj
*
key
,
robj
*
val
);
void
dbAdd
(
redisDb
*
db
,
robj
*
key
,
robj
*
val
);
int
dbReplace
(
redisDb
*
db
,
robj
*
key
,
robj
*
val
);
void
dbOverwrite
(
redisDb
*
db
,
robj
*
key
,
robj
*
val
);
void
setKey
(
redisDb
*
db
,
robj
*
key
,
robj
*
val
);
int
dbExists
(
redisDb
*
db
,
robj
*
key
);
int
dbExists
(
redisDb
*
db
,
robj
*
key
);
robj
*
dbRandomKey
(
redisDb
*
db
);
robj
*
dbRandomKey
(
redisDb
*
db
);
int
dbDelete
(
redisDb
*
db
,
robj
*
key
);
int
dbDelete
(
redisDb
*
db
,
robj
*
key
);
...
...
src/sort.c
View file @
307868e1
...
@@ -366,12 +366,12 @@ void sortCommand(redisClient *c) {
...
@@ -366,12 +366,12 @@ void sortCommand(redisClient *c) {
}
}
}
}
}
}
dbReplace
(
c
->
db
,
storekey
,
sobj
);
setKey
(
c
->
db
,
storekey
,
sobj
);
decrRefCount
(
sobj
);
/* Note: we add 1 because the DB is dirty anyway since even if the
/* Note: we add 1 because the DB is dirty anyway since even if the
* SORT result is empty a new key is set and maybe the old content
* SORT result is empty a new key is set and maybe the old content
* replaced. */
* replaced. */
server
.
dirty
+=
1
+
outputlen
;
server
.
dirty
+=
1
+
outputlen
;
touchWatchedKey
(
c
->
db
,
storekey
);
addReplyLongLong
(
c
,
outputlen
);
addReplyLongLong
(
c
,
outputlen
);
}
}
...
...
src/t_string.c
View file @
307868e1
...
@@ -13,7 +13,6 @@ static int checkStringLength(redisClient *c, long long size) {
...
@@ -13,7 +13,6 @@ static int checkStringLength(redisClient *c, long long size) {
}
}
void
setGenericCommand
(
redisClient
*
c
,
int
nx
,
robj
*
key
,
robj
*
val
,
robj
*
expire
)
{
void
setGenericCommand
(
redisClient
*
c
,
int
nx
,
robj
*
key
,
robj
*
val
,
robj
*
expire
)
{
int
retval
;
long
seconds
=
0
;
/* initialized to avoid an harmness warning */
long
seconds
=
0
;
/* initialized to avoid an harmness warning */
if
(
expire
)
{
if
(
expire
)
{
...
@@ -25,21 +24,12 @@ void setGenericCommand(redisClient *c, int nx, robj *key, robj *val, robj *expir
...
@@ -25,21 +24,12 @@ void setGenericCommand(redisClient *c, int nx, robj *key, robj *val, robj *expir
}
}
}
}
retval
=
dbAdd
(
c
->
db
,
key
,
val
);
if
(
lookupKeyWrite
(
c
->
db
,
key
)
!=
NULL
&&
nx
)
{
if
(
retval
==
REDIS_ERR
)
{
addReply
(
c
,
shared
.
czero
);
if
(
!
nx
)
{
return
;
dbReplace
(
c
->
db
,
key
,
val
);
incrRefCount
(
val
);
}
else
{
addReply
(
c
,
shared
.
czero
);
return
;
}
}
else
{
incrRefCount
(
val
);
}
}
touchWatched
Key
(
c
->
db
,
key
);
set
Key
(
c
->
db
,
key
,
val
);
server
.
dirty
++
;
server
.
dirty
++
;
removeExpire
(
c
->
db
,
key
);
if
(
expire
)
setExpire
(
c
->
db
,
key
,
time
(
NULL
)
+
seconds
);
if
(
expire
)
setExpire
(
c
->
db
,
key
,
time
(
NULL
)
+
seconds
);
addReply
(
c
,
nx
?
shared
.
cone
:
shared
.
ok
);
addReply
(
c
,
nx
?
shared
.
cone
:
shared
.
ok
);
}
}
...
@@ -81,9 +71,7 @@ void getCommand(redisClient *c) {
...
@@ -81,9 +71,7 @@ void getCommand(redisClient *c) {
void
getsetCommand
(
redisClient
*
c
)
{
void
getsetCommand
(
redisClient
*
c
)
{
if
(
getGenericCommand
(
c
)
==
REDIS_ERR
)
return
;
if
(
getGenericCommand
(
c
)
==
REDIS_ERR
)
return
;
c
->
argv
[
2
]
=
tryObjectEncoding
(
c
->
argv
[
2
]);
c
->
argv
[
2
]
=
tryObjectEncoding
(
c
->
argv
[
2
]);
dbReplace
(
c
->
db
,
c
->
argv
[
1
],
c
->
argv
[
2
]);
setKey
(
c
->
db
,
c
->
argv
[
1
],
c
->
argv
[
2
]);
incrRefCount
(
c
->
argv
[
2
]);
touchWatchedKey
(
c
->
db
,
c
->
argv
[
1
]);
server
.
dirty
++
;
server
.
dirty
++
;
removeExpire
(
c
->
db
,
c
->
argv
[
1
]);
removeExpire
(
c
->
db
,
c
->
argv
[
1
]);
}
}
...
@@ -138,7 +126,7 @@ void setbitCommand(redisClient *c) {
...
@@ -138,7 +126,7 @@ void setbitCommand(redisClient *c) {
robj
*
decoded
=
getDecodedObject
(
o
);
robj
*
decoded
=
getDecodedObject
(
o
);
o
=
createStringObject
(
decoded
->
ptr
,
sdslen
(
decoded
->
ptr
));
o
=
createStringObject
(
decoded
->
ptr
,
sdslen
(
decoded
->
ptr
));
decrRefCount
(
decoded
);
decrRefCount
(
decoded
);
db
Replac
e
(
c
->
db
,
c
->
argv
[
1
],
o
);
db
Overwrit
e
(
c
->
db
,
c
->
argv
[
1
],
o
);
}
}
}
}
...
@@ -236,7 +224,7 @@ void setrangeCommand(redisClient *c) {
...
@@ -236,7 +224,7 @@ void setrangeCommand(redisClient *c) {
robj
*
decoded
=
getDecodedObject
(
o
);
robj
*
decoded
=
getDecodedObject
(
o
);
o
=
createStringObject
(
decoded
->
ptr
,
sdslen
(
decoded
->
ptr
));
o
=
createStringObject
(
decoded
->
ptr
,
sdslen
(
decoded
->
ptr
));
decrRefCount
(
decoded
);
decrRefCount
(
decoded
);
db
Replac
e
(
c
->
db
,
c
->
argv
[
1
],
o
);
db
Overwrit
e
(
c
->
db
,
c
->
argv
[
1
],
o
);
}
}
}
}
...
@@ -319,18 +307,15 @@ void msetGenericCommand(redisClient *c, int nx) {
...
@@ -319,18 +307,15 @@ void msetGenericCommand(redisClient *c, int nx) {
busykeys
++
;
busykeys
++
;
}
}
}
}
}
if
(
busykeys
)
{
if
(
busykeys
)
{
addReply
(
c
,
shared
.
czero
);
addReply
(
c
,
shared
.
czero
)
;
return
;
return
;
}
}
}
for
(
j
=
1
;
j
<
c
->
argc
;
j
+=
2
)
{
for
(
j
=
1
;
j
<
c
->
argc
;
j
+=
2
)
{
c
->
argv
[
j
+
1
]
=
tryObjectEncoding
(
c
->
argv
[
j
+
1
]);
c
->
argv
[
j
+
1
]
=
tryObjectEncoding
(
c
->
argv
[
j
+
1
]);
dbReplace
(
c
->
db
,
c
->
argv
[
j
],
c
->
argv
[
j
+
1
]);
setKey
(
c
->
db
,
c
->
argv
[
j
],
c
->
argv
[
j
+
1
]);
incrRefCount
(
c
->
argv
[
j
+
1
]);
removeExpire
(
c
->
db
,
c
->
argv
[
j
]);
touchWatchedKey
(
c
->
db
,
c
->
argv
[
j
]);
}
}
server
.
dirty
+=
(
c
->
argc
-
1
)
/
2
;
server
.
dirty
+=
(
c
->
argc
-
1
)
/
2
;
addReply
(
c
,
nx
?
shared
.
cone
:
shared
.
ok
);
addReply
(
c
,
nx
?
shared
.
cone
:
shared
.
ok
);
...
@@ -346,7 +331,7 @@ void msetnxCommand(redisClient *c) {
...
@@ -346,7 +331,7 @@ void msetnxCommand(redisClient *c) {
void
incrDecrCommand
(
redisClient
*
c
,
long
long
incr
)
{
void
incrDecrCommand
(
redisClient
*
c
,
long
long
incr
)
{
long
long
value
,
oldvalue
;
long
long
value
,
oldvalue
;
robj
*
o
;
robj
*
o
,
*
new
;
o
=
lookupKeyWrite
(
c
->
db
,
c
->
argv
[
1
]);
o
=
lookupKeyWrite
(
c
->
db
,
c
->
argv
[
1
]);
if
(
o
!=
NULL
&&
checkType
(
c
,
o
,
REDIS_STRING
))
return
;
if
(
o
!=
NULL
&&
checkType
(
c
,
o
,
REDIS_STRING
))
return
;
...
@@ -358,12 +343,15 @@ void incrDecrCommand(redisClient *c, long long incr) {
...
@@ -358,12 +343,15 @@ void incrDecrCommand(redisClient *c, long long incr) {
addReplyError
(
c
,
"increment or decrement would overflow"
);
addReplyError
(
c
,
"increment or decrement would overflow"
);
return
;
return
;
}
}
o
=
createStringObjectFromLongLong
(
value
);
new
=
createStringObjectFromLongLong
(
value
);
dbReplace
(
c
->
db
,
c
->
argv
[
1
],
o
);
if
(
o
)
dbOverwrite
(
c
->
db
,
c
->
argv
[
1
],
new
);
else
dbAdd
(
c
->
db
,
c
->
argv
[
1
],
new
);
touchWatchedKey
(
c
->
db
,
c
->
argv
[
1
]);
touchWatchedKey
(
c
->
db
,
c
->
argv
[
1
]);
server
.
dirty
++
;
server
.
dirty
++
;
addReply
(
c
,
shared
.
colon
);
addReply
(
c
,
shared
.
colon
);
addReply
(
c
,
o
);
addReply
(
c
,
new
);
addReply
(
c
,
shared
.
crlf
);
addReply
(
c
,
shared
.
crlf
);
}
}
...
@@ -416,7 +404,7 @@ void appendCommand(redisClient *c) {
...
@@ -416,7 +404,7 @@ void appendCommand(redisClient *c) {
robj
*
decoded
=
getDecodedObject
(
o
);
robj
*
decoded
=
getDecodedObject
(
o
);
o
=
createStringObject
(
decoded
->
ptr
,
sdslen
(
decoded
->
ptr
));
o
=
createStringObject
(
decoded
->
ptr
,
sdslen
(
decoded
->
ptr
));
decrRefCount
(
decoded
);
decrRefCount
(
decoded
);
db
Replac
e
(
c
->
db
,
c
->
argv
[
1
],
o
);
db
Overwrit
e
(
c
->
db
,
c
->
argv
[
1
],
o
);
}
}
/* Append the value */
/* Append the value */
...
...
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