예제 #1
0
    DiskLoc CappedIterator::getNextCapped(const NamespaceDetails* nsd, const ExtentManager* em,
                                          const DiskLoc& dl,
                                          CollectionScanParams::Direction direction ) {
        verify(!dl.isNull());

        if (CollectionScanParams::FORWARD == direction) {
            // If it's not looped, it's easy.
            if (!nsd->capLooped()) { return em->getNextRecord( dl ); }

            // TODO ELABORATE
            // EOF.
            if (dl == em->getExtent( nsd->capExtent() )->lastRecord) { return DiskLoc(); }

            DiskLoc ret = nextLoop(nsd,em,dl);

            // If we become capFirstNewRecord from same extent, advance to next extent.
            if (ret == nsd->capFirstNewRecord() && ret != em->getExtent( nsd->capExtent() )->firstRecord) {
                ret = nextLoop(nsd,em,em->getExtent( nsd->capExtent() )->lastRecord);
            }

            // If we have just gotten to beginning of capExtent, skip to capFirstNewRecord
            if (ret == em->getExtent( nsd->capExtent() )->firstRecord) { ret = nsd->capFirstNewRecord(); }

            return ret;
        }
        else {
            if (!nsd->capLooped()) { return em->getPrevRecord( dl ); }

            // TODO ELABORATE
            // Last record
            if (nsd->capFirstNewRecord() == em->getExtent( nsd->capExtent() )->firstRecord) {
                if (dl == nextLoop(nsd,em,em->getExtent( nsd->capExtent() )->lastRecord)) {
                    return DiskLoc();
                }
            }
            else {
                if (dl == em->getExtent( nsd->capExtent() )->firstRecord) { return DiskLoc(); }
            }

            DiskLoc ret;
            // If we are capFirstNewRecord, advance to prev extent, otherwise just get prev.
            if (dl == nsd->capFirstNewRecord()) {
                ret = prevLoop(nsd, em, em->getExtent( nsd->capExtent() )->firstRecord);
            }
            else {
                ret = prevLoop(nsd, em, dl);
            }

            // If we just became last in cap extent, advance past capFirstNewRecord
            // (We know capExtent.ext()->firstRecord != capFirstNewRecord, since would
            // have returned DiskLoc() earlier otherwise.)
            if (ret == em->getExtent( nsd->capExtent() )->lastRecord) {
                ret = em->getPrevRecord( nsd->capFirstNewRecord() );
            }

            return ret;
        }
    }
