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
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