结果数组

来源:互联网 发布:sql某列后加合计数 编辑:程序博客网 时间:2024/05/09 09:32
ConstChunk const*
MultiStreamArray::nextChunk(AttributeID attId, MemChunk& chunk)
{
    static const char *funcName = "MultiStreamArray::nextChunk: ";


    ASSERT_EXCEPTION( (attId < getArrayDesc().getAttributes().size()) , funcName);
    assert(attId < _resultChunks.size());
    assert(attId < _chunkMergers.size());
    assert(attId < _currMinPos.size());
    assert(attId < _notReadyPositions.size());
    assert(attId < _readyPositions.size());
    assert(attId < _currPartialStreams.size());


    list<size_t>& notReadyPos = _notReadyPositions[attId];
    PositionMap& readyPos = _readyPositions[attId];


    if (logger->isTraceEnabled()) {
        for (list<size_t>::iterator it=notReadyPos.begin(); it != notReadyPos.end(); ++it) {
            LOG4CXX_TRACE(logger, funcName << "NOT ready streams attId= " << attId
                         <<", stream="<< (*it));
        }
    }


    while (true) {


        getAllStreamPositions(readyPos, notReadyPos, attId);


        list<size_t>& currPartialStreams = _currPartialStreams[attId];


        if (readyPos.empty() && currPartialStreams.empty()) {
            // no more remote chunks
            LOG4CXX_TRACE(logger, funcName << "EOF - no more chunks attId= " << attId);
            return NULL;
        }


        logReadyPositions(readyPos, attId);


        bool notMyStream = false;
        if (currPartialStreams.empty()) {
            // starting a new chunk, find all partial chunk streams


            assert(_currMinPos[attId].empty());


            PositionMap::value_type const& minElem = readyPos.top();
            _currMinPos[attId] = minElem.getCoords();
            notMyStream = (minElem.getDest() != _localStream);


            if (_resultChunks[attId] && !notMyStream) {
                scidb::CoordinatesLess comp;
                if (!comp(_resultChunks[attId]->getFirstPosition(false), _currMinPos[attId])) {
                    if (isEnforceDataIntegrity()) {
                        throw USER_EXCEPTION(SCIDB_SE_REDISTRIBUTE, SCIDB_LE_CHUNK_POSITION_OUT_OF_ORDER)
                        << CoordsToStr(_currMinPos[attId]);
                    }
                    if (!_hasDataIntegrityIssue) {
                        LOG4CXX_WARN(logger, funcName << "Data chunk at position " << CoordsToStr(_currMinPos[attId])
                                     << " for attribute ID = " << attId << " is received out of (row-major) order"
                                     << ". Add log4j.logger.scidb.qproc.streamarray=TRACE to the log4cxx config file for more");
                        _hasDataIntegrityIssue = true;
                    } else {
                        LOG4CXX_TRACE(logger, funcName << "Data chunk at position " << CoordsToStr(_currMinPos[attId])
                                      << " for attribute ID = " << attId << " is received out of (row-major) order");
                    }
                }
                LOG4CXX_TRACE(logger, funcName << "clearing old chunk attId= " << attId);
                _resultChunks[attId].reset();
            }
            while (!readyPos.empty()) {
                if (readyPos.top().getCoords() != _currMinPos[attId]) { break; }
                assert(notMyStream == (readyPos.top().getDest() != _localStream));
                currPartialStreams.push_back(readyPos.top().getSrc());
                readyPos.pop();
            }


        }


        if (logger->isTraceEnabled()) {
            for (list<size_t>::iterator it=currPartialStreams.begin();
                 it != currPartialStreams.end(); ++it) {
                LOG4CXX_TRACE(logger, funcName << "partial chunk attId= " << attId
                              <<", stream="<< *it
                              <<", isMyStream="<<!notMyStream);
            }
        }


        if (notMyStream) {
            // some stream positions are for chunks that are not destined for this instance
            _currMinPos[attId].clear();
            // let's check if we have more messages in the stream
            getNextStreamPositions(readyPos, notReadyPos, currPartialStreams, attId);
            // XXX TODO: this amounts to busy-polling of the stream generating extra network traffic etc.
            // we should probably just back-off for a few mils ...
        } else {
            break;
        }
    }


    list<size_t>& currPartialStreams = _currPartialStreams[attId];
    mergePartialStreams(readyPos, notReadyPos, currPartialStreams, attId);


    assert(currPartialStreams.empty());
    assert(_resultChunks[attId]);
    assert(_resultChunks[attId]->getFirstPosition(false) == _currMinPos[attId]);


    LOG4CXX_TRACE(logger, funcName <<"done with chunk attId= " << attId
                  <<", resultChunk=" << _resultChunks[attId].get()
                  <<", resultChunk size=" << _resultChunks[attId]->getSize());


    LOG4CXX_TRACE(logger, funcName <<"done with chunk attId=" <<attId
                  << ", minPos="<< _currMinPos[attId]);


    _currMinPos[attId].clear();
    const MemChunk* result = _resultChunks[attId].get();
    return result;
}
0 0
原创粉丝点击