summaryrefslogtreecommitdiff
path: root/src/geo.c
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2017-06-30 10:03:37 +0200
committerantirez <antirez@gmail.com>2017-06-30 10:03:37 +0200
commitf8547e53f0d80b4cd2a84c6d39d1e08a470f0a2c (patch)
treec14df596320f8c69f894f365d8f141dfa559534d /src/geo.c
parent01a4b9892d0922eeafbb1bfba0f9fa70bf1a2f3b (diff)
downloadredis-f8547e53f0d80b4cd2a84c6d39d1e08a470f0a2c.tar.gz
Added GEORADIUS(BYMEMBER)_RO variants for read-only operations.
Issue #4084 shows how for a design error, GEORADIUS is a write command because of the STORE option. Because of this it does not work on readonly slaves, gets redirected to masters in Redis Cluster even when the connection is in READONLY mode and so forth. To break backward compatibility at this stage, with Redis 4.0 to be in advanced RC state, is problematic for the user base. The API can be fixed into the unstable branch soon if we'll decide to do so in order to be more consistent, and reease Redis 5.0 with this incompatibility in the future. This is still unclear. However, the ability to scale GEO queries in slaves easily is too important so this commit adds two read-only variants to the GEORADIUS and GEORADIUSBYMEMBER command: GEORADIUS_RO and GEORADIUSBYMEMBER_RO. The commands are exactly as the original commands, but they do not accept the STORE and STOREDIST options.
Diffstat (limited to 'src/geo.c')
-rw-r--r--src/geo.c35
1 files changed, 26 insertions, 9 deletions
diff --git a/src/geo.c b/src/geo.c
index 8423931af..90216e7dd 100644
--- a/src/geo.c
+++ b/src/geo.c
@@ -452,13 +452,14 @@ void geoaddCommand(client *c) {
#define SORT_ASC 1
#define SORT_DESC 2
-#define RADIUS_COORDS 1
-#define RADIUS_MEMBER 2
+#define RADIUS_COORDS (1<<0) /* Search around coordinates. */
+#define RADIUS_MEMBER (1<<1) /* Search around member. */
+#define RADIUS_NOSTORE (1<<2) /* Do not acceot STORE/STOREDIST option. */
/* GEORADIUS key x y radius unit [WITHDIST] [WITHHASH] [WITHCOORD] [ASC|DESC]
* [COUNT count] [STORE key] [STOREDIST key]
* GEORADIUSBYMEMBER key member radius unit ... options ... */
-void georadiusGeneric(client *c, int type) {
+void georadiusGeneric(client *c, int flags) {
robj *key = c->argv[1];
robj *storekey = NULL;
int storedist = 0; /* 0 for STORE, 1 for STOREDIST. */
@@ -473,11 +474,11 @@ void georadiusGeneric(client *c, int type) {
/* Find long/lat to use for radius search based on inquiry type */
int base_args;
double xy[2] = { 0 };
- if (type == RADIUS_COORDS) {
+ if (flags & RADIUS_COORDS) {
base_args = 6;
if (extractLongLatOrReply(c, c->argv + 2, xy) == C_ERR)
return;
- } else if (type == RADIUS_MEMBER) {
+ } else if (flags & RADIUS_MEMBER) {
base_args = 5;
robj *member = c->argv[2];
if (longLatFromMember(zobj, member, xy) == C_ERR) {
@@ -485,7 +486,7 @@ void georadiusGeneric(client *c, int type) {
return;
}
} else {
- addReplyError(c, "unknown georadius search type");
+ addReplyError(c, "Unknown georadius search type");
return;
}
@@ -522,11 +523,17 @@ void georadiusGeneric(client *c, int type) {
return;
}
i++;
- } else if (!strcasecmp(arg, "store") && (i+1) < remaining) {
+ } else if (!strcasecmp(arg, "store") &&
+ (i+1) < remaining &&
+ !(flags & RADIUS_NOSTORE))
+ {
storekey = c->argv[base_args+i+1];
storedist = 0;
i++;
- } else if (!strcasecmp(arg, "storedist") && (i+1) < remaining) {
+ } else if (!strcasecmp(arg, "storedist") &&
+ (i+1) < remaining &&
+ !(flags & RADIUS_NOSTORE))
+ {
storekey = c->argv[base_args+i+1];
storedist = 1;
i++;
@@ -671,10 +678,20 @@ void georadiusCommand(client *c) {
}
/* GEORADIUSBYMEMBER wrapper function. */
-void georadiusByMemberCommand(client *c) {
+void georadiusbymemberCommand(client *c) {
georadiusGeneric(c, RADIUS_MEMBER);
}
+/* GEORADIUS_RO wrapper function. */
+void georadiusroCommand(client *c) {
+ georadiusGeneric(c, RADIUS_COORDS|RADIUS_NOSTORE);
+}
+
+/* GEORADIUSBYMEMBER_RO wrapper function. */
+void georadiusbymemberroCommand(client *c) {
+ georadiusGeneric(c, RADIUS_MEMBER|RADIUS_NOSTORE);
+}
+
/* GEOHASH key ele1 ele2 ... eleN
*
* Returns an array with an 11 characters geohash representation of the