bool S2NearCursor::ok() { if (_numToReturn <= 0) { return false; } if (_innerRadius > _maxDistance) { return false; } if (_results.empty()) { fillResults(); } // If fillResults can't find anything, we're outta results. return !_results.empty(); }
bool S2NearCursor::advance() { if (_numToReturn <= 0) { LOG(2) << "advancing but no more to return" << endl; return false; } if (_innerRadius > _maxDistance) { LOG(2) << "advancing but exhausted search distance" << endl; return false; } if (!_results.empty()) { _returned.insert(_results.top().loc); _results.pop(); --_numToReturn; // Safe to grow the radius as we've returned everything in our shell. We don't do this // check outside of !_results.empty() because we could have results, yield, dump them // (_results would be empty), then need to recreate them w/the same radii. In that case // we'd grow when we shouldn't. if (_results.empty()) { nextAnnulus(); } } if (_results.empty()) { fillResults(); } // The only reason _results should be empty now is if there are no more possible results. return !_results.empty(); }
// Called when we're un-yielding. // Note that this is (apparently) a valid call sequence: // 1. noteLocation() // 2. ok() // 3. checkLocation() // As such we might have results and only want to fill the result queue if it's empty. void S2NearCursor::checkLocation() { LOG(1) << "unyielding, have " << _results.size() << " results in queue"; if (_results.empty()) { LOG(1) << ", filling..." << endl; fillResults(); LOG(1) << "now have " << _results.size() << " results in queue"; } LOG(1) << endl; }
void S2NearIndexCursor::seek(const BSONObj& query, const NearQuery& nearQuery, const vector<GeoQuery>& regions) { _indexedGeoFields = regions; _nearQuery = nearQuery; _returnedDistance = 0; _nearFieldIndex = 0; _stats = Stats(); _returned = unordered_set<DiskLoc, DiskLoc::Hasher>(); _results = priority_queue<Result>(); BSONObjBuilder geoFieldsToNuke; for (size_t i = 0; i < _indexedGeoFields.size(); ++i) { geoFieldsToNuke.append(_indexedGeoFields[i].getField(), ""); } // false means we want to filter OUT geoFieldsToNuke, not filter to include only that. _filteredQuery = query.filterFieldsUndotted(geoFieldsToNuke.obj(), false); // More indexing machinery. BSONObjBuilder specBuilder; BSONObjIterator specIt(_descriptor->keyPattern()); while (specIt.more()) { BSONElement e = specIt.next(); // Checked in AccessMethod already, so we know this spec has only numbers and 2dsphere if ( e.type() == String ) { specBuilder.append( e.fieldName(), 1 ); } else { specBuilder.append( e.fieldName(), e.numberInt() ); } } _specForFRV = specBuilder.obj(); specIt = BSONObjIterator(_descriptor->keyPattern()); while (specIt.more()) { if (specIt.next().fieldName() == _nearQuery.field) { break; } ++_nearFieldIndex; } _minDistance = max(0.0, _nearQuery.minDistance); // _outerRadius can't be greater than (pi * r) or we wrap around the opposite // side of the world. _maxDistance = min(M_PI * _params.radius, _nearQuery.maxDistance); uassert(16892, "$minDistance too large", _minDistance < _maxDistance); // Start with a conservative _radiusIncrement. _radiusIncrement = 5 * S2::kAvgEdge.GetValue(_params.finestIndexedLevel) * _params.radius; _innerRadius = _outerRadius = _minDistance; // We might want to adjust the sizes of our coverings if our search // isn't local to the start point. // Set up _outerRadius with proper checks (maybe maxDistance is really small?) nextAnnulus(); fillResults(); }
bool S2NearCursor::ok() { if (_innerRadius > _maxDistance) { LOG(1) << "not OK, exhausted search bounds" << endl; return false; } if (_results.empty()) { LOG(1) << "results empty in OK, filling" << endl; fillResults(); } // If fillResults can't find anything, we're outta results. return !_results.empty(); }
void S2NearIndexCursor::next() { if (_innerRadius > _maxDistance) { LOG(2) << "advancing but exhausted search distance" << endl; } if (!_results.empty()) { _returnedDistance = _results.top().distance; _returned.insert(_results.top().loc); _results.pop(); ++_stats._numReturned; // Safe to grow the radius as we've returned everything in our shell. We don't do this // check outside of !_results.empty() because we could have results, yield, dump them // (_results would be empty), then need to recreate them w/the same radii. In that case // we'd grow when we shouldn't. if (_results.empty()) { nextAnnulus(); } } if (_results.empty()) { fillResults(); } }
bool S2NearCursor::advance() { if (_numToReturn <= 0) { return false; } if (_innerRadius > _maxDistance) { return false; } if (!_results.empty()) { _returned.insert(_results.top().loc); _results.pop(); --_numToReturn; ++_nscanned; // Safe to grow the radius as we've returned everything in our shell. We don't do this // check outside of !_results.empty() because we could have results, yield, dump them // (_results would be empty), then need to recreate them w/the same radii. In that case // we'd grow when we shouldn't. if (_results.empty()) { nextAnnulus(); } } if (_results.empty()) { fillResults(); } // The only reason this should be empty is if there are no more results to be had. return !_results.empty(); }
Status S2NearIndexCursor::restorePosition() { if (_results.empty()) { fillResults(); } return Status::OK(); }
// Called when we're un-yielding. void S2NearCursor::checkLocation() { fillResults(); }