Ejemplo n.º 1
0
    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;
    }
Ejemplo n.º 2
0
    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;
    }
Ejemplo n.º 3
0
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();
		}
}
Ejemplo n.º 4
0
    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();
    }
Ejemplo n.º 5
0
 // 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();
 }
Ejemplo n.º 6
0
    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();         
    }
Ejemplo n.º 7
0
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();
    }
}
Ejemplo n.º 8
0
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();
  }
}
Ejemplo n.º 9
0
void FileHeaderParser::feed(char *data, int len) {
	if (headerPassed) {
		total += len;
		checkEnd();
		}
	else
		parse(std::string(data, data+len));
}
Ejemplo n.º 10
0
 bool BtreeCursor::advance() {
     checkForInterrupt();
     if ( bucket.isNull() )
         return false;
     bucket = bucket.btree()->advance(bucket, keyOfs, direction, "BtreeCursor::advance");
     skipUnusedKeys();
     checkEnd();
     return !bucket.isNull();
 }
Ejemplo n.º 11
0
 void BtreeCursor::init() {
     bool found;
     bucket = indexDetails.head.btree()->
     locate(indexDetails, indexDetails.head, startKey, order, keyOfs, found, direction > 0 ? minDiskLoc : maxDiskLoc, direction);
     
     skipUnusedKeys();
     
     checkEnd();         
 }
Ejemplo n.º 12
0
 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();
 }
Ejemplo n.º 13
0
    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;
    }
Ejemplo n.º 14
0
 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();
 }
Ejemplo n.º 15
0
 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();
 }
Ejemplo n.º 16
0
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();
	}
}
Ejemplo n.º 17
0
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));
    }
}
Ejemplo n.º 18
0
 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();
 }
Ejemplo n.º 19
0
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();

		}
	}
}
Ejemplo n.º 20
0
    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;
    }
Ejemplo n.º 21
0
    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();
        }
    }
Ejemplo n.º 22
0
    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();
    }
Ejemplo n.º 23
0
    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();
        }
    }
Ejemplo n.º 24
0
    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();
    }
Ejemplo n.º 25
0
    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();
    }
Ejemplo n.º 26
0
    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();
    }
Ejemplo n.º 27
0
    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();
    }
Ejemplo n.º 28
0
    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;
    }
Ejemplo n.º 29
0
    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;
    }
Ejemplo n.º 30
0
    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;
    }