예제 #2
0
파일: xPL_Node.cpp 프로젝트: AndTH/arduixpl
xPL_Node* xPL_Node::prevLoop() { 
	if (_parent)
	{
		xPL_Node* n = _parent->child();
		while(n->nextLoop()!=this) n=nextLoop();
		return n;
	}
	return NULL;
}
예제 #3
0
    CappedIterator::CappedIterator(const CollectionTemp* collection,
                                   const DiskLoc& start, bool tailable,
                                   const CollectionScanParams::Direction& dir)
        : _collection(collection), _curr(start), _tailable(tailable),
          _direction(dir), _killedByInvalidate(false) {

        verify( collection->ok() );

        if (_curr.isNull()) {

            const NamespaceDetails* nsd = _collection->_details;
            const ExtentManager* em = _collection->getExtentManager();

            // If a start position isn't specified, we fill one out from the start of the
            // collection.
            if (CollectionScanParams::FORWARD == _direction) {
                // Going forwards.
                if (!nsd->capLooped()) {
                    // If our capped collection doesn't loop around, the first record is easy.
                    _curr = nsd->firstRecord();
                }
                else {
                    // Our capped collection has "looped' around.
                    // Copied verbatim from ForwardCappedCursor::init.
                    // TODO ELABORATE
                    _curr = em->getExtent( nsd->capExtent() )->firstRecord;
                    if (!_curr.isNull() && _curr == nsd->capFirstNewRecord()) {
                        _curr = em->getExtent( nsd->capExtent() )->lastRecord;
                        _curr = nextLoop(nsd,em,_curr);
                    }
                }
            }
            else {
                // Going backwards
                if (!nsd->capLooped()) {
                    // Start at the end.
                    _curr = nsd->lastRecord();
                }
                else {
                    _curr = em->getExtent( nsd->capExtent() )->lastRecord;
                }
            }
        }
    }
    //
    // Capped collection traversal
    //
    CappedRecordStoreV1Iterator::CappedRecordStoreV1Iterator( OperationContext* txn,
                                                              const CappedRecordStoreV1* collection,
                                                              const DiskLoc& start, bool tailable,
                                                              const CollectionScanParams::Direction& dir)
        : _txn(txn), _recordStore(collection), _curr(start), _tailable(tailable),
          _direction(dir), _killedByInvalidate(false) {

        if (_curr.isNull()) {

            const RecordStoreV1MetaData* nsd = _recordStore->details();

            // If a start position isn't specified, we fill one out from the start of the
            // collection.
            if (CollectionScanParams::FORWARD == _direction) {
                // Going forwards.
                if (!nsd->capLooped()) {
                    // If our capped collection doesn't loop around, the first record is easy.
                    _curr = collection->firstRecord(_txn);
                }
                else {
                    // Our capped collection has "looped' around.
                    // Copied verbatim from ForwardCappedCursor::init.
                    // TODO ELABORATE
                    _curr = _getExtent( nsd->capExtent() )->firstRecord;
                    if (!_curr.isNull() && _curr == nsd->capFirstNewRecord()) {
                        _curr = _getExtent( nsd->capExtent() )->lastRecord;
                        _curr = nextLoop(_curr);
                    }
                }
            }
            else {
                // Going backwards
                if (!nsd->capLooped()) {
                    // Start at the end.
                    _curr = collection->lastRecord(_txn);
                }
                else {
                    _curr = _getExtent( nsd->capExtent() )->lastRecord;
                }
            }
        }
    }
    DiskLoc CappedRecordStoreV1Iterator::getNextCapped(const DiskLoc& dl) {
        invariant(!dl.isNull());
        const RecordStoreV1MetaData* details = _recordStore->details();

        if (CollectionScanParams::FORWARD == _direction) {
            // If it's not looped, it's easy.
            if (!_recordStore->details()->capLooped()) {
                return _getNextRecord( dl );
            }

            // TODO ELABORATE
            // EOF.
            if (dl == _getExtent( details->capExtent() )->lastRecord) {
                return DiskLoc();
            }

            DiskLoc ret = nextLoop(dl);

            // If we become capFirstNewRecord from same extent, advance to next extent.
            if (ret == details->capFirstNewRecord() && ret != _getExtent( details->capExtent() )->firstRecord) {
                ret = nextLoop(_getExtent( details->capExtent() )->lastRecord);
            }

            // If we have just gotten to beginning of capExtent, skip to capFirstNewRecord
            if (ret == _getExtent( details->capExtent() )->firstRecord) { ret = details->capFirstNewRecord(); }

            return ret;
        }
        else {
            if (!details->capLooped()) { return _getPrevRecord( dl ); }

            // TODO ELABORATE
            // Last record
            if (details->capFirstNewRecord() == _getExtent( details->capExtent() )->firstRecord) {
                if (dl == nextLoop(_getExtent( details->capExtent() )->lastRecord)) {
                    return DiskLoc();
                }
            }
            else {
                if (dl == _getExtent( details->capExtent() )->firstRecord) { return DiskLoc(); }
            }

            DiskLoc ret;
            // If we are capFirstNewRecord, advance to prev extent, otherwise just get prev.
            if (dl == details->capFirstNewRecord()) {
                ret = prevLoop(_getExtent( details->capExtent() )->firstRecord);
            }
            else {
                ret = prevLoop(dl);
            }

            // If we just became last in cap extent, advance past capFirstNewRecord
            // (We know ext(capExtent)->firstRecord != capFirstNewRecord, since would
            // have returned DiskLoc() earlier otherwise.)
            if (ret == _getExtent( details->capExtent() )->lastRecord) {
                ret = _getPrevRecord( details->capFirstNewRecord() );
            }

            return ret;
        }
    }