mirror of
https://github.com/transmission/transmission
synced 2024-12-26 01:27:28 +00:00
(trunk libT) #4336 "availablility nonsense" -- fix bug in tr_cpMissingBytesInPiece() introduced last week by r12515 for #4332. Add assertions to the nightly build to watch for regressions of this fix.
The bug was that I fixed #4332's off-by-one improperly in tr_cpMissingBlocksInPiece(). The piece's last block has to be calculated separately because its byte size may be different than the other blocks, The mistake in r12515 was that the last block could wind up being counted twice.
This commit is contained in:
parent
5f5cc9b533
commit
fdec244f04
3 changed files with 19 additions and 5 deletions
|
@ -10,6 +10,8 @@
|
||||||
* $Id$
|
* $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include "transmission.h"
|
#include "transmission.h"
|
||||||
#include "completion.h"
|
#include "completion.h"
|
||||||
#include "torrent.h"
|
#include "torrent.h"
|
||||||
|
@ -213,12 +215,19 @@ tr_cpMissingBytesInPiece( const tr_completion * cp, tr_piece_index_t piece )
|
||||||
else {
|
else {
|
||||||
size_t haveBytes = 0;
|
size_t haveBytes = 0;
|
||||||
tr_block_index_t f, l;
|
tr_block_index_t f, l;
|
||||||
|
const size_t pieceByteSize = tr_torPieceCountBytes( cp->tor, piece );
|
||||||
tr_torGetPieceBlockRange( cp->tor, piece, &f, &l );
|
tr_torGetPieceBlockRange( cp->tor, piece, &f, &l );
|
||||||
haveBytes = tr_bitfieldCountRange( &cp->blockBitfield, f, l+1 );
|
if( f != l ) {
|
||||||
haveBytes *= cp->tor->blockSize;
|
/* nb: we don't pass the usual l+1 here to tr_bitfieldCountRange().
|
||||||
if( tr_bitfieldHas( &cp->blockBitfield, l ) )
|
It's faster to handle the last block separately because its size
|
||||||
|
needs to be checked separately. */
|
||||||
|
haveBytes = tr_bitfieldCountRange( &cp->blockBitfield, f, l );
|
||||||
|
haveBytes *= cp->tor->blockSize;
|
||||||
|
}
|
||||||
|
if( tr_bitfieldHas( &cp->blockBitfield, l ) ) /* handle the last block */
|
||||||
haveBytes += tr_torBlockCountBytes( cp->tor, l );
|
haveBytes += tr_torBlockCountBytes( cp->tor, l );
|
||||||
return tr_torPieceCountBytes( cp->tor, piece ) - haveBytes;
|
assert( haveBytes <= pieceByteSize );
|
||||||
|
return pieceByteSize - haveBytes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2557,7 +2557,7 @@ peerIsSeed( const tr_peer * peer )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* count how many pieces we want that connected peers have */
|
/* count how many bytes we want that connected peers have */
|
||||||
uint64_t
|
uint64_t
|
||||||
tr_peerMgrGetDesiredAvailable( const tr_torrent * tor )
|
tr_peerMgrGetDesiredAvailable( const tr_torrent * tor )
|
||||||
{
|
{
|
||||||
|
@ -2594,6 +2594,7 @@ tr_peerMgrGetDesiredAvailable( const tr_torrent * tor )
|
||||||
if( !tor->info.pieces[i].dnd && ( t->pieceReplication[i] > 0 ) )
|
if( !tor->info.pieces[i].dnd && ( t->pieceReplication[i] > 0 ) )
|
||||||
desiredAvailable += tr_cpMissingBytesInPiece( &t->tor->completion, i );
|
desiredAvailable += tr_cpMissingBytesInPiece( &t->tor->completion, i );
|
||||||
|
|
||||||
|
assert( desiredAvailable <= tor->info.totalSize );
|
||||||
return desiredAvailable;
|
return desiredAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1261,6 +1261,10 @@ tr_torrentStat( tr_torrent * tor )
|
||||||
|
|
||||||
tr_torrentUnlock( tor );
|
tr_torrentUnlock( tor );
|
||||||
|
|
||||||
|
/* test some of the constraints */
|
||||||
|
assert( s->sizeWhenDone <= tor->info.totalSize );
|
||||||
|
assert( s->leftUntilDone <= s->sizeWhenDone );
|
||||||
|
assert( s->desiredAvailable <= s->leftUntilDone );
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue