Changeset 7631


Ignore:
Timestamp:
Jan 7, 2009, 2:22:11 AM (12 years ago)
Author:
charles
Message:

(trunk libT) much faster implementation of tr_cpBlockBitfieldSet()

Location:
trunk/libtransmission
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/completion.c

    r7630 r7631  
    153153
    154154void
    155 tr_cpBlockAdd( tr_completion *  cp,
    156                tr_block_index_t block )
     155tr_cpBlockAdd( tr_completion * cp, tr_block_index_t block )
    157156{
    158157    const tr_torrent * tor = cp->tor;
     
    178177}
    179178
    180 int
    181 tr_cpBlockBitfieldSet( tr_completion * cp,
    182                        tr_bitfield *   bitfield )
    183 {
    184     int success = FALSE;
    185 
    186     assert( cp );
    187     assert( bitfield );
    188 
    189     if( tr_bitfieldTestFast( bitfield, cp->tor->blockCount - 1 ) )
    190     {
    191         tr_block_index_t i;
    192         tr_cpReset( cp );
    193         for( i = 0; i < cp->tor->blockCount; ++i )
    194             if( tr_bitfieldHasFast( bitfield, i ) )
    195                 tr_cpBlockAdd( cp, i );
    196         success = TRUE;
    197     }
    198 
    199     return success;
    200 }
    201 
    202 #if 0
    203 int
     179tr_bool
    204180tr_cpBlockBitfieldSet( tr_completion * cp, tr_bitfield * blockBitfield )
    205181{
     
    209185    assert( blockBitfield );
    210186
    211     if(( success = tr_bitfieldTestFast( blockBitfield, cp->tor->blockCount - 1 )))
    212     {
    213         tr_piece_index_t p;
    214         const tr_torrent * tor = cp->tor;
     187    if(( success = blockBitfield->byteCount == cp->blockBitfield.byteCount ))
     188    {
     189        tr_block_index_t b = 0;
     190        tr_piece_index_t p = 0;
     191        uint32_t pieceBlock = 0;
     192        uint32_t completeBlocksInPiece = 0;
     193        tr_block_index_t completeBlocksInTorrent = 0;
     194        uint32_t blocksInCurrentPiece = tr_torPieceCountBlocks( cp->tor, p );
     195
     196        assert( blockBitfield->byteCount == cp->blockBitfield.byteCount );
    215197
    216198        tr_cpReset( cp );
    217199
    218         for( p=0; p<tor->info.pieceCount; ++p )
     200        cp->sizeWhenDoneIsDirty = TRUE;
     201        cp->haveValidIsDirty = TRUE;
     202        memcpy( cp->blockBitfield.bits, blockBitfield->bits, blockBitfield->byteCount );
     203
     204        while( b < cp->tor->blockCount )
    219205        {
    220             tr_block_index_t i;
    221             uint16_t completeBlocksInPiece = 0;
    222 
    223             const tr_block_index_t start = tr_torPieceFirstBlock( tor, p );
    224             const tr_block_index_t end = start + tr_torPieceCountBlocks( tor, p );
    225 
    226             for( i=start; i!=end; ++i ) {
    227                 if( tr_bitfieldTestFast( blockBitfield, i ) ) {
     206            if( tr_bitfieldHasFast( blockBitfield, b ) )
     207                ++completeBlocksInPiece;
     208
     209            ++b;
     210            ++pieceBlock;
     211
     212            if( pieceBlock == blocksInCurrentPiece )
     213            {
     214                cp->completeBlocks[p] = completeBlocksInPiece;
     215
     216                completeBlocksInTorrent += completeBlocksInPiece;
     217
     218                if( completeBlocksInPiece == blocksInCurrentPiece )
     219                    tr_bitfieldAdd( &cp->pieceBitfield, p );
     220
     221                ++p;
     222                completeBlocksInPiece = 0;
     223                pieceBlock = 0;
     224                blocksInCurrentPiece = tr_torPieceCountBlocks( cp->tor, p );
     225            }
     226        }
     227
     228        /* update sizeNow */
     229        cp->sizeNow = completeBlocksInTorrent;
     230        cp->sizeNow *= tr_torBlockCountBytes( cp->tor, 0 );
     231        if( tr_bitfieldHasFast( &cp->blockBitfield, cp->tor->blockCount-1 ) ) {
     232            cp->sizeNow -= tr_torBlockCountBytes( cp->tor, 0 );
     233            cp->sizeNow += tr_torBlockCountBytes( cp->tor, cp->tor->blockCount-1 );
     234        }
     235
     236#if 1
     237#warning these checks are to see if the implementation is good, since getting this function wrong could make Transmission think their downloaded data has disappeared.  But they are also expensive, so this block should be turned off after the nightly build users had a chance to smoke out any errors.
     238        /**
     239        ***  correctness checks
     240        **/
     241        for( b=0; b<cp->tor->blockCount; ++b )
     242            assert( tr_bitfieldHasFast( blockBitfield, b ) == tr_bitfieldHasFast( &cp->blockBitfield, b ) );
     243
     244        assert( cp->sizeNow <= cp->tor->info.totalSize );
     245        for( p=0; p<cp->tor->info.pieceCount; ++p ) {
     246            const uint32_t blocksInCurrentPiece = tr_torPieceCountBlocks( cp->tor, p );
     247            const tr_block_index_t start = tr_torPieceFirstBlock( cp->tor, p );
     248            const tr_block_index_t end = start + tr_torPieceCountBlocks( cp->tor, p );
     249            uint32_t completeBlocksInPiece = 0;
     250
     251            assert( tr_bitfieldHasFast( &cp->pieceBitfield, p ) == ( blocksInCurrentPiece == cp->completeBlocks[p] ) );
     252
     253            for( b=start; b<end; ++b )
     254                if( tr_bitfieldHasFast( &cp->blockBitfield, b ) )
    228255                    ++completeBlocksInPiece;
    229                     cp->sizeNow += tr_torBlockCountBytes( tor, i );
    230                 }
    231             }
    232 
    233             cp->completeBlocks[p] = completeBlocksInPiece;
    234 
    235             if( completeBlocksInPiece == end - start )
    236                 tr_bitfieldAdd( &cp->pieceBitfield, p );
     256            assert( completeBlocksInPiece == cp->completeBlocks[p] );
    237257        }
    238 
    239         memcpy( cp->blockBitfield.bits, blockBitfield->bits, cp->blockBitfield.byteCount );
    240 
    241         cp->haveValidIsDirty = 1;
    242         cp->sizeWhenDoneIsDirty = 1;
     258#endif
    243259    }
    244260
    245261    return success;
    246262}
    247 #endif
    248263
    249264/***
     
    323338
    324339
    325 int
     340tr_bool
    326341tr_cpPieceIsComplete( const tr_completion * cp, tr_piece_index_t piece )
    327342{
  • trunk/libtransmission/completion.h

    r7578 r7631  
    132132                               tr_piece_index_t       piece );
    133133
    134 int    tr_cpPieceIsComplete( const tr_completion * cp,
    135                              tr_piece_index_t      piece );
     134tr_bool  tr_cpPieceIsComplete( const tr_completion * cp,
     135                               tr_piece_index_t      piece );
    136136
    137137void   tr_cpPieceAdd( tr_completion    * completion,
     
    149149}
    150150
    151 void                       tr_cpBlockAdd( tr_completion * completion,
    152                                           tr_block_index_t block );
     151void      tr_cpBlockAdd( tr_completion * completion,
     152                         tr_block_index_t block );
    153153
    154 int                        tr_cpBlockBitfieldSet( tr_completion      * completion,
    155                                                   struct tr_bitfield * blocks );
     154tr_bool   tr_cpBlockBitfieldSet( tr_completion      * completion,
     155                                 struct tr_bitfield * blocks );
    156156
    157157/***
Note: See TracChangeset for help on using the changeset viewer.