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; };
// 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; }