bool RemoteMergedArray::proceedChunkMsg(size_t stream, AttributeID attId, MemChunk* chunk)
{
    boost::shared_ptr<MessageDesc>  chunkDesc = _messages[attId][stream];
    _messages[attId][stream].reset();
    boost::shared_ptr<scidb_msg::Chunk> chunkMsg = chunkDesc->getRecord<scidb_msg::Chunk>();

    StatisticsScope sScope(_statistics);
    currentStatistics->receivedSize += chunkDesc->getMessageSize();
    currentStatistics->receivedMessages++;

    _nextPositions[attId][stream].clear();

    if (!chunkMsg->eof())
    {
        LOG4CXX_TRACE(logger, "RemoteMergedArray received next chunk message");
        if (chunkDesc->getBinary() && chunk != NULL)
        {
            const int compMethod = chunkMsg->compression_method();
            const size_t decompressedSize = chunkMsg->decompressed_size();

            Address firstElem;
            firstElem.attId = attId;
            firstElem.arrId = getArrayDesc().getId();
            for (int i = 0; i < chunkMsg->coordinates_size(); i++) {
                firstElem.coords.push_back(chunkMsg->coordinates(i));
            }

            chunk->initialize(this, &desc, firstElem, compMethod);
            chunk->setSparse(chunkMsg->sparse());
            chunk->setRLE(chunkMsg->rle());
            chunk->setCount(chunkMsg->count());

            boost::shared_ptr<CompressedBuffer> compressedBuffer = dynamic_pointer_cast<CompressedBuffer>(chunkDesc->getBinary());
            compressedBuffer->setCompressionMethod(compMethod);
            compressedBuffer->setDecompressedSize(decompressedSize);
            chunk->decompress(*compressedBuffer);
            assert(checkChunkMagic(*chunk));
            LOG4CXX_TRACE(logger, "RemoteMergedArray initializes next chunk");
        }

        LOG4CXX_TRACE(logger, "RemoteMergedArray initializes next position");
        if (chunkMsg->has_next())
        {
            for (int i = 0; i < chunkMsg->next_coordinates_size(); i++) {
                _nextPositions[attId][stream].push_back(chunkMsg->next_coordinates(i));
            }
            requestNextChunk(stream, attId, false);
        }
        return true;
    }
    else
    {
        LOG4CXX_TRACE(logger, "RemoteMergedArray has no new chunks");
        return false;
    }
}
bool RemoteMergedArray::fetchChunk(size_t stream, AttributeID attId, MemChunk* chunk)
{
   boost::shared_ptr<Query> query = Query::getQueryByID(_queryId);
   if (query->getInstanceID() != stream) {
       if (!_hasPositions[attId][stream]) {
           requestNextChunk(stream, attId, chunk == NULL);
       }
       Semaphore::ErrorChecker errorChecker = bind(&Query::validateQueryPtr, query);
       _received[attId][stream].enter(errorChecker);
       _hasPositions[attId][stream] = true;
       return proceedChunkMsg(stream, attId, chunk);
   } else {
       // We get chunk body from the current result array on local instance
       bool result = false;
       if (chunk) {
           if (!_localArray->getConstIterator(attId)->end()) {
               {
                   const ConstChunk& srcChunk = _localArray->getConstIterator(attId)->getChunk();
                   PinBuffer buf(srcChunk);
                   Address firstElem;
                   firstElem.attId = attId;
                   firstElem.arrId = getArrayDesc().getId();
                   firstElem.coords = srcChunk.getFirstPosition(false);
                   chunk->initialize(this, &desc, firstElem, srcChunk.getCompressionMethod());
                   chunk->setSparse(srcChunk.isSparse());
                   chunk->setRLE(srcChunk.isRLE());
                   if (srcChunk.isRLE() && !srcChunk.getAttributeDesc().isEmptyIndicator() && getArrayDesc().getEmptyBitmapAttribute() != NULL && srcChunk.getBitmapSize() == 0) { 
                       srcChunk.makeClosure(*chunk, srcChunk.getEmptyBitmap());
                   } else { 
                       chunk->allocate(srcChunk.getSize());
                       assert(checkChunkMagic(srcChunk));
                       memcpy(chunk->getData(), srcChunk.getData(), srcChunk.getSize());
                   }
                   chunk->write(query);
               }
               ++(*_localArray->getConstIterator(attId));
               result = true;
           }
       }
       _hasPositions[attId][stream] = true;
       if (!_localArray->getConstIterator(attId)->end()) {
           _nextPositions[attId][stream] = _localArray->getConstIterator(attId)->getPosition();
           result = true;
       } else {
           _nextPositions[attId][stream].clear();
       }
       return result;
   }
}
示例#3
0
std::shared_ptr<MemChunk>
SyntheticDimChunkMerger::getMergedChunk(AttributeID attId,
                                        const std::shared_ptr<Query>& query)
{
    std::shared_ptr<MemChunk> result;
    std::shared_ptr<ChunkIterator> dstIterator;

    for (std::vector<std::shared_ptr<MemChunk> >::iterator chunkIt =  _partialChunks.begin();
         chunkIt !=  _partialChunks.end(); ++chunkIt) {
        std::shared_ptr<MemChunk>& chunk = *chunkIt;
        if (!chunk) {
            continue;
        }
        if (!result) {
            result = chunk;
            // During redim, there is always a empty tag, and the chunk can't be sparse.
            assert(result->getArrayDesc().getEmptyBitmapAttribute());
            continue;
        }
        result->setCount(0); // unknown

        if (!dstIterator) {
            _syntheticDimHelper.updateMapCoordToCount(result.get());
            dstIterator = result->getIterator(query,
                                              ChunkIterator::APPEND_CHUNK|
                                              ChunkIterator::APPEND_EMPTY_BITMAP|
                                              ChunkIterator::NO_EMPTY_CHECK);
        }
        mergeChunks(dstIterator, chunk);
        chunk.reset();
    }
    if (dstIterator) {
        dstIterator->flush();
        dstIterator.reset();
    }
    clear();
    checkChunkMagic(*result);
    return result;
}