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
d785413d
Commit
d785413d
authored
Mar 28, 2013
by
antirez
Browse files
Extended SET command implemented (issue #931).
parent
e8a1a169
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/redis.c
View file @
d785413d
...
@@ -114,7 +114,7 @@ struct redisCommand *commandTable;
...
@@ -114,7 +114,7 @@ struct redisCommand *commandTable;
*/
*/
struct
redisCommand
redisCommandTable
[]
=
{
struct
redisCommand
redisCommandTable
[]
=
{
{
"get"
,
getCommand
,
2
,
"r"
,
0
,
NULL
,
1
,
1
,
1
,
0
,
0
},
{
"get"
,
getCommand
,
2
,
"r"
,
0
,
NULL
,
1
,
1
,
1
,
0
,
0
},
{
"set"
,
setCommand
,
3
,
"wm"
,
0
,
noPreloadGetKeys
,
1
,
1
,
1
,
0
,
0
},
{
"set"
,
setCommand
,
-
3
,
"wm"
,
0
,
noPreloadGetKeys
,
1
,
1
,
1
,
0
,
0
},
{
"setnx"
,
setnxCommand
,
3
,
"wm"
,
0
,
noPreloadGetKeys
,
1
,
1
,
1
,
0
,
0
},
{
"setnx"
,
setnxCommand
,
3
,
"wm"
,
0
,
noPreloadGetKeys
,
1
,
1
,
1
,
0
,
0
},
{
"setex"
,
setexCommand
,
4
,
"wm"
,
0
,
noPreloadGetKeys
,
1
,
1
,
1
,
0
,
0
},
{
"setex"
,
setexCommand
,
4
,
"wm"
,
0
,
noPreloadGetKeys
,
1
,
1
,
1
,
0
,
0
},
{
"psetex"
,
psetexCommand
,
4
,
"wm"
,
0
,
noPreloadGetKeys
,
1
,
1
,
1
,
0
,
0
},
{
"psetex"
,
psetexCommand
,
4
,
"wm"
,
0
,
noPreloadGetKeys
,
1
,
1
,
1
,
0
,
0
},
...
...
src/t_string.c
View file @
d785413d
...
@@ -42,7 +42,27 @@ static int checkStringLength(redisClient *c, long long size) {
...
@@ -42,7 +42,27 @@ static int checkStringLength(redisClient *c, long long size) {
return
REDIS_OK
;
return
REDIS_OK
;
}
}
void
setGenericCommand
(
redisClient
*
c
,
int
nx
,
robj
*
key
,
robj
*
val
,
robj
*
expire
,
int
unit
)
{
/* The setGenericCommand() function implements the SET operation with different
* options and variants. This function is called in order to implement the
* following commands: SET, SETEX, PSETEX, SETNX.
*
* 'flags' changes the behavior of the command (NX or XX, see belove).
*
* 'expire' represents an expire to set in form of a Redis object as passed
* by the user. It is interpreted according to the specified 'unit'.
*
* 'ok_reply' and 'abort_reply' is what the function will reply to the client
* if the operation is performed, or when it is not because of NX or
* XX flags.
*
* If ok_reply is NULL "+OK" is used.
* If abort_reply is NULL, "$-1" is used. */
#define REDIS_SET_NO_FLAGS 0
#define REDIS_SET_NX (1<<0)
/* Set if key not exists. */
#define REDIS_SET_XX (1<<1)
/* Set if key exists. */
void
setGenericCommand
(
redisClient
*
c
,
int
flags
,
robj
*
key
,
robj
*
val
,
robj
*
expire
,
int
unit
,
robj
*
ok_reply
,
robj
*
abort_reply
)
{
long
long
milliseconds
=
0
;
/* initialized to avoid any harmness warning */
long
long
milliseconds
=
0
;
/* initialized to avoid any harmness warning */
if
(
expire
)
{
if
(
expire
)
{
...
@@ -55,34 +75,64 @@ void setGenericCommand(redisClient *c, int nx, robj *key, robj *val, robj *expir
...
@@ -55,34 +75,64 @@ void setGenericCommand(redisClient *c, int nx, robj *key, robj *val, robj *expir
if
(
unit
==
UNIT_SECONDS
)
milliseconds
*=
1000
;
if
(
unit
==
UNIT_SECONDS
)
milliseconds
*=
1000
;
}
}
if
(
nx
&&
lookupKeyWrite
(
c
->
db
,
key
)
!=
NULL
)
{
if
((
flags
&
REDIS_SET_NX
&&
lookupKeyWrite
(
c
->
db
,
key
)
!=
NULL
)
||
addReply
(
c
,
shared
.
czero
);
(
flags
&
REDIS_SET_XX
&&
lookupKeyWrite
(
c
->
db
,
key
)
==
NULL
))
{
addReply
(
c
,
abort_reply
?
abort_reply
:
shared
.
nullbulk
);
return
;
return
;
}
}
setKey
(
c
->
db
,
key
,
val
);
setKey
(
c
->
db
,
key
,
val
);
server
.
dirty
++
;
server
.
dirty
++
;
if
(
expire
)
setExpire
(
c
->
db
,
key
,
mstime
()
+
milliseconds
);
if
(
expire
)
setExpire
(
c
->
db
,
key
,
mstime
()
+
milliseconds
);
addReply
(
c
,
nx
?
shared
.
cone
:
shared
.
ok
);
addReply
(
c
,
ok_reply
?
ok_reply
:
shared
.
ok
);
}
}
/* SET key value [NX] [XX] [EX <seconds>] [PX <milliseconds>] */
void
setCommand
(
redisClient
*
c
)
{
void
setCommand
(
redisClient
*
c
)
{
int
j
;
robj
*
expire
=
NULL
;
int
unit
=
UNIT_SECONDS
;
int
flags
=
REDIS_SET_NO_FLAGS
;
for
(
j
=
3
;
j
<
c
->
argc
;
j
++
)
{
char
*
a
=
c
->
argv
[
j
]
->
ptr
;
robj
*
next
=
(
j
==
c
->
argc
-
1
)
?
NULL
:
c
->
argv
[
j
+
1
];
if
(
a
[
0
]
==
'n'
&&
a
[
1
]
==
'x'
&&
a
[
2
]
==
'\0'
)
{
flags
|=
REDIS_SET_NX
;
}
else
if
(
a
[
0
]
==
'x'
&&
a
[
1
]
==
'x'
&&
a
[
2
]
==
'\0'
)
{
flags
|=
REDIS_SET_XX
;
}
else
if
(
a
[
0
]
==
'e'
&&
a
[
1
]
==
'x'
&&
a
[
2
]
==
'\0'
&&
next
)
{
unit
=
UNIT_SECONDS
;
expire
=
next
;
j
++
;
}
else
if
(
a
[
0
]
==
'p'
&&
a
[
1
]
==
'x'
&&
a
[
2
]
==
'\0'
&&
next
)
{
unit
=
UNIT_MILLISECONDS
;
expire
=
next
;
j
++
;
}
else
{
addReply
(
c
,
shared
.
syntaxerr
);
return
;
}
}
c
->
argv
[
2
]
=
tryObjectEncoding
(
c
->
argv
[
2
]);
c
->
argv
[
2
]
=
tryObjectEncoding
(
c
->
argv
[
2
]);
setGenericCommand
(
c
,
0
,
c
->
argv
[
1
],
c
->
argv
[
2
],
NULL
,
0
);
setGenericCommand
(
c
,
flags
,
c
->
argv
[
1
],
c
->
argv
[
2
],
expire
,
unit
,
NULL
,
NULL
);
}
}
void
setnxCommand
(
redisClient
*
c
)
{
void
setnxCommand
(
redisClient
*
c
)
{
c
->
argv
[
2
]
=
tryObjectEncoding
(
c
->
argv
[
2
]);
c
->
argv
[
2
]
=
tryObjectEncoding
(
c
->
argv
[
2
]);
setGenericCommand
(
c
,
1
,
c
->
argv
[
1
],
c
->
argv
[
2
],
NULL
,
0
);
setGenericCommand
(
c
,
REDIS_SET_NX
,
c
->
argv
[
1
],
c
->
argv
[
2
],
NULL
,
0
,
shared
.
cone
,
shared
.
czero
);
}
}
void
setexCommand
(
redisClient
*
c
)
{
void
setexCommand
(
redisClient
*
c
)
{
c
->
argv
[
3
]
=
tryObjectEncoding
(
c
->
argv
[
3
]);
c
->
argv
[
3
]
=
tryObjectEncoding
(
c
->
argv
[
3
]);
setGenericCommand
(
c
,
0
,
c
->
argv
[
1
],
c
->
argv
[
3
],
c
->
argv
[
2
],
UNIT_SECONDS
);
setGenericCommand
(
c
,
REDIS_SET_NO_FLAGS
,
c
->
argv
[
1
],
c
->
argv
[
3
],
c
->
argv
[
2
],
UNIT_SECONDS
,
NULL
,
NULL
);
}
}
void
psetexCommand
(
redisClient
*
c
)
{
void
psetexCommand
(
redisClient
*
c
)
{
c
->
argv
[
3
]
=
tryObjectEncoding
(
c
->
argv
[
3
]);
c
->
argv
[
3
]
=
tryObjectEncoding
(
c
->
argv
[
3
]);
setGenericCommand
(
c
,
0
,
c
->
argv
[
1
],
c
->
argv
[
3
],
c
->
argv
[
2
],
UNIT_MILLISECONDS
);
setGenericCommand
(
c
,
REDIS_SET_NO_FLAGS
,
c
->
argv
[
1
],
c
->
argv
[
3
],
c
->
argv
[
2
],
UNIT_MILLISECONDS
,
NULL
,
NULL
);
}
}
int
getGenericCommand
(
redisClient
*
c
)
{
int
getGenericCommand
(
redisClient
*
c
)
{
...
...
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