Skip to content

Commit 48a3d96

Browse files
committed
Add DELIFEQ command
1 parent 5d6e77f commit 48a3d96

File tree

5 files changed

+124
-0
lines changed

5 files changed

+124
-0
lines changed

src/commands.def

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10459,6 +10459,31 @@ struct COMMAND_ARG DECRBY_Args[] = {
1045910459
{MAKE_ARG("decrement",ARG_TYPE_INTEGER,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
1046010460
};
1046110461

10462+
/********** DELIFEQ ********************/
10463+
10464+
#ifndef SKIP_CMD_HISTORY_TABLE
10465+
/* DELIFEQ history */
10466+
#define DELIFEQ_History NULL
10467+
#endif
10468+
10469+
#ifndef SKIP_CMD_TIPS_TABLE
10470+
/* DELIFEQ tips */
10471+
#define DELIFEQ_Tips NULL
10472+
#endif
10473+
10474+
#ifndef SKIP_CMD_KEY_SPECS_TABLE
10475+
/* DELIFEQ key specs */
10476+
keySpec DELIFEQ_Keyspecs[1] = {
10477+
{NULL,CMD_KEY_RM|CMD_KEY_ACCESS|CMD_KEY_DELETE,KSPEC_BS_INDEX,.bs.index={1},KSPEC_FK_RANGE,.fk.range={-1,1,0}}
10478+
};
10479+
#endif
10480+
10481+
/* DELIFEQ argument table */
10482+
struct COMMAND_ARG DELIFEQ_Args[] = {
10483+
{MAKE_ARG("key",ARG_TYPE_KEY,0,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
10484+
{MAKE_ARG("value",ARG_TYPE_STRING,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
10485+
};
10486+
1046210487
/********** GET ********************/
1046310488

1046410489
#ifndef SKIP_CMD_HISTORY_TABLE
@@ -11316,6 +11341,7 @@ struct COMMAND_STRUCT serverCommandTable[] = {
1131611341
{MAKE_CMD("append","Appends a string to the value of a key. Creates the key if it doesn't exist.","O(1). The amortized time complexity is O(1) assuming the appended value is small and the already present value is of any size, since the dynamic string library used by the server will double the free space available on every reallocation.","2.0.0",CMD_DOC_NONE,NULL,NULL,"string",COMMAND_GROUP_STRING,APPEND_History,0,APPEND_Tips,0,appendCommand,3,CMD_WRITE|CMD_DENYOOM|CMD_FAST,ACL_CATEGORY_STRING,APPEND_Keyspecs,1,NULL,2),.args=APPEND_Args},
1131711342
{MAKE_CMD("decr","Decrements the integer value of a key by one. Uses 0 as initial value if the key doesn't exist.","O(1)","1.0.0",CMD_DOC_NONE,NULL,NULL,"string",COMMAND_GROUP_STRING,DECR_History,0,DECR_Tips,0,decrCommand,2,CMD_WRITE|CMD_DENYOOM|CMD_FAST,ACL_CATEGORY_STRING,DECR_Keyspecs,1,NULL,1),.args=DECR_Args},
1131811343
{MAKE_CMD("decrby","Decrements a number from the integer value of a key. Uses 0 as initial value if the key doesn't exist.","O(1)","1.0.0",CMD_DOC_NONE,NULL,NULL,"string",COMMAND_GROUP_STRING,DECRBY_History,0,DECRBY_Tips,0,decrbyCommand,3,CMD_WRITE|CMD_DENYOOM|CMD_FAST,ACL_CATEGORY_STRING,DECRBY_Keyspecs,1,NULL,2),.args=DECRBY_Args},
11344+
{MAKE_CMD("delifeq","Delete key if value matches string.","O(1)","8.2.0",CMD_DOC_NONE,NULL,NULL,"string",COMMAND_GROUP_STRING,DELIFEQ_History,0,DELIFEQ_Tips,0,delifeqCommand,3,CMD_WRITE,ACL_CATEGORY_KEYSPACE|ACL_CATEGORY_STRING,DELIFEQ_Keyspecs,1,NULL,2),.args=DELIFEQ_Args},
1131911345
{MAKE_CMD("get","Returns the string value of a key.","O(1)","1.0.0",CMD_DOC_NONE,NULL,NULL,"string",COMMAND_GROUP_STRING,GET_History,0,GET_Tips,0,getCommand,2,CMD_READONLY|CMD_FAST,ACL_CATEGORY_STRING,GET_Keyspecs,1,NULL,1),.args=GET_Args},
1132011346
{MAKE_CMD("getdel","Returns the string value of a key after deleting the key.","O(1)","6.2.0",CMD_DOC_NONE,NULL,NULL,"string",COMMAND_GROUP_STRING,GETDEL_History,0,GETDEL_Tips,0,getdelCommand,2,CMD_WRITE|CMD_FAST,ACL_CATEGORY_STRING,GETDEL_Keyspecs,1,NULL,1),.args=GETDEL_Args},
1132111347
{MAKE_CMD("getex","Returns the string value of a key after setting its expiration time.","O(1)","6.2.0",CMD_DOC_NONE,NULL,NULL,"string",COMMAND_GROUP_STRING,GETEX_History,0,GETEX_Tips,0,getexCommand,-2,CMD_WRITE|CMD_FAST,ACL_CATEGORY_STRING,GETEX_Keyspecs,1,NULL,2),.args=GETEX_Args},

src/commands/delifeq.json

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
{
2+
"DELIFEQ": {
3+
"summary": "Delete key if value matches string.",
4+
"complexity": "O(1)",
5+
"group": "string",
6+
"since": "8.2.0",
7+
"arity": 3,
8+
"function": "delifeqCommand",
9+
"command_flags": [
10+
"WRITE"
11+
],
12+
"acl_categories": [
13+
"KEYSPACE",
14+
"STRING"
15+
],
16+
"key_specs": [
17+
{
18+
"flags": [
19+
"RM",
20+
"ACCESS",
21+
"DELETE"
22+
],
23+
"begin_search": {
24+
"index": {
25+
"pos": 1
26+
}
27+
},
28+
"find_keys": {
29+
"range": {
30+
"lastkey": -1,
31+
"step": 1,
32+
"limit": 0
33+
}
34+
}
35+
}
36+
],
37+
"reply_schema": {
38+
"oneOf": [
39+
{
40+
"description": "The key was deleted.",
41+
"const": 0
42+
},
43+
{
44+
"description": "The key was not deleted.",
45+
"const": 1
46+
}
47+
]
48+
},
49+
"arguments": [
50+
{
51+
"name": "key",
52+
"type": "key",
53+
"key_spec_index": 0
54+
},
55+
{
56+
"name": "value",
57+
"type": "string"
58+
}
59+
]
60+
}
61+
}

src/server.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3608,6 +3608,7 @@ void setCommand(client *c);
36083608
void setnxCommand(client *c);
36093609
void setexCommand(client *c);
36103610
void psetexCommand(client *c);
3611+
void delifeqCommand(client *c);
36113612
void getCommand(client *c);
36123613
void getexCommand(client *c);
36133614
void getdelCommand(client *c);

src/t_string.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,27 @@ void psetexCommand(client *c) {
380380
setGenericCommand(c, OBJ_PX | OBJ_ARGV3, c->argv[1], c->argv[3], c->argv[2], UNIT_MILLISECONDS, NULL, NULL, NULL);
381381
}
382382

383+
void delifeqCommand(client *c) {
384+
robj *existing_value = lookupKeyWrite(c->db, c->argv[1]);
385+
386+
if (existing_value == NULL) {
387+
addReplyLongLong(c, 0);
388+
return;
389+
}
390+
391+
if (compareStringObjects(existing_value, c->argv[2]) != 0) {
392+
addReplyLongLong(c, 0);
393+
return;
394+
}
395+
396+
if (!dbSyncDelete(c->db, c->argv[1])) {
397+
addReplyLongLong(c, 0);
398+
return;
399+
}
400+
401+
addReplyLongLong(c, 1);
402+
}
403+
383404
int getGenericCommand(client *c) {
384405
robj *o;
385406

tests/unit/type/string.tcl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,21 @@ if {[string match {*jemalloc*} [s mem_allocator]]} {
756756
lappend res [r get bar]
757757
} {12 12}
758758

759+
test {DELIFEQ non-existing key} {
760+
r del foo
761+
assert_equal 0 [r delifeq foo "test"]
762+
}
763+
764+
test {DELIFEQ existing key, matching value} {
765+
r set foo "test"
766+
assert_equal 1 [r delifeq foo "test"]
767+
}
768+
769+
test {DELIFEQ existing key, non-matching value} {
770+
r set foo "nope"
771+
assert_equal 0 [r delifeq foo "test"]
772+
}
773+
759774
if {[string match {*jemalloc*} [s mem_allocator]]} {
760775
test {Memory usage of embedded string value} {
761776
# Check that we can fit 9 bytes of key + value into a 32 byte

0 commit comments

Comments
 (0)