MCPcopy Create free account
hub / github.com/Snapchat/KeyDB / georadiusGeneric

Function georadiusGeneric

src/geo.cpp:516–837  ·  view source on GitHub ↗

GEORADIUS key x y radius unit [WITHDIST] [WITHHASH] [WITHCOORD] [ASC|DESC] * [COUNT count [ANY]] [STORE key] [STOREDIST key] * GEORADIUSBYMEMBER key member radius unit ... options ... * GEOSEARCH key [FROMMEMBER member] [FROMLONLAT long lat] [BYRADIUS radius unit] * [BYBOX width height unit] [WITHCOORD] [WITHDIST] [WITHASH] [COUNT count [ANY]] [ASC|D

Source from the content-addressed store, hash-verified

514 * [BYBOX width height unit] [WITHCORD] [WITHDIST] [WITHASH] [COUNT count [ANY]] [ASC|DESC] [STOREDIST]
515 * */
516void georadiusGeneric(client *c, int srcKeyIndex, int flags) {
517 robj *storekey = NULL;
518 int storedist = 0; /* 0 for STORE, 1 for STOREDIST. */
519
520 /* Look up the requested zset */
521 robj_roptr zobj = lookupKeyRead(c->db, c->argv[srcKeyIndex]);
522 if (checkType(c, zobj, OBJ_ZSET)) return;
523
524 /* Find long/lat to use for radius or box search based on inquiry type */
525 int base_args;
526 GeoShape shape = {0};
527 if (flags & RADIUS_COORDS) {
528 /* GEORADIUS or GEORADIUS_RO */
529 base_args = 6;
530 shape.type = CIRCULAR_TYPE;
531 if (extractLongLatOrReply(c, c->argv + 2, shape.xy) == C_ERR) return;
532 if (extractDistanceOrReply(c, c->argv+base_args-2, &shape.conversion, &shape.t.radius) != C_OK) return;
533 } else if ((flags & RADIUS_MEMBER) && !zobj) {
534 /* We don't have a source key, but we need to proceed with argument
535 * parsing, so we know which reply to use depending on the STORE flag. */
536 base_args = 5;
537 } else if (flags & RADIUS_MEMBER) {
538 /* GEORADIUSBYMEMBER or GEORADIUSBYMEMBER_RO */
539 base_args = 5;
540 shape.type = CIRCULAR_TYPE;
541 robj *member = c->argv[2];
542 if (longLatFromMember(zobj, member, shape.xy) == C_ERR) {
543 addReplyError(c, "could not decode requested zset member");
544 return;
545 }
546 if (extractDistanceOrReply(c, c->argv+base_args-2, &shape.conversion, &shape.t.radius) != C_OK) return;
547 } else if (flags & GEOSEARCH) {
548 /* GEOSEARCH or GEOSEARCHSTORE */
549 base_args = 2;
550 if (flags & GEOSEARCHSTORE) {
551 base_args = 3;
552 storekey = c->argv[1];
553 }
554 } else {
555 addReplyError(c, "Unknown georadius search type");
556 return;
557 }
558
559 /* Discover and populate all optional parameters. */
560 int withdist = 0, withhash = 0, withcoords = 0;
561 int frommember = 0, fromloc = 0, byradius = 0, bybox = 0;
562 int sort = SORT_NONE;
563 int any = 0; /* any=1 means a limited search, stop as soon as enough results were found. */
564 long long count = 0; /* Max number of results to return. 0 means unlimited. */
565 if (c->argc > base_args) {
566 int remaining = c->argc - base_args;
567 for (int i = 0; i < remaining; i++) {
568 char *arg = szFromObj(c->argv[base_args + i]);
569 if (!strcasecmp(arg, "withdist")) {
570 withdist = 1;
571 } else if (!strcasecmp(arg, "withhash")) {
572 withhash = 1;
573 } else if (!strcasecmp(arg, "withcoord")) {

Callers 6

georadiusCommandFunction · 0.85
georadiusbymemberCommandFunction · 0.85
georadiusroCommandFunction · 0.85
geosearchCommandFunction · 0.85
geosearchstoreCommandFunction · 0.85

Calls 15

lookupKeyReadFunction · 0.85
checkTypeFunction · 0.85
extractLongLatOrReplyFunction · 0.85
extractDistanceOrReplyFunction · 0.85
longLatFromMemberFunction · 0.85
addReplyErrorFunction · 0.85
szFromObjFunction · 0.85
extractBoxOrReplyFunction · 0.85
addReplyErrorObjectFunction · 0.85
addReplyErrorFormatFunction · 0.85
dbDeleteFunction · 0.85

Tested by

no test coverage detected