PlanStage::StageState Count::work(WorkingSetID* out) { if (NULL == _btreeCursor.get()) { // First call to work(). Perform cursor init. initIndexCursor(); checkEnd(); return PlanStage::NEED_TIME; } if (isEOF()) { return PlanStage::IS_EOF; } DiskLoc loc = _btreeCursor->getValue(); _btreeCursor->next(); checkEnd(); if (_shouldDedup) { if (_returned.end() != _returned.find(loc)) { return PlanStage::NEED_TIME; } else { _returned.insert(loc); } } *out = WorkingSet::INVALID_ID; return PlanStage::ADVANCED; }
PlanStage::StageState IndexScan::work(WorkingSetID* out) { if (NULL == _indexCursor.get()) { // First call to work(). Perform cursor init. CursorOptions cursorOptions; // The limit is *required* for 2d $near, which is the only index that pays attention to // it anyway. cursorOptions.numWanted = _numWanted; if (1 == _direction) { cursorOptions.direction = CursorOptions::INCREASING; } else { cursorOptions.direction = CursorOptions::DECREASING; } IndexCursor *cursor; _iam->newCursor(&cursor); _indexCursor.reset(cursor); _indexCursor->setOptions(cursorOptions); _indexCursor->seek(_startKey); checkEnd(); } else if (_yieldMovedCursor) { _yieldMovedCursor = false; // Note that we're not calling next() here. } else { _indexCursor->next(); checkEnd(); } if (isEOF()) { return PlanStage::IS_EOF; } DiskLoc loc = _indexCursor->getValue(); if (_shouldDedup) { if (_returned.end() != _returned.find(loc)) { return PlanStage::NEED_TIME; } else { _returned.insert(loc); } } WorkingSetID id = _workingSet->allocate(); WorkingSetMember* member = _workingSet->get(id); member->loc = loc; member->keyData.push_back(IndexKeyDatum(_descriptor->keyPattern(), _indexCursor->getKey().getOwned())); member->state = WorkingSetMember::LOC_AND_IDX; if (NULL == _matcher || _matcher->matches(member)) { *out = id; return PlanStage::ADVANCED; } _workingSet->free(id); return PlanStage::NEED_TIME; }
void FileHeaderParser::parse(std::string data) { storedData += data; if (storedData.find("\r\n\r\n") != 0) { headerPassed = true; total += storedData.length() - storedData.find("\r\n\r\n") - 4; std::istringstream iss(storedData, std::istringstream::in); while(!iss.eof()) { std::string line; std::getline(iss, line); if (line == "\r") break; line[line.length()-1] = 0; Logger::instance().log("FileHeaderParser: ["+line+"]", DEBUG); //std::cout << "Line: [" << line << "]" << std::endl; if (line.find("Content-Length:") == 0) { std::vector<std::string> parts; split(line, parts, ':', 2); lengthRecieved = true; contentLength = valueOfString<int>(parts[1]); Logger::instance().log("GOT Content-Length: "+stringOf(contentLength), DEBUG); } } checkEnd(); } }
void Count::initIndexCursor() { CursorOptions cursorOptions; cursorOptions.direction = CursorOptions::INCREASING; IndexCursor *cursor; Status s = _iam->newCursor(&cursor); verify(s.isOK()); verify(cursor); // Is this assumption always valid? See SERVER-12397 _btreeCursor.reset(static_cast<BtreeIndexCursor*>(cursor)); _btreeCursor->setOptions(cursorOptions); // _btreeCursor points at our start position. We move it forward until it hits a cursor // that points at the end. _btreeCursor->seek(_params.startKey, !_params.startKeyInclusive); // Create the cursor that points at our end position. IndexCursor* endCursor; verify(_iam->newCursor(&endCursor).isOK()); verify(endCursor); // Is this assumption always valid? See SERVER-12397 _endCursor.reset(static_cast<BtreeIndexCursor*>(endCursor)); _endCursor->setOptions(cursorOptions); // If the end key is inclusive we want to point *past* it since that's the end. _endCursor->seek(_params.endKey, _params.endKeyInclusive); // See if we've hit the end already. checkEnd(); }
// Check the current key with respect to our key bounds, whether // it be provided by independent field ranges or by start/end keys. bool IndexCursor::checkCurrentAgainstBounds() { if ( _bounds == NULL ) { checkEnd(); if ( ok() ) { ++_nscanned; } } else { // If nscanned is increased by more than 20 before a matching key is found, abort // skipping through the index to find a matching key. This iteration cutoff // prevents unbounded internal iteration within IndexCursor::initializeDBC and // IndexCursor::advance(). See SERVER-3448. const long long startNscanned = _nscanned; if ( skipOutOfRangeKeysAndCheckEnd() ) { do { if ( _nscanned > startNscanned + 20 ) { // If iteration is aborted before a key matching _bounds is identified, the // cursor may be left pointing at a key that is not within bounds // (_bounds->matchesKey( currKey() ) may be false). Set _boundsMustMatch to // false accordingly. _boundsMustMatch = false; break; } } while ( skipOutOfRangeKeysAndCheckEnd() ); } } return ok(); }
BtreeCursor::BtreeCursor( const IndexDetails &_id, const BSONObj &_startKey, const BSONObj &_endKey, int _direction ) : startKey( _startKey ), endKey( _endKey ), indexDetails( _id ), order( _id.keyPattern() ), direction( _direction ) { bool found; if ( otherTraceLevel >= 12 ) { if ( otherTraceLevel >= 200 ) { out() << "::BtreeCursor() qtl>200. validating entire index." << endl; indexDetails.head.btree()->fullValidate(indexDetails.head, order); } else { out() << "BTreeCursor(). dumping head bucket" << endl; indexDetails.head.btree()->dump(); } } bucket = indexDetails.head.btree()-> locate(indexDetails, indexDetails.head, startKey, order, keyOfs, found, direction > 0 ? minDiskLoc : maxDiskLoc, direction); skipUnusedKeys(); checkEnd(); }
void IndexScan::recoverFromYield() { ++_commonStats.unyields; if (isEOF() || (NULL == _indexCursor.get())) { return; } // We can have a valid position before we check isEOF(), restore the position, and then be // EOF upon restore. if (!_indexCursor->restorePosition().isOK() || _indexCursor->isEOF()) { _hitEnd = true; return; } if (!_savedKey.binaryEqual(_indexCursor->getKey()) || _savedLoc != _indexCursor->getValue()) { // Our restored position isn't the same as the saved position. When we call work() // again we want to return where we currently point, not past it. _yieldMovedCursor = true; ++_specificStats.yieldMovedCursor; // Our restored position might be past endKey, see if we've hit the end. checkEnd(); } }
void Board::takeStep(){ checkTurn(); vec step = inputVec(); if(step == vec(-1, -1)){ fprintf(stderr, "no input vector!\n"); step = inputVec(); } while(!canFlip(step.x, step.y, turnToPieceType(turn))){ fprintf(stderr, "invalid input (%d, %d)!\n", step.x, step.y); step = inputVec(); } setPieces(step.x, step.y); if(checkEnd()){ if(countColor(black) > countColor(white)){ printf("black: %d\n", countColor(black)); printf("white: %d\n", countColor(white)); printf("black wins!\n"); } else if(countColor(black) < countColor(white)){ printf("black: %d\n", countColor(black)); printf("white: %d\n", countColor(white)); printf("white wins!\n"); } else{ printf("black: %d\n", countColor(black)); printf("white: %d\n", countColor(white)); printf("ties!\n"); } printBoard(); exit(0); } else{ printBoard(); } }
void FileHeaderParser::feed(char *data, int len) { if (headerPassed) { total += len; checkEnd(); } else parse(std::string(data, data+len)); }
bool BtreeCursor::advance() { checkForInterrupt(); if ( bucket.isNull() ) return false; bucket = bucket.btree()->advance(bucket, keyOfs, direction, "BtreeCursor::advance"); skipUnusedKeys(); checkEnd(); return !bucket.isNull(); }
void BtreeCursor::init() { bool found; bucket = indexDetails.head.btree()-> locate(indexDetails, indexDetails.head, startKey, order, keyOfs, found, direction > 0 ? minDiskLoc : maxDiskLoc, direction); skipUnusedKeys(); checkEnd(); }
void BtreeCursor::init() { if ( _spec.getType() ){ startKey = _spec.getType()->fixKey( startKey ); endKey = _spec.getType()->fixKey( endKey ); } bool found; bucket = indexDetails.head.btree()-> locate(indexDetails, indexDetails.head, startKey, _ordering, keyOfs, found, direction > 0 ? minDiskLoc : maxDiskLoc, direction); skipUnusedKeys( false ); checkEnd(); }
PlanStage::StageState DistinctScan::work(WorkingSetID* out) { ++_commonStats.works; if (NULL == _btreeCursor.get()) { // First call to work(). Perform cursor init. initIndexCursor(); checkEnd(); } if (isEOF()) { return PlanStage::IS_EOF; } // Grab the next (key, value) from the index. BSONObj ownedKeyObj = _btreeCursor->getKey().getOwned(); DiskLoc loc = _btreeCursor->getValue(); // The underlying IndexCursor points at the *next* thing we want to return. We do this so // that if we're scanning an index looking for docs to delete we don't continually clobber // the thing we're pointing at. // We skip to the next value of the _params.fieldNo-th field in the index key pattern. // This is the field we're distinct-ing over. _btreeCursor->skip(_btreeCursor->getKey(), _params.fieldNo + 1, true, _keyElts, _keyEltsInc); // And make sure we're within the bounds. checkEnd(); // Package up the result for the caller. WorkingSetID id = _workingSet->allocate(); WorkingSetMember* member = _workingSet->get(id); member->loc = loc; member->keyData.push_back(IndexKeyDatum(_descriptor->keyPattern(), ownedKeyObj)); member->state = WorkingSetMember::LOC_AND_IDX; *out = id; ++_commonStats.advanced; return PlanStage::ADVANCED; }
void BtreeCursor::init() { if ( _spec.getType() ) { startKey = _spec.getType()->fixKey( startKey ); endKey = _spec.getType()->fixKey( endKey ); } bucket = _locate(startKey, _direction > 0 ? minDiskLoc : maxDiskLoc); if ( ok() ) { _nscanned = 1; } skipUnusedKeys(); checkEnd(); }
void BtreeCursor::initWithoutIndependentFieldRanges() { if ( indexDetails.getSpec().getType() ) { startKey = indexDetails.getSpec().getType()->fixKey( startKey ); endKey = indexDetails.getSpec().getType()->fixKey( endKey ); } bucket = _locate(startKey, _direction > 0 ? minDiskLoc : maxDiskLoc); if ( ok() ) { _nscanned = 1; } skipUnusedKeys(); checkEnd(); }
void Piece::playPiece(){ auto par = dynamic_cast<HorseshoeMain*>(this->getParent()); if(par->isConnected(position)){ auto ai = par->getAI(); bool p = UserDefault::getInstance()->getBoolForKey("Player"); auto audio = CocosDenshion::SimpleAudioEngine::getInstance(); if(UserDefault::getInstance()->getBoolForKey("Sound",true)) audio->playEffect("sfx/Move.wav"); Size visibleSize = Director::getInstance()->getVisibleSize(); Vec2 origin = Director::getInstance()->getVisibleOrigin(); int x = par->empty; par->empty = position; position = x; Vec2 np; switch(position){ case 1: np = Vec2(origin.x + visibleSize.width/2 - 180, origin.y + 2*visibleSize.height/5 + 180); break; case 2: np = Vec2(origin.x + visibleSize.width/2 + 180, origin.y + 2*visibleSize.height/5 + 180); break; case 3: np = Vec2(origin.x + visibleSize.width/2, origin.y + 2*visibleSize.height/5); break; case 4: np = Vec2(origin.x + visibleSize.width/2 - 180, origin.y + 2*visibleSize.height/5 - 180); break; case 5: np = Vec2(origin.x + visibleSize.width/2 + 180, origin.y + 2*visibleSize.height/5 - 180); break; } auto move = MoveTo::create(0.4f, np); auto scaleup = ScaleTo::create(0.2f,1.4f); auto scaledown = ScaleTo::create(0.2f,1); auto scale = Sequence::createWithTwoActions(scaleup,scaledown); auto act = Spawn::createWithTwoActions(scale,move); this->runAction(act); CCLOG("%d to %d", par->empty, position); turn=!turn; if(par->checkEnd(turn)){ ended = true; par->setBGColor(Color3B(57,120,63)); if(UserDefault::getInstance()->getBoolForKey("Sound",true)){ if(ai&&turn!=p) audio->playEffect("sfx/Win.wav"); else audio->playEffect("sfx/Lose.wav"); } } else if(!turn) par->setBGColor(Color3B(156,48,47)); else par->setBGColor(Color3B(56,92,120)); if(ai&&turn!=p) par->playAI(); } }
void PIDThread::run() { while(1) { usleep(10000); // 10 ms error_last_time = error_this_time; error_this_time = targetPosition - currentPosition; error_integral += error_this_time; double speed = calculateSpeed(); if (checkEnd(speed)) this->terminate(); emit updatePosition(RND((currentPosition + speed) * 10)); } }
bool BtreeCursor::advance() { checkForInterrupt(); if ( bucket.isNull() ) return false; bucket = bucket.btree()->advance(bucket, keyOfs, direction, "BtreeCursor::advance"); skipUnusedKeys(); checkEnd(); while( !ok() && ++boundIndex_ < bounds_.size() ) { startKey = bounds_[ boundIndex_ ].first; endKey = bounds_[ boundIndex_ ].second; init(); } return !bucket.isNull(); }
void Battleship::gameLoop() { bool end = false; while (!end) { // Ask user for co-ordinates int x, y; cout << endl << "Choose your co-ordinates in the " << GRID_SIZE << "x" << GRID_SIZE << " grid:" << endl; cout << "Your x co-ord: "; cin >> x; cout << "Your y co-ord: "; cin >> y; // Validate data inputted by user if (x < 1 || x > GRID_SIZE || y < 1 || y > GRID_SIZE) { cout << "You chose co-ordinates outside of the battleground!" << endl; cout << "Try again..." << endl; } else { if (battleground[y - 1][x - 1]) { // HIT if (player_battleground[y - 1][x - 1] == TileType::NONE) { incrementScore(); player_battleground[y - 1][x - 1] = TileType::HIT; cout << endl << "HIT!" << endl; } else { cout << "You have already shot at this co-ordinate!" << endl; } } else { // MISS if (player_battleground[y - 1][x - 1] == TileType::NONE){ loseLife(); player_battleground[y - 1][x - 1] = TileType::MISS; cout << endl << "MISS!" << endl; } else { cout << "You have already shot at this co-ordinate!" << endl; } } printPlayerBattleground(); end = checkEnd(); } } }
PlanStage::StageState Count::work(WorkingSetID* out) { ++_commonStats.works; // Adds the amount of time taken by work() to executionTimeMillis. ScopedTimer timer(&_commonStats.executionTimeMillis); if (NULL == _btreeCursor.get()) { // First call to work(). Perform cursor init. initIndexCursor(); checkEnd(); ++_commonStats.needTime; return PlanStage::NEED_TIME; } if (isEOF()) { return PlanStage::IS_EOF; } DiskLoc loc = _btreeCursor->getValue(); _btreeCursor->next(); checkEnd(); ++_specificStats.keysExamined; if (_shouldDedup) { if (_returned.end() != _returned.find(loc)) { ++_commonStats.needTime; return PlanStage::NEED_TIME; } else { _returned.insert(loc); } } *out = WorkingSet::INVALID_ID; ++_commonStats.advanced; return PlanStage::ADVANCED; }
void IndexScan::recoverFromYield() { if (isEOF()) { return; } _indexCursor->restorePosition(); if (!_savedKey.binaryEqual(_indexCursor->getKey()) || _savedLoc != _indexCursor->getValue()) { // Our restored position isn't the same as the saved position. When we call work() // again we want to return where we currently point, not past it. _yieldMovedCursor = true; // Our restored position might be past endKey, see if we've hit the end. checkEnd(); } }
bool BtreeCursor::advance() { killCurrentOp.checkForInterrupt(); if ( bucket.isNull() ) return false; bucket = bucket.btree()->advance(bucket, keyOfs, direction, "BtreeCursor::advance"); if ( !_independentFieldRanges ) { skipUnusedKeys( false ); checkEnd(); return ok(); } skipAndCheck(); return ok(); }
void DistinctScan::recoverFromYield() { ++_commonStats.unyields; if (isEOF() || (NULL == _btreeCursor.get())) { return; } // We can have a valid position before we check isEOF(), restore the position, and then be // EOF upon restore. if (!_btreeCursor->restorePosition().isOK() || _btreeCursor->isEOF()) { _hitEnd = true; return; } if (!_savedKey.binaryEqual(_btreeCursor->getKey()) || _savedLoc != _btreeCursor->getValue()) { // Our restored position might be past endKey, see if we've hit the end. checkEnd(); } }
void Count::recoverFromYield() { if (isEOF() || (NULL == _btreeCursor.get())) { return; } if (!_btreeCursor->restorePosition().isOK()) { _hitEnd = true; } if (_btreeCursor->isEOF()) { _hitEnd = true; return; } // See if we're somehow already past our end key (maybe the thing we were pointing at got // deleted...) int cmp = _btreeCursor->getKey().woCompare(_params.endKey, _descriptor->keyPattern(), false); if (cmp > 0 || (cmp == 0 && !_params.endKeyInclusive)) { _hitEnd = true; return; } if (!_endCursor->isEOF()) { if (!_endCursor->restorePosition().isOK()) { _hitEnd = true; return; } } // If we were EOF when we yielded we don't always want to have _btreeCursor run until // EOF. New documents may have been inserted after our endKey and our end marker // may be before them. // // As an example, say we're counting from 5 to 10 and the index only has keys // for 6, 7, 8, and 9. btreeCursor will point at a 6 key at the start and the // endCursor will be EOF. If we insert documents with keys 11 during a yield we // need to relocate the endCursor to point at them as the "end key" of our count. // // If we weren't EOF our end position might have moved around. Relocate it. _endCursor->seek(_params.endKey, _params.endKeyInclusive); // This can change during yielding. _shouldDedup = _descriptor->isMultikey(); checkEnd(); }
bool BtreeCursor::advance() { killCurrentOp.checkForInterrupt(); if ( bucket.isNull() ) return false; bucket = _advance(bucket, keyOfs, _direction, "BtreeCursor::advance"); if ( !_independentFieldRanges ) { skipUnusedKeys(); checkEnd(); if ( ok() ) { ++_nscanned; } } else { skipAndCheck(); } return ok(); }
bool BtreeCursor::advance() { // Reset this flag at the start of a new iteration. _boundsMustMatch = true; killCurrentOp.checkForInterrupt(); if ( bucket.isNull() ) return false; bucket = _advance(bucket, keyOfs, _direction, "BtreeCursor::advance"); if ( !_independentFieldRanges ) { skipUnusedKeys(); checkEnd(); if ( ok() ) { ++_nscanned; } } else { skipAndCheck(); } return ok(); }
bool BtreeCursor::advance() { // Reset this flag at the start of a new iteration. _boundsMustMatch = true; killCurrentOp.checkForInterrupt(); if (!ok()) { return false; } _indexCursor->next(); if ( !_independentFieldRanges ) { checkEnd(); if ( ok() ) { ++_nscanned; } } else { skipAndCheck(); } return ok(); }
PlanStage::StageState IndexScan::work(WorkingSetID* out) { ++_commonStats.works; if (NULL == _indexCursor.get()) { // First call to work(). Perform possibly heavy init. initIndexScan(); checkEnd(); } else if (_yieldMovedCursor) { _yieldMovedCursor = false; // Note that we're not calling next() here. We got the next thing when we recovered // from yielding. } if (isEOF()) { return PlanStage::IS_EOF; } // Grab the next (key, value) from the index. BSONObj keyObj = _indexCursor->getKey(); DiskLoc loc = _indexCursor->getValue(); // Move to the next result. // The underlying IndexCursor points at the *next* thing we want to return. We do this so // that if we're scanning an index looking for docs to delete we don't continually clobber // the thing we're pointing at. _indexCursor->next(); checkEnd(); if (_shouldDedup) { ++_specificStats.dupsTested; if (_returned.end() != _returned.find(loc)) { ++_specificStats.dupsDropped; ++_commonStats.needTime; return PlanStage::NEED_TIME; } else { _returned.insert(loc); } } if (Filter::passes(keyObj, _keyPattern, _filter)) { if (NULL != _filter) { ++_specificStats.matchTested; } // We must make a copy of the on-disk data since it can mutate during the execution of // this query. BSONObj ownedKeyObj = keyObj.getOwned(); // Fill out the WSM. WorkingSetID id = _workingSet->allocate(); WorkingSetMember* member = _workingSet->get(id); member->loc = loc; member->keyData.push_back(IndexKeyDatum(_keyPattern, ownedKeyObj)); member->state = WorkingSetMember::LOC_AND_IDX; if (_params.addKeyMetadata) { BSONObjBuilder bob; bob.appendKeys(_keyPattern, ownedKeyObj); member->addComputed(new IndexKeyComputedData(bob.obj())); } *out = id; ++_commonStats.advanced; return PlanStage::ADVANCED; } ++_commonStats.needTime; return PlanStage::NEED_TIME; }
PlanStage::StageState IndexScan::work(WorkingSetID* out) { ++_commonStats.works; if (NULL == _indexCursor.get()) { // First call to work(). Perform cursor init. CursorOptions cursorOptions; // The limit is *required* for 2d $near, which is the only index that pays attention to // it anyway. cursorOptions.numWanted = _params.limit; if (1 == _params.direction) { cursorOptions.direction = CursorOptions::INCREASING; } else { cursorOptions.direction = CursorOptions::DECREASING; } IndexCursor *cursor; Status s = _iam->newCursor(&cursor); verify(s.isOK()); _indexCursor.reset(cursor); _indexCursor->setOptions(cursorOptions); if (_params.bounds.isSimpleRange) { // Start at one key, end at another. Status status = _indexCursor->seek(_params.bounds.startKey); if (!status.isOK()) { warning() << "Seek failed: " << status.toString(); _hitEnd = true; return PlanStage::FAILURE; } if (!isEOF()) { _specificStats.keysExamined = 1; } } else { // "Fast" Btree-specific navigation. _btreeCursor = static_cast<BtreeIndexCursor*>(_indexCursor.get()); _checker.reset(new IndexBoundsChecker(&_params.bounds, _descriptor->keyPattern(), _params.direction)); int nFields = _descriptor->keyPattern().nFields(); vector<const BSONElement*> key; vector<bool> inc; key.resize(nFields); inc.resize(nFields); if (_checker->getStartKey(&key, &inc)) { _btreeCursor->seek(key, inc); _keyElts.resize(nFields); _keyEltsInc.resize(nFields); } else { _hitEnd = true; } } checkEnd(); } else if (_yieldMovedCursor) { _yieldMovedCursor = false; // Note that we're not calling next() here. } else { // You're allowed to call work() even if the stage is EOF, but we can't call // _indexCursor->next() if we're EOF. if (!isEOF()) { _indexCursor->next(); checkEnd(); } } if (isEOF()) { return PlanStage::IS_EOF; } DiskLoc loc = _indexCursor->getValue(); if (_shouldDedup) { ++_specificStats.dupsTested; if (_returned.end() != _returned.find(loc)) { ++_specificStats.dupsDropped; ++_commonStats.needTime; return PlanStage::NEED_TIME; } else { _returned.insert(loc); } } BSONObj ownedKeyObj = _indexCursor->getKey().getOwned(); WorkingSetID id = _workingSet->allocate(); WorkingSetMember* member = _workingSet->get(id); member->loc = loc; member->keyData.push_back(IndexKeyDatum(_descriptor->keyPattern(), ownedKeyObj)); member->state = WorkingSetMember::LOC_AND_IDX; if (Filter::passes(member, _filter)) { if (NULL != _filter) { ++_specificStats.matchTested; } if (_params.addKeyMetadata) { BSONObjBuilder bob; bob.appendKeys(_descriptor->keyPattern(), ownedKeyObj); member->addComputed(new IndexKeyComputedData(bob.obj())); } *out = id; ++_commonStats.advanced; return PlanStage::ADVANCED; } _workingSet->free(id); ++_commonStats.needTime; return PlanStage::NEED_TIME; }
PlanStage::StageState IndexScan::work(WorkingSetID* out) { ++_commonStats.works; if (NULL == _indexCursor.get()) { // First call to work(). Perform cursor init. CursorOptions cursorOptions; // The limit is *required* for 2d $near, which is the only index that pays attention to // it anyway. cursorOptions.numWanted = _params.limit; if (1 == _params.direction) { cursorOptions.direction = CursorOptions::INCREASING; } else { cursorOptions.direction = CursorOptions::DECREASING; } IndexCursor *cursor; _iam->newCursor(&cursor); _indexCursor.reset(cursor); _indexCursor->setOptions(cursorOptions); if (_params.bounds.isSimpleRange) { // Start at one key, end at another. _indexCursor->seek(_params.bounds.startKey); } else { // "Fast" Btree-specific navigation. _btreeCursor = static_cast<BtreeIndexCursor*>(_indexCursor.get()); _checker.reset(new IndexBoundsChecker(&_params.bounds, _descriptor->keyPattern(), _params.direction)); vector<const BSONElement*> key; vector<bool> inc; _checker->getStartKey(&key, &inc); _btreeCursor->seek(key, inc); int nFields = _descriptor->keyPattern().nFields(); _keyElts.resize(nFields); _keyEltsInc.resize(nFields); } checkEnd(); } else if (_yieldMovedCursor) { _yieldMovedCursor = false; // Note that we're not calling next() here. } else { _indexCursor->next(); checkEnd(); } if (isEOF()) { return PlanStage::IS_EOF; } DiskLoc loc = _indexCursor->getValue(); if (_shouldDedup) { ++_specificStats.dupsTested; if (_returned.end() != _returned.find(loc)) { ++_specificStats.dupsDropped; ++_commonStats.needTime; return PlanStage::NEED_TIME; } else { _returned.insert(loc); } } WorkingSetID id = _workingSet->allocate(); WorkingSetMember* member = _workingSet->get(id); member->loc = loc; member->keyData.push_back(IndexKeyDatum(_descriptor->keyPattern(), _indexCursor->getKey().getOwned())); member->state = WorkingSetMember::LOC_AND_IDX; if (Filter::passes(member, _filter)) { if (NULL != _filter) { ++_specificStats.matchTested; } *out = id; ++_commonStats.advanced; return PlanStage::ADVANCED; } _workingSet->free(id); ++_commonStats.needTime; return PlanStage::NEED_TIME; }