Пример #1
0
tr_addreq_t
tr_webseedAddRequest( tr_webseed  * w,
                      uint32_t      pieceIndex,
                      uint32_t      pieceOffset,
                      uint32_t      byteCount )
{
    int ret;

    if( w->busy || w->dead )
    {
        ret = TR_ADDREQ_FULL;
    }
    else
    {
        w->busy = 1;
        w->pieceIndex = pieceIndex;
        w->pieceOffset = pieceOffset;
        w->byteCount = byteCount;
        evbuffer_drain( w->content, EVBUFFER_LENGTH( w->content ) );
        requestNextChunk( w );
        ret = TR_ADDREQ_OK;
    }

    return ret;
}
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;
    }
}
ConstChunk const* RemoteArray::nextChunk(AttributeID attId, MemChunk& chunk)
{
    if (!_requested[attId]) {
        requestNextChunk(attId);
    }
    boost::shared_ptr<Query> query = Query::getQueryByID(_queryId);
    Semaphore::ErrorChecker errorChecker = bind(&Query::validateQueryPtr, query);
    _received[attId].enter(errorChecker);
    _requested[attId] = true;
    return proceedChunkMsg(attId, chunk) ? &chunk : NULL;
}
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;
   }
}
bool RemoteArray::proceedChunkMsg(AttributeID attId, MemChunk& chunk)
{
    boost::shared_ptr<MessageDesc>  chunkDesc = _messages[attId];
    _messages[attId].reset();

    StatisticsScope sScope(_statistics);
    boost::shared_ptr<scidb_msg::Chunk> chunkMsg = chunkDesc->getRecord<scidb_msg::Chunk>();
    currentStatistics->receivedSize += chunkDesc->getMessageSize();
    currentStatistics->receivedMessages++;

    if (!chunkMsg->eof())
    {
        LOG4CXX_TRACE(logger, "RemoteArray received next chunk message");
        assert(chunkDesc->getBinary());

        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.setCount(chunkMsg->count());

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

        requestNextChunk(attId);
        return true;
    }
    else
    {
        return false;
    }
}
Пример #6
0
static void
webResponseFunc( tr_session    * session,
                 long            response_code,
                 const void    * response,
                 size_t          response_byte_count,
                 void          * vw )
{
    tr_webseed * w = vw;
    tr_torrent * tor = tr_torrentFindFromHash( session, w->hash );
    const int    success = ( response_code == 206 );

/*fprintf( stderr, "server responded with code %ld and %lu bytes\n",
  response_code, (unsigned long)response_byte_count );*/
    if( !success )
    {
        /* FIXME */
    }
    else if( tor != NULL )
    {
        evbuffer_add( w->content, response, response_byte_count );
        if( !w->dead )
        {
            fireClientGotData( w, response_byte_count );
            tr_rcTransferred( &w->rateDown, response_byte_count );
        }

        if( EVBUFFER_LENGTH( w->content ) < w->byteCount )
            requestNextChunk( w );
        else {
            tr_ioWrite( tor, w->pieceIndex, w->pieceOffset, w->byteCount, EVBUFFER_DATA(w->content) );
            evbuffer_drain( w->content, EVBUFFER_LENGTH( w->content ) );
            w->busy = 0;
            if( w->dead )
                tr_webseedFree( w );
            else  {
                fireClientGotBlock( w, w->pieceIndex, w->pieceOffset, w->byteCount );
                fireNeedReq( w );
            }
        }
    }
}