From 063b11bda11c128203c74b9fdc480bc8fd830706 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sat, 16 May 2009 01:43:21 +0000 Subject: [PATCH] (trunk libT) experimental faster implementation of tr_torrentFiles(). for the time being, keep the old implementation too and add an assertion that the two come up with the same results. --- libtransmission/torrent.c | 69 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/libtransmission/torrent.c b/libtransmission/torrent.c index cf97a5dbd..8e48ad907 100644 --- a/libtransmission/torrent.c +++ b/libtransmission/torrent.c @@ -842,7 +842,7 @@ tr_torrentStat( tr_torrent * tor ) const tr_tracker_info * ti; int usableSeeds = 0; uint64_t now; - double downloadedForRatio, seedRatio; + double downloadedForRatio, seedRatio=0; tr_bool checkSeedRatio; if( !tor ) @@ -982,7 +982,7 @@ tr_torrentStat( tr_torrent * tor ) ***/ static uint64_t -fileBytesCompleted( const tr_torrent * tor, +oldFileBytesCompleted( const tr_torrent * tor, tr_file_index_t fileIndex ) { const tr_file * file = &tor->info.files[fileIndex]; @@ -1032,6 +1032,71 @@ fileBytesCompleted( const tr_torrent * tor, return haveBytes; } +static uint64_t +fileBytesCompleted( const tr_torrent * tor, tr_file_index_t index ) +{ + uint64_t total = 0; + + const tr_file * f = &tor->info.files[index]; + const tr_block_index_t firstBlock = f->offset / tor->blockSize; + const uint64_t lastByte = f->offset + f->length - (f->length?1:0); + const tr_block_index_t lastBlock = lastByte / tor->blockSize; + + if( firstBlock == lastBlock ) + { + if( tr_cpBlockIsCompleteFast( &tor->completion, firstBlock ) ) + total = f->length; + } + else + { + uint32_t i; + + /* the first block */ + if( tr_cpBlockIsCompleteFast( &tor->completion, firstBlock ) ) + total += tor->blockSize - ( f->offset % tor->blockSize ); + + /* the middle blocks */ + if( f->firstPiece == f->lastPiece ) + { + for( i=firstBlock+1; icompletion, i ) ) + total += tor->blockSize; + } + else + { + const tr_block_index_t firstBlockOfLastPiece = tr_torPieceFirstBlock( tor, f->lastPiece ); + const tr_block_index_t lastBlockOfFirstPiece = tr_torPieceFirstBlock( tor, f->firstPiece ) + + tr_torPieceCountBlocks( tor, f->firstPiece ) + - 1; + /* the rest of the first piece */ + for( i=firstBlock+1; icompletion, i ) ) + total += tor->blockSize; + + /* the middle pieces */ + if( f->firstPiece + 1 < f->lastPiece ) { + uint64_t b = tor->blockCountInPiece * ( f->lastPiece - ( f->firstPiece + 1 ) ); + for( i=f->firstPiece+1; ilastPiece; ++i ) + b -= tr_cpMissingBlocksInPiece( &tor->completion, i ); + b *= tor->blockSize; + total += b; + } + + /* the rest of the last piece */ + for( i=firstBlockOfLastPiece; icompletion, i ) ) + total += tor->blockSize; + } + + /* the last block */ + if( tr_cpBlockIsCompleteFast( &tor->completion, lastBlock ) ) + total += ( lastByte+1 - (lastBlock*tor->blockSize) ); + } + + assert( total == oldFileBytesCompleted( tor, index ) ); + return total; +} + tr_file_stat * tr_torrentFiles( const tr_torrent * tor, tr_file_index_t * fileCount )