summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbodong.ybd <bodong.ybd@alibaba-inc.com>2020-03-04 20:51:45 +0800
committerbodong.ybd <bodong.ybd@alibaba-inc.com>2020-03-04 20:51:45 +0800
commit94376f46adc693ebac1f54b313527a1bac46e6e1 (patch)
treef9b478eb1bdad77f452f79a0f12de191b5fed580
parentf88f8661ac29c054cffb795e6c371fbb2240aa0e (diff)
downloadredis-94376f46adc693ebac1f54b313527a1bac46e6e1.tar.gz
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 bb8b3b103..ab2afd47f 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 87c293c26..e5043855c 100644
--- a/src/server.h
+++ b/src/server.h
@@ -2171,6 +2171,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
+ }
+ }
+}