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
f85cd526
Commit
f85cd526
authored
Jun 14, 2011
by
antirez
Browse files
DB API refactoring. The changes were designed together with Pieter Noordhuis.
parent
3e2a0bf4
Changes
7
Show whitespace changes
Inline
Side-by-side
src/cluster.c
View file @
f85cd526
...
...
@@ -1390,7 +1390,7 @@ void restoreCommand(redisClient *c) {
long
ttl
;
/* Make sure this key does not already exist here... */
if
(
dbExists
(
c
->
db
,
c
->
argv
[
1
]))
{
if
(
lookupKeyWrite
(
c
->
db
,
c
->
argv
[
1
])
!=
NULL
)
{
addReplyError
(
c
,
"Target key name is busy."
);
return
;
}
...
...
src/db.c
View file @
f85cd526
...
...
@@ -86,8 +86,7 @@ robj *lookupKey(redisDb *db, robj *key) {
redisLog
(
REDIS_DEBUG
,
"Force loading key %s via lookup"
,
key
->
ptr
);
val
=
dsGet
(
db
,
key
,
&
expire
);
if
(
val
)
{
int
retval
=
dbAdd
(
db
,
key
,
val
);
redisAssert
(
retval
==
REDIS_OK
);
dbAdd
(
db
,
key
,
val
);
if
(
expire
!=
-
1
)
setExpire
(
db
,
key
,
expire
);
server
.
stat_keyspace_hits
++
;
return
val
;
...
...
@@ -122,42 +121,47 @@ robj *lookupKeyWriteOrReply(redisClient *c, robj *key, robj *reply) {
return
o
;
}
/* Add the key to the DB. If the key already exists REDIS_ERR is returned,
* otherwise REDIS_OK is returned, and the caller should increment the
* refcount of 'val'. */
int
dbAdd
(
redisDb
*
db
,
robj
*
key
,
robj
*
val
)
{
/* Perform a lookup before adding the key, as we need to copy the
* key value. */
if
(
dictFind
(
db
->
dict
,
key
->
ptr
)
!=
NULL
)
{
return
REDIS_ERR
;
}
else
{
/* Add the key to the DB. It's up to the caller to increment the reference
* counte of the value if needed.
*
* The program is aborted if the key already exists. */
void
dbAdd
(
redisDb
*
db
,
robj
*
key
,
robj
*
val
)
{
sds
copy
=
sdsdup
(
key
->
ptr
);
dictAdd
(
db
->
dict
,
copy
,
val
);
int
retval
=
dictAdd
(
db
->
dict
,
copy
,
val
);
redisAssert
(
retval
==
REDIS_OK
);
if
(
server
.
ds_enabled
)
cacheSetKeyMayExist
(
db
,
key
);
if
(
server
.
cluster_enabled
)
SlotToKeyAdd
(
key
);
return
REDIS_OK
;
}
}
/* If the key does not exist, this is just like dbAdd(). Otherwise
* the value associated to the key is replaced with the new one.
/* Overwrite an existing key with a new value. Incrementing the reference
* 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. */
int
dbReplace
(
redisDb
*
db
,
robj
*
key
,
robj
*
val
)
{
robj
*
oldval
;
int
retval
;
* The program is aborted if the key was not already present. */
void
dbOverwrite
(
redisDb
*
db
,
robj
*
key
,
robj
*
val
)
{
struct
dictEntry
*
de
=
dictFind
(
db
->
dict
,
key
->
ptr
);
if
((
oldval
=
dictFetchValue
(
db
->
dict
,
key
->
ptr
))
==
NULL
)
{
sds
copy
=
sdsdup
(
key
->
ptr
);
dictAdd
(
db
->
dict
,
copy
,
val
);
if
(
server
.
cluster_enabled
)
SlotToKeyAdd
(
key
);
retval
=
1
;
}
else
{
redisAssert
(
de
!=
NULL
);
dictReplace
(
db
->
dict
,
key
->
ptr
,
val
);
retval
=
0
;
}
if
(
server
.
ds_enabled
)
cacheSetKeyMayExist
(
db
,
key
);
return
retval
;
}
/* 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
{
dbOverwrite
(
db
,
key
,
val
);
}
incrRefCount
(
val
);
removeExpire
(
db
,
key
);
touchWatchedKey
(
db
,
key
);
}
int
dbExists
(
redisDb
*
db
,
robj
*
key
)
{
...
...
@@ -414,13 +418,15 @@ void renameGenericCommand(redisClient *c, int nx) {
return
;
incrRefCount
(
o
);
if
(
dbAdd
(
c
->
db
,
c
->
argv
[
2
]
,
o
)
=
=
REDIS_ERR
)
{
if
(
lookupKeyWrite
(
c
->
db
,
c
->
argv
[
2
])
!
=
NULL
)
{
if
(
nx
)
{
decrRefCount
(
o
);
addReply
(
c
,
shared
.
czero
);
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
]);
signalModifiedKey
(
c
->
db
,
c
->
argv
[
1
]);
...
...
@@ -471,11 +477,12 @@ void moveCommand(redisClient *c) {
return
;
}
/*
Try to add the element to
the target DB */
if
(
dbAdd
(
dst
,
c
->
argv
[
1
]
,
o
)
=
=
REDIS_ERR
)
{
/*
Return zero if the key already exists in
the target DB */
if
(
lookupKeyWrite
(
dst
,
c
->
argv
[
1
])
!
=
NULL
)
{
addReply
(
c
,
shared
.
czero
);
return
;
}
dbAdd
(
dst
,
c
->
argv
[
1
],
o
);
incrRefCount
(
o
);
/* OK! key moved, free the entry in the source DB */
...
...
src/dscache.c
View file @
f85cd526
...
...
@@ -362,7 +362,8 @@ void vmThreadedIOCompletedJob(aeEventLoop *el, int fd, void *privdata,
if
(
j
->
val
!=
NULL
)
{
/* Note: it's possible that the key is already in memory
* due to a blocking load operation. */
if
(
dbAdd
(
j
->
db
,
j
->
key
,
j
->
val
)
==
REDIS_OK
)
{
if
(
dictFind
(
j
->
db
->
dict
,
j
->
key
->
ptr
)
==
NULL
)
{
dbAdd
(
j
->
db
,
j
->
key
,
j
->
val
);
incrRefCount
(
j
->
val
);
if
(
j
->
expire
!=
-
1
)
setExpire
(
j
->
db
,
j
->
key
,
j
->
expire
);
}
...
...
src/rdb.c
View file @
f85cd526
...
...
@@ -918,7 +918,7 @@ void stopLoading(void) {
int
rdbLoad
(
char
*
filename
)
{
FILE
*
fp
;
uint32_t
dbid
;
int
type
,
retval
,
rdbver
;
int
type
,
rdbver
;
redisDb
*
db
=
server
.
db
+
0
;
char
buf
[
1024
];
time_t
expiretime
,
now
=
time
(
NULL
);
...
...
@@ -981,11 +981,8 @@ int rdbLoad(char *filename) {
continue
;
}
/* Add the new object in the hash table */
retval
=
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
);
}
dbAdd
(
db
,
key
,
val
);
/* Set the expire time if needed */
if
(
expiretime
!=
-
1
)
setExpire
(
db
,
key
,
expiretime
);
...
...
src/redis.h
View file @
f85cd526
...
...
@@ -1058,8 +1058,9 @@ robj *lookupKeyRead(redisDb *db, robj *key);
robj
*
lookupKeyWrite
(
redisDb
*
db
,
robj
*
key
);
robj
*
lookupKeyReadOrReply
(
redisClient
*
c
,
robj
*
key
,
robj
*
reply
);
robj
*
lookupKeyWriteOrReply
(
redisClient
*
c
,
robj
*
key
,
robj
*
reply
);
int
dbAdd
(
redisDb
*
db
,
robj
*
key
,
robj
*
val
);
int
dbReplace
(
redisDb
*
db
,
robj
*
key
,
robj
*
val
);
void
dbAdd
(
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
);
robj
*
dbRandomKey
(
redisDb
*
db
);
int
dbDelete
(
redisDb
*
db
,
robj
*
key
);
...
...
src/sort.c
View file @
f85cd526
...
...
@@ -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
* SORT result is empty a new key is set and maybe the old content
* replaced. */
server
.
dirty
+=
1
+
outputlen
;
signalModifiedKey
(
c
->
db
,
storekey
);
addReplyLongLong
(
c
,
outputlen
);
}
...
...
src/t_string.c
View file @
f85cd526
...
...
@@ -13,7 +13,6 @@ static int checkStringLength(redisClient *c, long long size) {
}
void
setGenericCommand
(
redisClient
*
c
,
int
nx
,
robj
*
key
,
robj
*
val
,
robj
*
expire
)
{
int
retval
;
long
seconds
=
0
;
/* initialized to avoid an harmness warning */
if
(
expire
)
{
...
...
@@ -25,21 +24,12 @@ void setGenericCommand(redisClient *c, int nx, robj *key, robj *val, robj *expir
}
}
retval
=
dbAdd
(
c
->
db
,
key
,
val
);
if
(
retval
==
REDIS_ERR
)
{
if
(
!
nx
)
{
dbReplace
(
c
->
db
,
key
,
val
);
incrRefCount
(
val
);
}
else
{
if
(
lookupKeyWrite
(
c
->
db
,
key
)
!=
NULL
&&
nx
)
{
addReply
(
c
,
shared
.
czero
);
return
;
}
}
else
{
incrRefCount
(
val
);
}
signalModifiedKey
(
c
->
db
,
key
);
setKey
(
c
->
db
,
key
,
val
);
server
.
dirty
++
;
removeExpire
(
c
->
db
,
key
);
if
(
expire
)
setExpire
(
c
->
db
,
key
,
time
(
NULL
)
+
seconds
);
addReply
(
c
,
nx
?
shared
.
cone
:
shared
.
ok
);
}
...
...
@@ -81,9 +71,7 @@ void getCommand(redisClient *c) {
void
getsetCommand
(
redisClient
*
c
)
{
if
(
getGenericCommand
(
c
)
==
REDIS_ERR
)
return
;
c
->
argv
[
2
]
=
tryObjectEncoding
(
c
->
argv
[
2
]);
dbReplace
(
c
->
db
,
c
->
argv
[
1
],
c
->
argv
[
2
]);
incrRefCount
(
c
->
argv
[
2
]);
signalModifiedKey
(
c
->
db
,
c
->
argv
[
1
]);
setKey
(
c
->
db
,
c
->
argv
[
1
],
c
->
argv
[
2
]);
server
.
dirty
++
;
removeExpire
(
c
->
db
,
c
->
argv
[
1
]);
}
...
...
@@ -138,7 +126,7 @@ void setbitCommand(redisClient *c) {
robj
*
decoded
=
getDecodedObject
(
o
);
o
=
createStringObject
(
decoded
->
ptr
,
sdslen
(
decoded
->
ptr
));
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) {
robj
*
decoded
=
getDecodedObject
(
o
);
o
=
createStringObject
(
decoded
->
ptr
,
sdslen
(
decoded
->
ptr
));
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) {
busykeys
++
;
}
}
}
if
(
busykeys
)
{
addReply
(
c
,
shared
.
czero
);
return
;
}
}
for
(
j
=
1
;
j
<
c
->
argc
;
j
+=
2
)
{
c
->
argv
[
j
+
1
]
=
tryObjectEncoding
(
c
->
argv
[
j
+
1
]);
dbReplace
(
c
->
db
,
c
->
argv
[
j
],
c
->
argv
[
j
+
1
]);
incrRefCount
(
c
->
argv
[
j
+
1
]);
removeExpire
(
c
->
db
,
c
->
argv
[
j
]);
signalModifiedKey
(
c
->
db
,
c
->
argv
[
j
]);
setKey
(
c
->
db
,
c
->
argv
[
j
],
c
->
argv
[
j
+
1
]);
}
server
.
dirty
+=
(
c
->
argc
-
1
)
/
2
;
addReply
(
c
,
nx
?
shared
.
cone
:
shared
.
ok
);
...
...
@@ -346,7 +331,7 @@ void msetnxCommand(redisClient *c) {
void
incrDecrCommand
(
redisClient
*
c
,
long
long
incr
)
{
long
long
value
,
oldvalue
;
robj
*
o
;
robj
*
o
,
*
new
;
o
=
lookupKeyWrite
(
c
->
db
,
c
->
argv
[
1
]);
if
(
o
!=
NULL
&&
checkType
(
c
,
o
,
REDIS_STRING
))
return
;
...
...
@@ -358,12 +343,15 @@ void incrDecrCommand(redisClient *c, long long incr) {
addReplyError
(
c
,
"increment or decrement would overflow"
);
return
;
}
o
=
createStringObjectFromLongLong
(
value
);
dbReplace
(
c
->
db
,
c
->
argv
[
1
],
o
);
new
=
createStringObjectFromLongLong
(
value
);
if
(
o
)
dbOverwrite
(
c
->
db
,
c
->
argv
[
1
],
new
);
else
dbAdd
(
c
->
db
,
c
->
argv
[
1
],
new
);
signalModifiedKey
(
c
->
db
,
c
->
argv
[
1
]);
server
.
dirty
++
;
addReply
(
c
,
shared
.
colon
);
addReply
(
c
,
o
);
addReply
(
c
,
new
);
addReply
(
c
,
shared
.
crlf
);
}
...
...
@@ -416,7 +404,7 @@ void appendCommand(redisClient *c) {
robj
*
decoded
=
getDecodedObject
(
o
);
o
=
createStringObject
(
decoded
->
ptr
,
sdslen
(
decoded
->
ptr
));
decrRefCount
(
decoded
);
db
Replac
e
(
c
->
db
,
c
->
argv
[
1
],
o
);
db
Overwrit
e
(
c
->
db
,
c
->
argv
[
1
],
o
);
}
/* 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