Changeset 2531


Ignore:
Timestamp:
Jul 28, 2007, 3:43:34 PM (14 years ago)
Author:
charles
Message:

a nice patch that makes the three most CPU-hogging functions (as reported by Shark) essentially free and reduces memory overhead by 8 bytes per piece per torrent. Lots of asserts for extra testing fun.

Location:
trunk/libtransmission
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/completion.c

    r2518 r2531  
    4141    /* a block is complete if and only if we have it */
    4242    uint16_t * completeBlocks;
     43
     44    uint8_t doneDirty;
     45    uint64_t doneHave;
     46    uint64_t doneTotal;
     47    uint64_t completeHave;
    4348};
    4449
     
    7681    tr_bitfieldClear( cp->pieceBitfield );
    7782    memset( cp->completeBlocks, 0, sizeof(uint16_t) * tor->info.pieceCount );
    78 }
    79 
    80 int tr_cpPieceHasAllBlocks( const tr_completion_t * cp, int piece )
    81 {
    82     return tr_cpPieceIsComplete( cp, piece );
    83 }
    84 
    85 int tr_cpPieceIsComplete( const tr_completion_t * cp, int piece )
    86 {
    87     return cp->completeBlocks[piece] >= TR_BLOCKS_IN_PIECE(cp->tor,piece);
    88 }
    89 
    90 const tr_bitfield_t * tr_cpPieceBitfield( const tr_completion_t * cp )
    91 {
    92     return cp->pieceBitfield;
    93 }
    94 
    95 void tr_cpPieceAdd( tr_completion_t * cp, int piece )
    96 {
    97     const tr_torrent_t * tor = cp->tor;
    98     const int n_blocks = TR_BLOCKS_IN_PIECE(tor,piece);
    99     const int startBlock = TOR_PIECE_FIRST_BLOCK(tor,piece);
    100     const int endBlock   = startBlock + n_blocks;
    101 
    102     cp->completeBlocks[piece] = n_blocks;
    103     tr_bitfieldAddRange( cp->blockBitfield, startBlock, endBlock );
    104     tr_bitfieldAdd( cp->pieceBitfield, piece );
    105 }
    106 
    107 void tr_cpPieceRem( tr_completion_t * cp, int piece )
    108 {
    109     const tr_torrent_t * tor = cp->tor;
    110     const int n_blocks = TR_BLOCKS_IN_PIECE(tor,piece);
    111     const int startBlock = TOR_PIECE_FIRST_BLOCK(tor,piece);
    112     const int endBlock   = startBlock + n_blocks;
    113 
    114     assert( cp != NULL );
    115     assert( 0 <= piece );
    116     assert( piece < tor->info.pieceCount );
    117     assert( 0 <= startBlock );
    118     assert( startBlock < tor->blockCount );
    119     assert( startBlock <= endBlock );
    120     assert( endBlock <= tor->blockCount );
    121 
    122     cp->completeBlocks[piece] = 0;
    123     tr_bitfieldRemRange ( cp->blockBitfield, startBlock, endBlock );
    124     tr_bitfieldRem( cp->pieceBitfield, piece );
    125 }
    126 
    127 /* Blocks */
    128 void tr_cpDownloaderAdd( tr_completion_t * cp, int block )
    129 {
    130     ++cp->blockDownloaders[block];
    131 }
    132 
    133 void tr_cpDownloaderRem( tr_completion_t * cp, int block )
    134 {
    135     --cp->blockDownloaders[block];
    136 }
    137 
    138 int tr_cpBlockIsComplete( const tr_completion_t * cp, int block )
    139 {
    140     return tr_bitfieldHas( cp->blockBitfield, block );
    141 }
    142 
    143 void tr_cpBlockAdd( tr_completion_t * cp, int block )
    144 {
    145     const tr_torrent_t * tor = cp->tor;
    146 
    147     if( !tr_cpBlockIsComplete( cp, block ) )
    148     {
    149         const int piece = TOR_BLOCK_PIECE(tor, block);
    150 
    151         ++cp->completeBlocks[piece];
    152 
    153         if( cp->completeBlocks[piece] == TR_BLOCKS_IN_PIECE(tor,piece) )
    154             tr_bitfieldAdd( cp->pieceBitfield, piece );
    155 
    156         tr_bitfieldAdd( cp->blockBitfield, block );
    157     }
    158 }
    159 
    160 const tr_bitfield_t * tr_cpBlockBitfield( const tr_completion_t * cp )
    161 {
    162     assert( cp != NULL );
    163 
    164     return cp->blockBitfield;
    165 }
    166 
    167 void
    168 tr_cpBlockBitfieldSet( tr_completion_t * cp, tr_bitfield_t * bitfield )
    169 {
    170     int i;
    171 
    172     assert( cp != NULL );
    173     assert( bitfield != NULL );
    174 
    175     tr_cpReset( cp );
    176 
    177     for( i=0; i < cp->tor->blockCount; ++i )
    178         if( tr_bitfieldHas( bitfield, i ) )
    179             tr_cpBlockAdd( cp, i );
    180 }
    181 
    182 float tr_cpPercentBlocksInPiece( const tr_completion_t * cp, int piece )
    183 {
    184     assert( cp != NULL );
    185 
    186     return cp->completeBlocks[piece] / (double)TR_BLOCKS_IN_PIECE(cp->tor,piece);
    187 }
    188 
    189 int
    190 tr_cpMissingBlocksForPiece( const tr_completion_t * cp, int piece )
    191 {
    192     int i;
    193     int n;
    194     const tr_torrent_t * tor = cp->tor;
    195     const int start = TOR_PIECE_FIRST_BLOCK(tor,piece);
    196     const int end   = start + TR_BLOCKS_IN_PIECE(tor,piece);
    197 
    198     n = 0;
    199     for( i = start; i < end; ++i )
    200         if( !tr_cpBlockIsComplete( cp, i ) && !cp->blockDownloaders[i] )
    201             ++n;
    202 
    203     return n;
    204 }
    205 
    206 int tr_cpMissingBlockInPiece( const tr_completion_t * cp, int piece )
    207 {
    208     int i;
    209     const tr_torrent_t * tor = cp->tor;
    210     const int start = TOR_PIECE_FIRST_BLOCK(tor,piece);
    211     const int end   = start + TR_BLOCKS_IN_PIECE(tor,piece);
    212 
    213     for( i = start; i < end; ++i )
    214         if( !tr_cpBlockIsComplete( cp, i ) && !cp->blockDownloaders[i] )
    215             return i;
    216 
    217     return -1;
    218 }
    219 
    220 /***
    221 ****
    222 ***/
    223 
    224 cp_status_t
    225 tr_cpGetStatus ( const tr_completion_t * cp )
    226 {
    227     int i;
    228     int ret = TR_CP_COMPLETE;
    229     const tr_info_t * info;
    230 
    231     assert( cp != NULL );
    232     assert( cp->tor != NULL );
    233 
    234     info = &cp->tor->info;
    235     for( i=0; i<info->pieceCount; ++i ) {
    236         if( tr_cpPieceIsComplete( cp, i ) )
    237             continue;
    238         if( !info->pieces[i].dnd )
    239             return TR_CP_INCOMPLETE;
    240         ret = TR_CP_DONE;
    241     }
    242 
    243     return ret;
    244 }
    245 
    246 uint64_t
    247 tr_cpLeftUntilComplete ( const tr_completion_t * cp )
    248 {
    249     int i;
    250     uint64_t b=0;
    251     const tr_torrent_t * tor;
    252     const tr_info_t * info;
    253 
    254     assert( cp != NULL );
    255     assert( cp->tor != NULL );
    256 
    257     tor = cp->tor;
    258     info = &tor->info;
    259     for( i=0; i<info->pieceCount; ++i )
    260         if( !tr_cpPieceIsComplete( cp, i ) )
    261             b += ( TR_BLOCKS_IN_PIECE(tor,i) - cp->completeBlocks[ i ] );
    262 
    263     b *= tor->blockSize;
    264 
    265     if( tor->blockCount && !tr_cpBlockIsComplete( cp, tor->blockCount - 1 ) )
    266           b -= (tor->blockSize - (tor->info.totalSize % tor->blockSize));
    267 
    268     return b;
    269 }
    270 
    271 void
    272 tr_cpDoneStats( const tr_completion_t  * cp ,
    273                 uint64_t               * setmeHaveBytes,
    274                 uint64_t               * setmeTotalBytes )
    275 {
    276     const tr_torrent_t * tor = cp->tor;
     83
     84    cp->doneDirty = TRUE;
     85    cp->doneHave = 0;
     86    cp->doneTotal = 0;
     87    cp->completeHave = 0;
     88}
     89
     90/**
     91***
     92**/
     93
     94static void
     95tr_cpEnsureDoneValid( const tr_completion_t * ccp )
     96{
     97    const tr_torrent_t * tor = ccp->tor;
    27798    const tr_info_t * info = &tor->info;
    27899    uint64_t have=0, total=0;
    279100    int i;
     101    tr_completion_t * cp ;
     102
     103    if( !ccp->doneDirty )
     104        return;
     105
     106    /* too bad C doesn't have 'mutable' */
     107    cp = (tr_completion_t*) ccp;
     108    cp->doneDirty = FALSE;
    280109
    281110    for( i=0; i<info->pieceCount; ++i ) {
     
    298127    assert( total <= info->totalSize );
    299128
    300     *setmeHaveBytes = have;
    301     *setmeTotalBytes = total;
    302 }
     129    cp->doneHave = have;
     130    cp->doneTotal = total;
     131}
     132
     133void
     134tr_cpInvalidateDND ( tr_completion_t * cp )
     135{
     136    cp->doneDirty = TRUE;
     137}
     138
     139int tr_cpPieceHasAllBlocks( const tr_completion_t * cp, int piece )
     140{
     141    return tr_cpPieceIsComplete( cp, piece );
     142}
     143
     144int tr_cpPieceIsComplete( const tr_completion_t * cp, int piece )
     145{
     146    return cp->completeBlocks[piece] >= tr_torPieceCountBlocks(cp->tor,piece);
     147}
     148
     149const tr_bitfield_t * tr_cpPieceBitfield( const tr_completion_t * cp )
     150{
     151    return cp->pieceBitfield;
     152}
     153
     154void tr_cpPieceAdd( tr_completion_t * cp, int piece )
     155{
     156    const tr_torrent_t * tor = cp->tor;
     157    const int start = tr_torPieceFirstBlock(tor,piece);
     158    const int end = start + tr_torPieceCountBlocks(tor,piece);
     159    int i;
     160
     161    for( i=start; i<end; ++i )
     162        tr_cpBlockAdd( cp, i );
     163}
     164
     165void tr_cpPieceRem( tr_completion_t * cp, int piece )
     166{
     167    const tr_torrent_t * tor = cp->tor;
     168    const int start = tr_torPieceFirstBlock(tor,piece);
     169    const int end = start + tr_torPieceCountBlocks(tor,piece);
     170    int block;
     171
     172    assert( cp != NULL );
     173    assert( 0 <= piece );
     174    assert( piece < tor->info.pieceCount );
     175    assert( 0 <= start );
     176    assert( start < tor->blockCount );
     177    assert( start <= end );
     178    assert( end <= tor->blockCount );
     179
     180    for( block=start; block<end; ++block ) {
     181        if( tr_cpBlockIsComplete( cp, block ) ) {
     182            const int blockSize = tr_torBlockCountBytes( tor, block );
     183            cp->completeHave -= blockSize;
     184            if( !tor->info.pieces[piece].dnd )
     185                cp->doneHave -= blockSize;
     186        }
     187    }
     188
     189    cp->completeBlocks[piece] = 0;
     190    tr_bitfieldRemRange ( cp->blockBitfield, start, end );
     191    tr_bitfieldRem( cp->pieceBitfield, piece );
     192}
     193
     194/* Blocks */
     195void tr_cpDownloaderAdd( tr_completion_t * cp, int block )
     196{
     197    ++cp->blockDownloaders[block];
     198}
     199
     200void tr_cpDownloaderRem( tr_completion_t * cp, int block )
     201{
     202    --cp->blockDownloaders[block];
     203}
     204
     205int tr_cpBlockIsComplete( const tr_completion_t * cp, int block )
     206{
     207    return tr_bitfieldHas( cp->blockBitfield, block );
     208}
     209
     210void
     211tr_cpBlockAdd( tr_completion_t * cp, int block )
     212{
     213    const tr_torrent_t * tor = cp->tor;
     214
     215    if( !tr_cpBlockIsComplete( cp, block ) )
     216    {
     217        const int piece = tr_torBlockPiece( tor, block );
     218        const int blockSize = tr_torBlockCountBytes( tor, block );
     219
     220        ++cp->completeBlocks[piece];
     221
     222        if( cp->completeBlocks[piece] == tr_torPieceCountBlocks( tor, piece ) )
     223            tr_bitfieldAdd( cp->pieceBitfield, piece );
     224
     225        tr_bitfieldAdd( cp->blockBitfield, block );
     226
     227        cp->completeHave += blockSize;
     228
     229        if( !tor->info.pieces[piece].dnd )
     230            cp->doneHave += blockSize;
     231    }
     232}
     233
     234const tr_bitfield_t * tr_cpBlockBitfield( const tr_completion_t * cp )
     235{
     236    assert( cp != NULL );
     237
     238    return cp->blockBitfield;
     239}
     240
     241void
     242tr_cpBlockBitfieldSet( tr_completion_t * cp, tr_bitfield_t * bitfield )
     243{
     244    int i;
     245
     246    assert( cp != NULL );
     247    assert( bitfield != NULL );
     248
     249    tr_cpReset( cp );
     250
     251    for( i=0; i < cp->tor->blockCount; ++i )
     252        if( tr_bitfieldHas( bitfield, i ) )
     253            tr_cpBlockAdd( cp, i );
     254}
     255
     256float tr_cpPercentBlocksInPiece( const tr_completion_t * cp, int piece )
     257{
     258    assert( cp != NULL );
     259
     260    return (double)cp->completeBlocks[piece] / tr_torPieceCountBlocks(cp->tor,piece);
     261}
     262
     263int
     264tr_cpMissingBlocksForPiece( const tr_completion_t * cp, int piece )
     265{
     266    int i;
     267    int n;
     268    const tr_torrent_t * tor = cp->tor;
     269    const int start = tr_torPieceFirstBlock(tor,piece);
     270    const int end   = start + tr_torPieceCountBlocks(tor,piece);
     271
     272    n = 0;
     273    for( i = start; i < end; ++i )
     274        if( !tr_cpBlockIsComplete( cp, i ) && !cp->blockDownloaders[i] )
     275            ++n;
     276
     277    return n;
     278}
     279
     280int tr_cpMissingBlockInPiece( const tr_completion_t * cp, int piece )
     281{
     282    int i;
     283    const tr_torrent_t * tor = cp->tor;
     284    const int start = tr_torPieceFirstBlock(tor,piece);
     285    const int end   = start + tr_torPieceCountBlocks(tor,piece);
     286
     287    for( i = start; i < end; ++i )
     288        if( !tr_cpBlockIsComplete( cp, i ) && !cp->blockDownloaders[i] )
     289            return i;
     290
     291    return -1;
     292}
     293
     294/***
     295****
     296***/
    303297
    304298float
    305299tr_cpPercentComplete ( const tr_completion_t * cp )
    306300{
    307     const uint64_t tilComplete = tr_cpLeftUntilComplete( cp );
    308     const uint64_t total = cp->tor->info.totalSize;
    309     const float f = 1.0 - (double)tilComplete / total;
    310     return MAX(0.0, f);
     301    return (double)cp->completeHave / cp->tor->info.totalSize;
     302}
     303
     304uint64_t
     305tr_cpLeftUntilComplete ( const tr_completion_t * cp )
     306{
     307    return cp->tor->info.totalSize - cp->completeHave;
     308}
     309
     310float
     311tr_cpPercentDone( const tr_completion_t * cp )
     312{
     313    tr_cpEnsureDoneValid( cp );
     314
     315    return (double)cp->doneHave / cp->doneTotal;
     316}
     317
     318uint64_t
     319tr_cpLeftUntilDone ( const tr_completion_t * cp )
     320{
     321    tr_cpEnsureDoneValid( cp );
     322
     323    return cp->doneTotal - cp->doneHave;
     324}
     325
     326cp_status_t
     327tr_cpGetStatus ( const tr_completion_t * cp )
     328{
     329    if( cp->completeHave >= cp->tor->info.totalSize )
     330        return TR_CP_COMPLETE;
     331
     332    tr_cpEnsureDoneValid( cp );
     333
     334    if( cp->doneHave >= cp->doneTotal )
     335        return TR_CP_DONE;
     336
     337    return TR_CP_INCOMPLETE;
    311338}
    312339
  • trunk/libtransmission/completion.h

    r2509 r2531  
    3535
    3636cp_status_t           tr_cpGetStatus ( const tr_completion_t * );
    37 
    3837uint64_t              tr_cpDownloadedValid( const tr_completion_t * );
    3938uint64_t              tr_cpLeftUntilComplete( const tr_completion_t * );
     39uint64_t              tr_cpLeftUntilDone( const tr_completion_t * );
    4040float                 tr_cpPercentComplete( const tr_completion_t * );
    41 void                  tr_cpDoneStats( const tr_completion_t  * cp,
    42                                       uint64_t               * setmeHaveBytes,
    43                                       uint64_t               * setmeTotalBytes );
    44 
     41float                 tr_cpPercentDone( const tr_completion_t * );
     42void                  tr_cpInvalidateDND ( tr_completion_t * );
    4543
    4644/* Pieces */
  • trunk/libtransmission/inout.c

    r2485 r2531  
    8282    assert ( 0<=pieceIndex && pieceIndex < info->pieceCount );
    8383    assert ( 0<=tor->info.pieceSize );
    84     assert ( pieceOffset < tr_pieceSize(pieceIndex) );
     84    assert ( pieceOffset < tr_torPieceCountBytes( tor, pieceIndex ) );
    8585    assert ( piecePos < info->totalSize );
    8686
     
    140140
    141141    assert( 0<=pieceIndex && pieceIndex<tor->info.pieceCount );
    142     assert( buflen <= (size_t) tr_pieceSize( pieceIndex ) );
     142    assert( buflen <= (size_t) tr_torPieceCountBytes( tor, pieceIndex ) );
    143143
    144144    findFileLocation ( tor, pieceIndex, pieceOffset, &fileIndex, &fileOffset );
     
    195195
    196196    info = &tor->info;
    197     n = tr_pieceSize( pieceIndex );
     197    n = tr_torPieceCountBytes( tor, pieceIndex );
    198198
    199199    buf = malloc( n );
  • trunk/libtransmission/internal.h

    r2525 r2531  
    122122void tr_torrentWriterUnlock  ( tr_torrent_t * );
    123123
    124 
    125 #define TOR_BLOCK_PIECE(tor,block) \
    126     ( (block) / ( (tor)->info.pieceSize / (tor)->blockSize ) )
    127 
    128 #define TOR_PIECE_FIRST_BLOCK(tor,piece) \
    129     ( (tor)->info.pieces[(piece)].firstBlock )
    130 
    131 #define TR_BLOCKS_IN_PIECE(tor,piece) \
    132     ( (tor)->info.pieces[(piece)].blockCount )
    133 
    134 #define tr_blockSize(a) _tr_blockSize(tor,a)
    135 int _tr_blockSize( const tr_torrent_t * tor, int block );
    136 
    137 #define tr_pieceSize(a) _tr_pieceSize(tor,a)
    138 int _tr_pieceSize( const tr_torrent_t * tor, int piece );
     124/* get the index of this piece's first block */
     125#define tr_torPieceFirstBlock(tor,piece) ( (piece) * (tor)->blockCountInPiece )
     126
     127/* what piece index is this block in? */
     128#define tr_torBlockPiece(tor,block) ( (block) / (tor)->blockCountInPiece )
     129
     130/* how many blocks are in this piece? */
     131#define tr_torPieceCountBlocks(tor,piece) \
     132    ( ((piece)==((tor)->info.pieceCount-1)) ? (tor)->blockCountInLastPiece : (tor)->blockCountInPiece )
     133
     134/* how many bytes are in this piece? */
     135#define tr_torPieceCountBytes(tor,piece) \
     136    ( ((piece)==((tor)->info.pieceCount-1)) ? (tor)->lastPieceSize : (tor)->info.pieceSize )
     137
     138/* how many bytes are in this block? */
     139#define tr_torBlockCountBytes(tor,block) \
     140    ( ((block)==((tor)->blockCount-1)) ? (tor)->lastBlockSize : (tor)->blockSize )
    139141
    140142#define tr_block(a,b) _tr_block(tor,a,b)
     
    185187    int               blockSize;
    186188    int               blockCount;
     189
     190    int               lastBlockSize;
     191    int               lastPieceSize;
     192
     193    int               blockCountInPiece;
     194    int               blockCountInLastPiece;
    187195   
    188196    tr_completion_t * completion;
  • trunk/libtransmission/peer.c

    r2503 r2531  
    690690            {
    691691                const int piece = pool[p];
    692                 const int firstBlock = TOR_PIECE_FIRST_BLOCK( tor, piece );
    693                 const int n = TR_BLOCKS_IN_PIECE( tor, piece );
     692                const int firstBlock = tr_torPieceFirstBlock( tor, piece );
     693                const int n = tr_torPieceCountBlocks( tor, piece );
    694694                const int end = firstBlock + n;
    695695                int block;
  • trunk/libtransmission/peermessages.h

    r2428 r2531  
    305305    r->begin  = ( block % ( inf->pieceSize / tor->blockSize ) ) *
    306306                    tor->blockSize;
    307     r->length = tr_blockSize( block );
     307    r->length = tr_torBlockCountBytes( tor, block );
    308308    (peer->inRequestCount)++;
    309309
  • trunk/libtransmission/peerparse.h

    r2496 r2531  
    224224        return TR_ERROR_ASSERT;
    225225    }
    226     if( tr_pieceSize( index ) < begin + length )
     226    if( tr_torPieceCountBytes( tor, index ) < begin + length )
    227227    {
    228228        peer_dbg( "GET  request, invalid begin/length" );
     
    302302        return TR_ERROR_ASSERT;
    303303    }
    304     if( tr_pieceSize( index ) < begin + len - 8 )
     304    if( tr_torPieceCountBytes( tor, index ) < begin + len - 8 )
    305305    {
    306306        peer_dbg( "GET  piece, invalid begin/length" );
     
    316316
    317317    /* Sanity checks */
    318     if( len - 8 != tr_blockSize( block ) )
    319     {
    320         peer_dbg( "wrong size (expecting %d)", tr_blockSize( block ) );
     318    if( len - 8 != tr_torBlockCountBytes( tor, block ) )
     319    {
     320        peer_dbg( "wrong size (expecting %d)", tr_torBlockCountBytes( tor, block ) );
    321321        return TR_ERROR_ASSERT;
    322322    }
     
    406406        return TR_ERROR_ASSERT;
    407407    }
    408     if( tr_pieceSize( index ) < begin + length )
     408    if( tr_torPieceCountBytes( tor, index ) < begin + length )
    409409    {
    410410        peer_dbg( "GET  cancel, invalid begin/length" );
  • trunk/libtransmission/torrent.c

    r2518 r2531  
    2323 *****************************************************************************/
    2424
     25#include <assert.h>
    2526#include <sys/types.h>
    2627#include <sys/socket.h>
     
    169170
    170171    for( i=0; i<tor->info.pieceCount; ++i )
    171     {
    172         tr_piece_t * piece = tor->info.pieces + i;
    173         uint64_t lastByte;
    174         int lastBlock;
    175         if( i == (tor->info.pieceCount-1))
    176             lastByte = tor->info.totalSize - 1;
    177         else {
    178             lastByte = i + 1;
    179             lastByte *= tor->info.pieceSize;
    180             --lastByte;
    181         }
    182         lastBlock = lastByte / tor->blockSize;
    183 
    184         piece->priority = calculatePiecePriority( tor, i );
    185         piece->firstBlock = i * (tor->info.pieceSize / tor->blockSize);
    186         piece->blockCount = lastBlock + 1 - piece->firstBlock;
    187 
    188         assert( 0 <= piece->firstBlock );
    189         assert( piece->firstBlock <= lastBlock );
    190         assert( lastBlock < tor->blockCount );
    191         assert( piece->firstBlock + piece->blockCount <= tor->blockCount );
    192     }
     172        tor->info.pieces[i].priority = calculatePiecePriority( tor, i );
    193173}
    194174
     
    203183    int i;
    204184    uint64_t loaded;
     185    uint64_t t;
    205186    char name[512];
    206187    tr_bitfield_t * uncheckedPieces;
     188    tr_info_t * info = &tor->info;
    207189   
    208190    tor->info.flags |= flags;
     
    227209    tor->pexDisabled = 0;
    228210
    229     /* Block size: usually 16 kib, or less if we have to */
    230     tor->blockSize  = MIN( tor->info.pieceSize, 1 << 14 );
    231     tor->blockCount = ( tor->info.totalSize + tor->blockSize - 1 ) /
    232                         tor->blockSize;
     211    /**
     212     * Decide on a block size.  constraints:
     213     * (1) most clients decline requests over 16 KiB
     214     * (2) pieceSize must be a multiple of block size
     215     */
     216    tor->blockSize = info->pieceSize;
     217    while( tor->blockSize > (1024*16) )
     218        tor->blockSize /= 2;
     219
     220    tor->lastPieceSize = info->totalSize % info->pieceSize;
     221
     222    tor->lastBlockSize = info->totalSize % tor->blockSize;
     223
     224    tor->blockCount =
     225        ( info->totalSize + tor->blockSize - 1 ) / tor->blockSize;
     226
     227    tor->blockCountInPiece =
     228        info->pieceSize / tor->blockSize;
     229
     230    tor->blockCountInLastPiece =
     231        ( tor->lastPieceSize + tor->blockSize - 1 ) / tor->blockSize;
     232
     233    /* check our work */
     234    assert( ( info->pieceSize % tor->blockSize ) == 0 );
     235    t = info->pieceCount - 1;
     236    t *= info->pieceSize;
     237    t += tor->lastPieceSize;
     238    assert( t == info->totalSize );
     239    t = tor->blockCount - 1;
     240    t *= tor->blockSize;
     241    t += tor->lastBlockSize;
     242    assert( t == info->totalSize );
     243    t = info->pieceCount - 1;
     244    t *= tor->blockCountInPiece;
     245    t += tor->blockCountInLastPiece;
     246    assert( t == (uint64_t)tor->blockCount );
     247
    233248    tor->completion = tr_cpInit( tor );
    234249
     
    597612    tr_tracker_t * tc;
    598613    int i;
    599     uint64_t doneHave, doneTotal;
    600614
    601615    tr_torrentReaderLock( tor );
     
    640654    s->percentComplete = tr_cpPercentComplete ( tor->completion );
    641655
    642     tr_cpDoneStats( tor->completion, &doneHave, &doneTotal );
    643     s->percentDone = (float)doneHave / (float)doneTotal;
    644     s->left = doneTotal - doneHave;
     656    s->percentDone = tr_cpPercentDone( tor->completion );
     657    s->left = tr_cpLeftUntilDone( tor->completion );
    645658
    646659    if( tor->uncheckedPieces )
     
    722735    assert( (int)lastBlock < tor->blockCount );
    723736    assert( firstBlock <= lastBlock );
    724     assert( (int)TOR_BLOCK_PIECE( tor, firstBlock ) == file->firstPiece );
    725     assert( (int)TOR_BLOCK_PIECE( tor, lastBlock ) == file->lastPiece );
     737    assert( (int)tr_torBlockPiece( tor, firstBlock ) == file->firstPiece );
     738    assert( (int)tr_torBlockPiece( tor, lastBlock ) == file->lastPiece );
    726739
    727740    if( firstBlock == lastBlock )
     
    13841397    }
    13851398
     1399    tr_cpInvalidateDND ( tor->completion );
     1400
    13861401    tor->fastResumeDirty = TRUE;
    13871402
     
    14041419***/
    14051420
    1406 int _tr_blockSize( const tr_torrent_t * tor, int block )
    1407 {
    1408     const tr_info_t * inf = &tor->info;
    1409     int dummy;
    1410 
    1411     if( block != tor->blockCount - 1 ||
    1412         !( dummy = inf->totalSize % tor->blockSize ) )
    1413     {
    1414         return tor->blockSize;
    1415     }
    1416 
    1417     return dummy;
    1418 }
    1419 
    1420 int _tr_pieceSize( const tr_torrent_t * tor, int piece )
    1421 {
    1422     const tr_info_t * inf = &tor->info;
    1423     if( piece < inf->pieceCount - 1 ||
    1424         !( inf->totalSize % inf->pieceSize ) )
    1425     {
    1426         return inf->pieceSize;
    1427     }
    1428     return inf->totalSize % inf->pieceSize;
    1429 }
    1430 
    14311421int _tr_block( const tr_torrent_t * tor, int index, int begin )
    14321422{
  • trunk/libtransmission/transmission.h

    r2488 r2531  
    516516    int8_t   priority;                 /* TR_PRI_HIGH, _NORMAL, or _LOW */
    517517    int8_t   dnd;                      /* nonzero if the piece shouldn't be downloaded */
    518     int      firstBlock;               /* this piece's first byte is in this block */
    519     int      blockCount;               /* number of blocks this piece is in */
    520518}
    521519tr_piece_t;
Note: See TracChangeset for help on using the changeset viewer.