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; } }
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 ); } } } }