From 194833dfec534b5646ff26005a09b6cfd743258d Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 5 Nov 2008 04:50:03 +0000 Subject: [PATCH] (libT) optimize tr_cpHaveValid(), which according to cachegrind is the biggest remaining hotspot function --- libtransmission/completion.c | 40 +++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/libtransmission/completion.c b/libtransmission/completion.c index bfc4568df..fd00c7adb 100644 --- a/libtransmission/completion.c +++ b/libtransmission/completion.c @@ -33,6 +33,7 @@ struct tr_completion { unsigned int sizeWhenDoneIsDirty : 1; + unsigned int haveValidIsDirty : 1; tr_torrent * tor; @@ -50,6 +51,11 @@ struct tr_completion use tr_cpSizeWhenDone() instead! */ uint64_t sizeWhenDoneLazy; + /* number of bytes we'll have when done downloading. [0..info.totalSize] + DON'T access this directly; it's a lazy field. + use tr_cpHaveValid() instead! */ + uint64_t haveValidLazy; + /* number of bytes we want or have now. [0..sizeWhenDone] */ uint64_t sizeNow; }; @@ -63,6 +69,7 @@ tr_cpReset( tr_completion * cp ) sizeof( uint16_t ) * cp->tor->info.pieceCount ); cp->sizeNow = 0; cp->sizeWhenDoneIsDirty = 1; + cp->haveValidIsDirty = 1; } tr_completion * @@ -142,8 +149,7 @@ int tr_cpPieceIsComplete( const tr_completion * cp, tr_piece_index_t piece ) { - return cp->completeBlocks[piece] == tr_torPieceCountBlocks( cp->tor, - piece ); + return cp->completeBlocks[piece] == tr_torPieceCountBlocks( cp->tor, piece ); } const tr_bitfield * @@ -185,6 +191,7 @@ tr_cpPieceRem( tr_completion * cp, cp->sizeNow -= tr_torBlockCountBytes( tor, block ); cp->sizeWhenDoneIsDirty = 1; + cp->haveValidIsDirty = 1; cp->completeBlocks[piece] = 0; tr_bitfieldRemRange ( cp->blockBitfield, start, end ); tr_bitfieldRem( cp->pieceBitfield, piece ); @@ -211,13 +218,14 @@ tr_cpBlockAdd( tr_completion * cp, ++cp->completeBlocks[piece]; - if( cp->completeBlocks[piece] == tr_torPieceCountBlocks( tor, piece ) ) + if( tr_cpPieceIsComplete( cp, piece ) ) tr_bitfieldAdd( cp->pieceBitfield, piece ); tr_bitfieldAdd( cp->blockBitfield, block ); cp->sizeNow += blockSize; + cp->haveValidIsDirty = 1; cp->sizeWhenDoneIsDirty = 1; } } @@ -260,8 +268,7 @@ int tr_cpMissingBlocksInPiece( const tr_completion * cp, tr_piece_index_t piece ) { - return tr_torPieceCountBlocks( cp->tor, - piece ) - cp->completeBlocks[piece]; + return tr_torPieceCountBlocks( cp->tor, piece ) - cp->completeBlocks[piece]; } /*** @@ -300,26 +307,39 @@ tr_cpGetStatus( const tr_completion * cp ) return TR_CP_INCOMPLETE; } -uint64_t -tr_cpHaveValid( const tr_completion * cp ) +static uint64_t +calculateHaveValid( const tr_completion * ccp ) { uint64_t b = 0; tr_piece_index_t i; - const tr_torrent * tor = cp->tor; + const tr_torrent * tor = ccp->tor; const uint64_t pieceSize = tor->info.pieceSize; const uint64_t lastPieceSize = tor->lastPieceSize; const tr_piece_index_t lastPiece = tor->info.pieceCount - 1; for( i=0; i!=lastPiece; ++i ) - if( tr_cpPieceIsComplete( cp, i ) ) + if( tr_cpPieceIsComplete( ccp, i ) ) b += pieceSize; - if( tr_cpPieceIsComplete( cp, lastPiece ) ) + if( tr_cpPieceIsComplete( ccp, lastPiece ) ) b += lastPieceSize; return b; } +uint64_t +tr_cpHaveValid( const tr_completion * ccp ) +{ + if( ccp->haveValidIsDirty ) + { + tr_completion * cp = (tr_completion *) ccp; /* mutable */ + cp->haveValidLazy = calculateHaveValid( ccp ); + cp->haveValidIsDirty = 0; + } + + return ccp->haveValidLazy; +} + uint64_t tr_cpHaveTotal( const tr_completion * cp ) {