Esempio n. 1
0
 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();
 }
Esempio n. 2
0
    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();
    }
Esempio n. 3
0
 // 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;
 }
Esempio n. 4
0
    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();
    }
Esempio n. 5
0
 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();
 }
Esempio n. 6
0
    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(); }
    }
Esempio n. 7
0
    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();
    }
Esempio n. 8
0
Status S2NearIndexCursor::restorePosition() {
    if (_results.empty()) {
        fillResults();
    }
    return Status::OK();
}
Esempio n. 9
0
 // Called when we're un-yielding.
 void S2NearCursor::checkLocation() { fillResults(); }