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
Hide whitespace changes
Inline
Side-by-side
src/cluster.c
View file @
f85cd526
...
@@ -1390,7 +1390,7 @@ void restoreCommand(redisClient *c) {
...
@@ -1390,7 +1390,7 @@ void restoreCommand(redisClient *c) {
long
ttl
;
long
ttl
;
/* Make sure this key does not already exist here... */
/* 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."
);
addReplyError
(
c
,
"Target key name is busy."
);
return
;
return
;
}
}
...
...
src/db.c
View file @
f85cd526
...
@@ -86,8 +86,7 @@ robj *lookupKey(redisDb *db, robj *key) {
...
@@ -86,8 +86,7 @@ robj *lookupKey(redisDb *db, robj *key) {
redisLog
(
REDIS_DEBUG
,
"Force loading key %s via lookup"
,
key
->
ptr
);
redisLog
(
REDIS_DEBUG
,
"Force loading key %s via lookup"
,
key
->
ptr
);
val
=
dsGet
(
db
,
key
,
&
expire
);
val
=
dsGet
(
db
,
key
,
&
expire
);
if
(
val
)
{
if
(
val
)
{
int
retval
=
dbAdd
(
db
,
key
,
val
);
dbAdd
(
db
,
key
,
val
);
redisAssert
(
retval
==
REDIS_OK
);
if
(
expire
!=
-
1
)
setExpire
(
db
,
key
,
expire
);
if
(
expire
!=
-
1
)
setExpire
(
db
,
key
,
expire
);
server
.
stat_keyspace_hits
++
;
server
.
stat_keyspace_hits
++
;
return
val
;
return
val
;
...
@@ -122,42 +121,47 @@ robj *lookupKeyWriteOrReply(redisClient *c, robj *key, robj *reply) {
...
@@ -122,42 +121,47 @@ 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
;
}
else
{
redisAssert
(
retval
==
REDIS_OK
);
sds
copy
=
sdsdup
(
key
->
ptr
);
if
(
server
.
ds_enabled
)
cacheSetKeyMayExist
(
db
,
key
);
dictAdd
(
db
->
dict
,
copy
,
val
);
if
(
server
.
cluster_enabled
)
SlotToKeyAdd
(
key
);
if
(
server
.
ds_enabled
)
cacheSetKeyMayExist
(
db
,
key
);
}
if
(
server
.
cluster_enabled
)
SlotToKeyAdd
(
key
);
return
REDIS_OK
;
/* 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.
*
* 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
);
redisAssert
(
de
!=
NULL
);
dictReplace
(
db
->
dict
,
key
->
ptr
,
val
);
if
(
server
.
ds_enabled
)
cacheSetKeyMayExist
(
db
,
key
);
}
}
/*
If the key does not exist, this is just like dbAdd(). Otherwi
se
/*
High level Set operation. This function can be used in order to
se
t
*
the value associated to the key is replaced with the
new o
ne
.
*
a key, whatever it was existing or not, to a
new o
bject
.
*
*
* On update (key already existed) 0 is returned. Otherwise 1. */
* 1) The ref count of the value object is incremented.
int
dbReplace
(
redisDb
*
db
,
robj
*
key
,
robj
*
val
)
{
* 2) clients WATCHing for the destination key notified.
robj
*
oldval
;
* 3) The expire time of the key is reset (the key is made persistent). */
int
retval
;
void
setKey
(
redisDb
*
db
,
robj
*
key
,
robj
*
val
)
{
if
(
lookupKeyWrite
(
db
,
key
)
==
NULL
)
{
if
((
oldval
=
dictFetchValue
(
db
->
dict
,
key
->
ptr
))
==
NULL
)
{
dbAdd
(
db
,
key
,
val
);
sds
copy
=
sdsdup
(
key
->
ptr
);
dictAdd
(
db
->
dict
,
copy
,
val
);
if
(
server
.
cluster_enabled
)
SlotToKeyAdd
(
key
);
retval
=
1
;
}
else
{
}
else
{
dictReplace
(
db
->
dict
,
key
->
ptr
,
val
);
dbOverwrite
(
db
,
key
,
val
);
retval
=
0
;
}
}
if
(
server
.
ds_enabled
)
cacheSetKeyMayExist
(
db
,
key
);
incrRefCount
(
val
);
return
retval
;
removeExpire
(
db
,
key
);
touchWatchedKey
(
db
,
key
);
}
}
int
dbExists
(
redisDb
*
db
,
robj
*
key
)
{
int
dbExists
(
redisDb
*
db
,
robj
*
key
)
{
...
@@ -414,13 +418,15 @@ void renameGenericCommand(redisClient *c, int nx) {
...
@@ -414,13 +418,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
]);
signalModifiedKey
(
c
->
db
,
c
->
argv
[
1
]);
signalModifiedKey
(
c
->
db
,
c
->
argv
[
1
]);
...
@@ -471,11 +477,12 @@ void moveCommand(redisClient *c) {
...
@@ -471,11 +477,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/dscache.c
View file @
f85cd526
...
@@ -362,7 +362,8 @@ void vmThreadedIOCompletedJob(aeEventLoop *el, int fd, void *privdata,
...
@@ -362,7 +362,8 @@ void vmThreadedIOCompletedJob(aeEventLoop *el, int fd, void *privdata,
if
(
j
->
val
!=
NULL
)
{
if
(
j
->
val
!=
NULL
)
{
/* Note: it's possible that the key is already in memory
/* Note: it's possible that the key is already in memory
* due to a blocking load operation. */
* 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
);
incrRefCount
(
j
->
val
);
if
(
j
->
expire
!=
-
1
)
setExpire
(
j
->
db
,
j
->
key
,
j
->
expire
);
if
(
j
->
expire
!=
-
1
)
setExpire
(
j
->
db
,
j
->
key
,
j
->
expire
);
}
}
...
...
src/rdb.c
View file @
f85cd526
...
@@ -918,7 +918,7 @@ void stopLoading(void) {
...
@@ -918,7 +918,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
;
redisDb
*
db
=
server
.
db
+
0
;
redisDb
*
db
=
server
.
db
+
0
;
char
buf
[
1024
];
char
buf
[
1024
];
time_t
expiretime
,
now
=
time
(
NULL
);
time_t
expiretime
,
now
=
time
(
NULL
);
...
@@ -981,11 +981,8 @@ int rdbLoad(char *filename) {
...
@@ -981,11 +981,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 @
f85cd526
...
@@ -1058,8 +1058,9 @@ robj *lookupKeyRead(redisDb *db, robj *key);
...
@@ -1058,8 +1058,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 @
f85cd526
...
@@ -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
;
signalModifiedKey
(
c
->
db
,
storekey
);
addReplyLongLong
(
c
,
outputlen
);
addReplyLongLong
(
c
,
outputlen
);
}
}
...
...
src/t_string.c
View file @
f85cd526
...
@@ -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
);
}
}
s
ignalModified
Key
(
c
->
db
,
key
);
s
et
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
]);
signalModifiedKey
(
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
]);
signalModifiedKey
(
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
);
signalModifiedKey
(
c
->
db
,
c
->
argv
[
1
]);
signalModifiedKey
(
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