]> granicus.if.org Git - transmission/commitdiff
(trunk libT) experimental faster implementation of tr_torrentFiles(). for the time...
authorCharles Kerr <charles@transmissionbt.com>
Sat, 16 May 2009 01:43:21 +0000 (01:43 +0000)
committerCharles Kerr <charles@transmissionbt.com>
Sat, 16 May 2009 01:43:21 +0000 (01:43 +0000)
libtransmission/torrent.c

index cf97a5dbd4d15f781dcfc07c28b97c58c4388c42..8e48ad907abbe7e57ec19fa1557f7d7afa516d72 100644 (file)
@@ -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; i<lastBlock; ++i )
+                if( tr_cpBlockIsCompleteFast( &tor->completion, 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; i<lastBlock && i<=lastBlockOfFirstPiece; ++i )
+                if( tr_cpBlockIsCompleteFast( &tor->completion, 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; i<f->lastPiece; ++i )
+                    b -= tr_cpMissingBlocksInPiece( &tor->completion, i );
+                b *= tor->blockSize;
+                total += b;
+            }
+
+            /* the rest of the last piece */
+            for( i=firstBlockOfLastPiece; i<lastBlock; ++i )
+                if( tr_cpBlockIsCompleteFast( &tor->completion, 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 )