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

Function geoGetPointsInRange

src/geo.cpp:255–316  ·  view source on GitHub ↗

Query a Redis sorted set to extract all the elements between 'min' and * 'max', appending them into the array of geoPoint structures 'gparray'. * The command returns the number of elements added to the array. * * Elements which are farest than 'radius' from the specified 'x' and 'y' * coordinates are not included. * * The ability of this function to append to an existing set of points is *

Source from the content-addressed store, hash-verified

253 * via qsort. Similarly we need to be able to reject points outside the search
254 * radius area ASAP in order to allocate and process more points than needed. */
255int geoGetPointsInRange(robj_roptr zobj, double min, double max, GeoShape *shape, geoArray *ga, unsigned long limit) {
256 /* minex 0 = include min in range; maxex 1 = exclude max in range */
257 /* That's: min <= val < max */
258 zrangespec range = { min, max, 0, 1 };
259 size_t origincount = ga->used;
260 sds member;
261
262 if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
263 unsigned char *zl = (unsigned char*)zobj->m_ptr;
264 unsigned char *eptr, *sptr;
265 unsigned char *vstr = NULL;
266 unsigned int vlen = 0;
267 long long vlong = 0;
268 double score = 0;
269
270 if ((eptr = zzlFirstInRange(zl, &range)) == NULL) {
271 /* Nothing exists starting at our min. No results. */
272 return 0;
273 }
274
275 sptr = ziplistNext(zl, eptr);
276 while (eptr) {
277 score = zzlGetScore(sptr);
278
279 /* If we fell out of range, break. */
280 if (!zslValueLteMax(score, &range))
281 break;
282
283 /* We know the element exists. ziplistGet should always succeed */
284 ziplistGet(eptr, &vstr, &vlen, &vlong);
285 member = (vstr == NULL) ? sdsfromlonglong(vlong) :
286 sdsnewlen(vstr,vlen);
287 if (geoAppendIfWithinShape(ga,shape,score,member)
288 == C_ERR) sdsfree(member);
289 if (ga->used && limit && ga->used >= limit) break;
290 zzlNext(zl, &eptr, &sptr);
291 }
292 } else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) {
293 zset *zs = (zset*)zobj->m_ptr;
294 zskiplist *zsl = zs->zsl;
295 zskiplistNode *ln;
296
297 if ((ln = zslFirstInRange(zsl, &range)) == NULL) {
298 /* Nothing exists starting at our min. No results. */
299 return 0;
300 }
301
302 while (ln) {
303 sds ele = ln->ele;
304 /* Abort when the node is no longer in range. */
305 if (!zslValueLteMax(ln->score, &range))
306 break;
307
308 ele = sdsdup(ele);
309 if (geoAppendIfWithinShape(ga,shape,ln->score,ele)
310 == C_ERR) sdsfree(ele);
311 if (ga->used && limit && ga->used >= limit) break;
312 ln = ln->level(0)->forward;

Callers 1

membersOfGeoHashBoxFunction · 0.85

Calls 13

zzlFirstInRangeFunction · 0.85
ziplistNextFunction · 0.85
zzlGetScoreFunction · 0.85
zslValueLteMaxFunction · 0.85
ziplistGetFunction · 0.85
sdsfromlonglongFunction · 0.85
sdsnewlenFunction · 0.85
geoAppendIfWithinShapeFunction · 0.85
sdsfreeFunction · 0.85
zzlNextFunction · 0.85
zslFirstInRangeFunction · 0.85
sdsdupFunction · 0.85

Tested by

no test coverage detected