summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSalvatore Sanfilippo <antirez@gmail.com>2020-03-23 11:23:21 +0100
committerGitHub <noreply@github.com>2020-03-23 11:23:21 +0100
commit493a7f9823dae5303208be2de778942815df24ba (patch)
tree9bd292a844a24440be0b281df350ef2872445c35
parent19f5be231d5b745f84f562d40b5e5c5aa1939393 (diff)
parent94376f46adc693ebac1f54b313527a1bac46e6e1 (diff)
downloadredis-493a7f9823dae5303208be2de778942815df24ba.tar.gz
Merge pull request #6951 from yangbodong22011/feature-bitfield-ro
Added BITFIELD_RO variants for read-only operations.
-rw-r--r--src/bitops.c19
-rw-r--r--src/server.c4
-rw-r--r--src/server.h1
-rw-r--r--tests/unit/bitfield.tcl31
4 files changed, 54 insertions, 1 deletions
diff --git a/src/bitops.c b/src/bitops.c
index ee1ce0460..ffb330013 100644
--- a/src/bitops.c
+++ b/src/bitops.c
@@ -902,6 +902,9 @@ void bitposCommand(client *c) {
* OVERFLOW [WRAP|SAT|FAIL]
*/
+#define BITFIELD_COMMON (1<<0)
+#define BITFIELD_READONLY (1<<1)
+
struct bitfieldOp {
uint64_t offset; /* Bitfield offset. */
int64_t i64; /* Increment amount (INCRBY) or SET value */
@@ -911,7 +914,7 @@ struct bitfieldOp {
int sign; /* True if signed, otherwise unsigned op. */
};
-void bitfieldCommand(client *c) {
+void bitfieldGeneric(client *c, int flags) {
robj *o;
size_t bitoffset;
int j, numops = 0, changes = 0;
@@ -999,6 +1002,12 @@ void bitfieldCommand(client *c) {
return;
}
} else {
+ if (flags & BITFIELD_READONLY) {
+ zfree(ops);
+ addReplyError(c, "bitfield_ro only support get subcommand");
+ return;
+ }
+
/* Lookup by making room up to the farest bit reached by
* this operation. */
if ((o = lookupStringForBitCommand(c,
@@ -1129,3 +1138,11 @@ void bitfieldCommand(client *c) {
}
zfree(ops);
}
+
+void bitfieldCommand(client *c) {
+ bitfieldGeneric(c, BITFIELD_COMMON);
+}
+
+void bitfieldroCommand(client *c) {
+ bitfieldGeneric(c, BITFIELD_READONLY);
+}
diff --git a/src/server.c b/src/server.c
index 4b010b870..f5fb339f9 100644
--- a/src/server.c
+++ b/src/server.c
@@ -238,6 +238,10 @@ struct redisCommand redisCommandTable[] = {
"write use-memory @bitmap",
0,NULL,1,1,1,0,0,0},
+ {"bitfield_ro",bitfieldroCommand,-2,
+ "read-only fast @bitmap",
+ 0,NULL,1,1,1,0,0,0},
+
{"setrange",setrangeCommand,4,
"write use-memory @string",
0,NULL,1,1,1,0,0,0},
diff --git a/src/server.h b/src/server.h
index fdfe5b8ea..ed4707d66 100644
--- a/src/server.h
+++ b/src/server.h
@@ -2177,6 +2177,7 @@ void existsCommand(client *c);
void setbitCommand(client *c);
void getbitCommand(client *c);
void bitfieldCommand(client *c);
+void bitfieldroCommand(client *c);
void setrangeCommand(client *c);
void getrangeCommand(client *c);
void incrCommand(client *c);
diff --git a/tests/unit/bitfield.tcl b/tests/unit/bitfield.tcl
index d76452b1b..819d8f36d 100644
--- a/tests/unit/bitfield.tcl
+++ b/tests/unit/bitfield.tcl
@@ -199,3 +199,34 @@ start_server {tags {"bitops"}} {
r del mystring
}
}
+
+start_server {tags {"repl"}} {
+ start_server {} {
+ set master [srv -1 client]
+ set master_host [srv -1 host]
+ set master_port [srv -1 port]
+ set slave [srv 0 client]
+
+ test {setup slave} {
+ $slave slaveof $master_host $master_port
+ wait_for_condition 50 100 {
+ [s 0 master_link_status] eq {up}
+ } else {
+ fail "Replication not started."
+ }
+ }
+
+ test {write on master, read on slave} {
+ $master del bits
+ assert_equal 0 [$master bitfield bits set u8 0 255]
+ assert_equal 255 [$master bitfield bits set u8 0 100]
+ wait_for_ofs_sync $master $slave
+ assert_equal 100 [$slave bitfield_ro bits get u8 0]
+ }
+
+ test {bitfield_ro with write option} {
+ catch {$slave bitfield_ro bits set u8 0 100 get u8 0} err
+ assert_match {*ERR bitfield_ro only support get subcommand*} $err
+ }
+ }
+}