From 6a8e108e2d220e95668a14db4bc891bfe1bb9743 Mon Sep 17 00:00:00 2001 From: antirez Date: Mon, 29 Jun 2015 09:34:05 +0200 Subject: [PATCH] Geo: GEOENCODE now returns score ranges. If GEOENCODE must be our door to enter the Geocoding implementation details and do fancy things client side, than return the scores as well so that we can query the sorted sets directly if we wish to do the same search multiple times, or want to compute the boxes in the client side to refine our search needs. --- src/geo.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/geo.c b/src/geo.c index f9a12bae..c2e963f6 100644 --- a/src/geo.c +++ b/src/geo.c @@ -263,12 +263,10 @@ int geoGetPointsInRange(robj *zobj, double min, double max, double lon, double l return ga->used - origincount; } -/* Obtain all members between the min/max of this geohash bounding box. - * Populate a geoArray of GeoPoints by calling geoGetPointsInRange(). - * Return the number of points added to the array. */ -int membersOfGeoHashBox(robj *zobj, GeoHashBits hash, geoArray *ga, double lon, double lat, double radius) { - GeoHashFix52Bits min, max; - +/* Compute the sorted set scores min (inclusive), max (exclusive) we should + * query in order to retrieve all the elements inside the specified area + * 'hash'. The two scores are returned by reference in *min and *max. */ +void scoresOfGeoHashBox(GeoHashBits hash, GeoHashFix52Bits *min, GeoHashFix52Bits *max) { /* We want to compute the sorted set scores that will include all the * elements inside the specified Geohash 'hash', which has as many * bits as specified by hash.step * 2. @@ -289,10 +287,18 @@ int membersOfGeoHashBox(robj *zobj, GeoHashBits hash, geoArray *ga, double lon, * and * 1010110000000000000000000000000000000000000000000000 (excluded). */ - min = geohashAlign52Bits(hash); + *min = geohashAlign52Bits(hash); hash.bits++; - max = geohashAlign52Bits(hash); + *max = geohashAlign52Bits(hash); +} +/* Obtain all members between the min/max of this geohash bounding box. + * Populate a geoArray of GeoPoints by calling geoGetPointsInRange(). + * Return the number of points added to the array. */ +int membersOfGeoHashBox(robj *zobj, GeoHashBits hash, geoArray *ga, double lon, double lat, double radius) { + GeoHashFix52Bits min, max; + + scoresOfGeoHashBox(hash,&min,&max); return geoGetPointsInRange(zobj, min, max, lon, lat, radius, ga); } @@ -621,7 +627,7 @@ void geoEncodeCommand(redisClient *c) { double lat = (area.latitude.min + area.latitude.max) / 2; /* Return four nested multibulk replies. */ - addReplyMultiBulkLen(c, 4); + addReplyMultiBulkLen(c, 5); /* Return the binary geohash we calculated as 52-bit integer */ addReplyLongLong(c, bits); @@ -640,6 +646,13 @@ void geoEncodeCommand(redisClient *c) { addReplyMultiBulkLen(c, 2); addReplyDouble(c, lon); addReplyDouble(c, lat); + + /* Return the two scores to query to get the range from the sorted set. */ + GeoHashFix52Bits min, max; + scoresOfGeoHashBox(geohash,&min,&max); + addReplyMultiBulkLen(c, 2); + addReplyDouble(c, min); + addReplyDouble(c, max); } /* GEOHASH key ele1 ele2 ... eleN