void fetchNext(SpanItr &s){
		if(++s==spans.end()) {
			uint64_t nxtInterval=nextInterval(s->first, timeUnit);
			s=spans.insert(std::pair<int64_t,spanView*>(nxtInterval, new spanView(this, s->first,nxtInterval))).first;
		}
	};
	// The 'move' commands fetch spans as needed then set leftMostSpan and backLeft.
	void moveTo(uint64_t idx){
		SpanItr ret=spans.find(idx);
		if(ret!=spans.end()) leftMostSpan=ret;
		else leftMostSpan=spans.insert(std::pair<int64_t,spanView*>(idx, new spanView(this, idx, nextInterval(idx,timeUnit)))).first;
		backLeft=0;
	};
	SpanItr fetchSpan(int64_t idx){
		SpanItr ret=spans.find(idx); 
		if(ret!=spans.end()) return ret;
		spans.insert(std::pair<int64_t,spanView*>(idx, new spanView(this, idx, nextInterval(idx,timeUnit)))).first;
	};
Exemple #4
0
    // Set "toReturn" when NEED_FETCH.
    PlanStage::StageState NearStage::bufferNext(WorkingSetID* toReturn, Status* error) {

        //
        // Try to retrieve the next covered member
        //

        if (!_nextInterval) {

            StatusWith<CoveredInterval*> intervalStatus = nextInterval(_txn,
                                                                       _workingSet,
                                                                       _collection);
            if (!intervalStatus.isOK()) {
                _searchState = SearchState_Finished;
                *error = intervalStatus.getStatus();
                return PlanStage::FAILURE;
            }

            if (NULL == intervalStatus.getValue()) {
                _searchState = SearchState_Finished;
                return PlanStage::IS_EOF;
            }

            // CoveredInterval and its child stage are owned by _childrenIntervals
            _childrenIntervals.push_back(intervalStatus.getValue());
            _nextInterval = _childrenIntervals.back();
            _nextIntervalStats.reset(new IntervalStats());
            _nextIntervalStats->minDistanceAllowed = _nextInterval->minDistance;
            _nextIntervalStats->maxDistanceAllowed = _nextInterval->maxDistance;
            _nextIntervalStats->inclusiveMaxDistanceAllowed = _nextInterval->inclusiveMax;
        }

        WorkingSetID nextMemberID;
        PlanStage::StageState intervalState = _nextInterval->covering->work(&nextMemberID);

        if (PlanStage::IS_EOF == intervalState) {
            _nextInterval = NULL;
            _nextIntervalSeen.clear();

            _searchState = SearchState_Advancing;
            return PlanStage::NEED_TIME;
        }
        else if (PlanStage::FAILURE == intervalState) {
            *error = WorkingSetCommon::getMemberStatus(*_workingSet->get(nextMemberID));
            return intervalState;
        }
        else if (PlanStage::NEED_FETCH == intervalState) {
            *toReturn = nextMemberID;
            return intervalState;
        }
        else if (PlanStage::ADVANCED != intervalState) {
            return intervalState;
        }

        //
        // Try to buffer the next covered member
        //

        WorkingSetMember* nextMember = _workingSet->get(nextMemberID);

        // The child stage may not dedup so we must dedup them ourselves.
        if (_nextInterval->dedupCovering && nextMember->hasLoc()) {
            if (_nextIntervalSeen.end() != _nextIntervalSeen.find(nextMember->loc))
                return PlanStage::NEED_TIME;
        }

        ++_nextIntervalStats->numResultsFound;

        StatusWith<double> distanceStatus = computeDistance(nextMember);

        // Store the member's RecordId, if available, for quick invalidation
        if (nextMember->hasLoc()) {
            _nextIntervalSeen.insert(make_pair(nextMember->loc, nextMemberID));
        }

        if (!distanceStatus.isOK()) {
            _searchState = SearchState_Finished;
            *error = distanceStatus.getStatus();
            return PlanStage::FAILURE;
        }

        // If the member's distance is in the current distance interval, add it to our buffered
        // results.
        double memberDistance = distanceStatus.getValue();
        bool inInterval = memberDistance >= _nextInterval->minDistance
                          && (_nextInterval->inclusiveMax ?
                              memberDistance <= _nextInterval->maxDistance :
                              memberDistance < _nextInterval->maxDistance);

        // Update found distance stats
        if (_nextIntervalStats->minDistanceFound < 0
            || memberDistance < _nextIntervalStats->minDistanceFound) {
            _nextIntervalStats->minDistanceFound = memberDistance;
        }

        if (_nextIntervalStats->maxDistanceFound < 0
            || memberDistance > _nextIntervalStats->maxDistanceFound) {
            _nextIntervalStats->maxDistanceFound = memberDistance;
        }

        if (inInterval) {
            _resultBuffer.push(SearchResult(nextMemberID, memberDistance));

            ++_nextIntervalStats->numResultsBuffered;

            // Update buffered distance stats
            if (_nextIntervalStats->minDistanceBuffered < 0
                || memberDistance < _nextIntervalStats->minDistanceBuffered) {
                _nextIntervalStats->minDistanceBuffered = memberDistance;
            }

            if (_nextIntervalStats->maxDistanceBuffered < 0
                || memberDistance > _nextIntervalStats->maxDistanceBuffered) {
                _nextIntervalStats->maxDistanceBuffered = memberDistance;
            }
        }
        else {
            // We won't pass this WSM up, so deallocate it
            _workingSet->free(nextMemberID);
        }

        return PlanStage::NEED_TIME;
    }