diff --git a/src/geo.c b/src/geo.c index 63730266..ff507fe7 100644 --- a/src/geo.c +++ b/src/geo.c @@ -319,7 +319,7 @@ int membersOfGeoHashBox(robj *zobj, GeoHashBits hash, geoArray *ga, double lon, /* Search all eight neighbors + self geohash box */ int membersOfAllNeighbors(robj *zobj, GeoHashRadius n, double lon, double lat, double radius, geoArray *ga) { GeoHashBits neighbors[9]; - unsigned int i, count = 0; + unsigned int i, count = 0, last_processed = 0; neighbors[0] = n.hash; neighbors[1] = n.neighbors.north; @@ -336,7 +336,17 @@ int membersOfAllNeighbors(robj *zobj, GeoHashRadius n, double lon, double lat, d for (i = 0; i < sizeof(neighbors) / sizeof(*neighbors); i++) { if (HASHISZERO(neighbors[i])) continue; + + /* When a huge Radius (in the 5000 km range or more) is used, + * adjacent neighbors can be the same, leading to duplicated + * elements. Skip every range which is the same as the one + * processed previously. */ + if (last_processed && + neighbors[i].bits == neighbors[last_processed].bits && + neighbors[i].step == neighbors[last_processed].step) + continue; count += membersOfGeoHashBox(zobj, neighbors[i], ga, lon, lat, radius); + last_processed = i; } return count; } diff --git a/tests/unit/geo.tcl b/tests/unit/geo.tcl index 1c6b90b6..76f65b39 100644 --- a/tests/unit/geo.tcl +++ b/tests/unit/geo.tcl @@ -64,6 +64,11 @@ start_server {tags {"geo"}} { r georadius nyc -73.9798091 40.7598464 10 km COUNT 2 DESC } {{wtc one} q4} + test {GEORADIUS HUGE, issue #2767} { + r geoadd users -47.271613776683807 -54.534504198047678 user_000000 + llength [r GEORADIUS users 0 0 50000 km WITHCOORD] + } {1} + test {GEORADIUSBYMEMBER simple (sorted)} { r georadiusbymember nyc "wtc one" 7 km } {{wtc one} {union square} {central park n/q/r} 4545 {lic market}}