mirror of
https://github.com/transmission/transmission
synced 2025-03-10 06:02:57 +00:00
(trunk libT) avoid some unnecessary memory fragmentation... for composited objects that have a tr_completion, contain the it directly rather than a pointer to one allocated elsewhere on the heap.
This commit is contained in:
parent
06d9314be4
commit
199e38dd66
11 changed files with 198 additions and 219 deletions
|
@ -30,36 +30,6 @@
|
|||
#include "torrent.h"
|
||||
#include "utils.h"
|
||||
|
||||
struct tr_completion
|
||||
{
|
||||
tr_bool sizeWhenDoneIsDirty;
|
||||
tr_bool haveValidIsDirty;
|
||||
|
||||
tr_torrent * tor;
|
||||
|
||||
/* do we have this block? */
|
||||
tr_bitfield blockBitfield;
|
||||
|
||||
/* do we have this piece? */
|
||||
tr_bitfield pieceBitfield;
|
||||
|
||||
/* a block is complete if and only if we have it */
|
||||
uint16_t * completeBlocks;
|
||||
|
||||
/* number of bytes we'll have when done downloading. [0..info.totalSize]
|
||||
DON'T access this directly; it's a lazy field.
|
||||
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;
|
||||
};
|
||||
|
||||
static void
|
||||
tr_cpReset( tr_completion * cp )
|
||||
{
|
||||
|
@ -73,11 +43,9 @@ tr_cpReset( tr_completion * cp )
|
|||
}
|
||||
|
||||
tr_completion *
|
||||
tr_cpInit( tr_torrent * tor )
|
||||
tr_cpConstruct( tr_completion * cp, tr_torrent * tor )
|
||||
{
|
||||
tr_completion * cp = tr_new( tr_completion, 1 );
|
||||
|
||||
cp->tor = tor;
|
||||
cp->tor = tor;
|
||||
cp->completeBlocks = tr_new( uint16_t, tor->info.pieceCount );
|
||||
tr_bitfieldConstruct( &cp->blockBitfield, tor->blockCount );
|
||||
tr_bitfieldConstruct( &cp->pieceBitfield, tor->info.pieceCount );
|
||||
|
@ -85,13 +53,13 @@ tr_cpInit( tr_torrent * tor )
|
|||
return cp;
|
||||
}
|
||||
|
||||
void
|
||||
tr_cpClose( tr_completion * cp )
|
||||
tr_completion*
|
||||
tr_cpDestruct( tr_completion * cp )
|
||||
{
|
||||
tr_free( cp->completeBlocks );
|
||||
tr_bitfieldDestruct( &cp->pieceBitfield );
|
||||
tr_bitfieldDestruct( &cp->blockBitfield );
|
||||
tr_free ( cp );
|
||||
return cp;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -145,19 +113,6 @@ tr_cpSizeWhenDone( const tr_completion * ccp )
|
|||
return ccp->sizeWhenDoneLazy;
|
||||
}
|
||||
|
||||
int
|
||||
tr_cpPieceIsComplete( const tr_completion * cp,
|
||||
tr_piece_index_t piece )
|
||||
{
|
||||
return cp->completeBlocks[piece] == tr_torPieceCountBlocks( cp->tor, piece );
|
||||
}
|
||||
|
||||
const tr_bitfield *
|
||||
tr_cpPieceBitfield( const tr_completion * cp )
|
||||
{
|
||||
return &cp->pieceBitfield;
|
||||
}
|
||||
|
||||
void
|
||||
tr_cpPieceAdd( tr_completion * cp,
|
||||
tr_piece_index_t piece )
|
||||
|
@ -197,13 +152,6 @@ tr_cpPieceRem( tr_completion * cp,
|
|||
tr_bitfieldRem( &cp->pieceBitfield, piece );
|
||||
}
|
||||
|
||||
int
|
||||
tr_cpBlockIsComplete( const tr_completion * cp,
|
||||
tr_block_index_t block )
|
||||
{
|
||||
return tr_bitfieldHas( &cp->blockBitfield, block );
|
||||
}
|
||||
|
||||
void
|
||||
tr_cpBlockAdd( tr_completion * cp,
|
||||
tr_block_index_t block )
|
||||
|
@ -230,16 +178,6 @@ tr_cpBlockAdd( tr_completion * cp,
|
|||
}
|
||||
}
|
||||
|
||||
const tr_bitfield *
|
||||
tr_cpBlockBitfield( const tr_completion * cp )
|
||||
{
|
||||
assert( cp );
|
||||
assert( cp->blockBitfield.bits );
|
||||
assert( cp->blockBitfield.bitCount );
|
||||
|
||||
return &cp->blockBitfield;
|
||||
}
|
||||
|
||||
int
|
||||
tr_cpBlockBitfieldSet( tr_completion * cp,
|
||||
tr_bitfield * bitfield )
|
||||
|
@ -262,41 +200,10 @@ tr_cpBlockBitfieldSet( tr_completion * cp,
|
|||
return success;
|
||||
}
|
||||
|
||||
int
|
||||
tr_cpMissingBlocksInPiece( const tr_completion * cp,
|
||||
tr_piece_index_t piece )
|
||||
{
|
||||
return tr_torPieceCountBlocks( cp->tor, piece ) - cp->completeBlocks[piece];
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
||||
float
|
||||
tr_cpPercentDone( const tr_completion * cp )
|
||||
{
|
||||
return tr_getRatio( cp->sizeNow, tr_cpSizeWhenDone( cp ) );
|
||||
}
|
||||
|
||||
float
|
||||
tr_cpPercentComplete( const tr_completion * cp )
|
||||
{
|
||||
return tr_getRatio( cp->sizeNow, cp->tor->info.totalSize );
|
||||
}
|
||||
|
||||
uint64_t
|
||||
tr_cpLeftUntilDone( const tr_completion * cp )
|
||||
{
|
||||
return tr_cpSizeWhenDone( cp ) - cp->sizeNow;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
tr_cpLeftUntilComplete( const tr_completion * cp )
|
||||
{
|
||||
return cp->tor->info.totalSize - cp->sizeNow;
|
||||
}
|
||||
|
||||
tr_completeness
|
||||
tr_cpGetStatus( const tr_completion * cp )
|
||||
{
|
||||
|
@ -338,12 +245,6 @@ tr_cpHaveValid( const tr_completion * ccp )
|
|||
return ccp->haveValidLazy;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
tr_cpHaveTotal( const tr_completion * cp )
|
||||
{
|
||||
return cp->sizeNow;
|
||||
}
|
||||
|
||||
void
|
||||
tr_cpGetAmountDone( const tr_completion * cp,
|
||||
float * tab,
|
||||
|
@ -352,7 +253,7 @@ tr_cpGetAmountDone( const tr_completion * cp,
|
|||
int i;
|
||||
const tr_torrent * tor = cp->tor;
|
||||
const float interval = tor->info.pieceCount / (float)tabCount;
|
||||
const int isSeed = tr_cpGetStatus ( tor->completion ) == TR_SEED;
|
||||
const int isSeed = tr_cpGetStatus( cp ) == TR_SEED;
|
||||
|
||||
for( i = 0; i < tabCount; ++i )
|
||||
{
|
||||
|
@ -367,3 +268,16 @@ tr_cpGetAmountDone( const tr_completion * cp,
|
|||
tr_torPieceCountBlocks( tor, piece );
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
tr_cpMissingBlocksInPiece( const tr_completion * cp, tr_piece_index_t piece )
|
||||
{
|
||||
return tr_torPieceCountBlocks( cp->tor, piece ) - cp->completeBlocks[piece];
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
tr_cpPieceIsComplete( const tr_completion * cp, tr_piece_index_t piece )
|
||||
{
|
||||
return cp->completeBlocks[piece] == tr_torPieceCountBlocks( cp->tor, piece );
|
||||
}
|
||||
|
|
|
@ -29,52 +29,124 @@
|
|||
#error only libtransmission should #include this header.
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "transmission.h"
|
||||
#include "utils.h" /* tr_bitfield */
|
||||
|
||||
struct tr_bitfield;
|
||||
typedef struct tr_completion tr_completion;
|
||||
typedef struct tr_completion
|
||||
{
|
||||
tr_bool sizeWhenDoneIsDirty;
|
||||
tr_bool haveValidIsDirty;
|
||||
|
||||
tr_completion * tr_cpInit( tr_torrent * );
|
||||
tr_torrent * tor;
|
||||
|
||||
void tr_cpClose( tr_completion * );
|
||||
/* do we have this block? */
|
||||
tr_bitfield blockBitfield;
|
||||
|
||||
/* General */
|
||||
/* do we have this piece? */
|
||||
tr_bitfield pieceBitfield;
|
||||
|
||||
/* a block is complete if and only if we have it */
|
||||
uint16_t * completeBlocks;
|
||||
|
||||
/* number of bytes we'll have when done downloading. [0..info.totalSize]
|
||||
DON'T access this directly; it's a lazy field.
|
||||
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;
|
||||
}
|
||||
tr_completion;
|
||||
|
||||
/**
|
||||
*** Life Cycle
|
||||
**/
|
||||
|
||||
tr_completion * tr_cpConstruct( tr_completion *, tr_torrent * );
|
||||
|
||||
tr_completion * tr_cpDestruct( tr_completion * );
|
||||
|
||||
static inline tr_completion* tr_cpNew( tr_torrent * tor )
|
||||
{
|
||||
return tr_cpConstruct( tr_new0( tr_completion, 1 ), tor );
|
||||
}
|
||||
|
||||
static inline void tr_cpFree( tr_completion * cp )
|
||||
{
|
||||
tr_free( tr_cpDestruct( cp ) );
|
||||
}
|
||||
|
||||
/**
|
||||
*** General
|
||||
**/
|
||||
|
||||
tr_completeness tr_cpGetStatus( const tr_completion * );
|
||||
|
||||
extern inline uint64_t tr_cpHaveTotal( const tr_completion * );
|
||||
|
||||
uint64_t tr_cpHaveValid( const tr_completion * );
|
||||
|
||||
extern inline uint64_t tr_cpLeftUntilComplete( const tr_completion * );
|
||||
|
||||
extern inline uint64_t tr_cpLeftUntilDone( const tr_completion * );
|
||||
|
||||
uint64_t tr_cpSizeWhenDone( const tr_completion * );
|
||||
|
||||
extern inline float tr_cpPercentComplete( const tr_completion * );
|
||||
|
||||
extern inline float tr_cpPercentDone( const tr_completion * );
|
||||
|
||||
void tr_cpInvalidateDND( tr_completion * );
|
||||
|
||||
void tr_cpGetAmountDone( const tr_completion * completion,
|
||||
float * tab,
|
||||
int tabCount );
|
||||
|
||||
/* Pieces */
|
||||
extern inline int tr_cpPieceIsComplete( const tr_completion * completion,
|
||||
tr_piece_index_t piece );
|
||||
static inline uint64_t tr_cpHaveTotal( const tr_completion * cp )
|
||||
{
|
||||
return cp->sizeNow;
|
||||
}
|
||||
|
||||
void tr_cpPieceAdd( tr_completion * completion,
|
||||
tr_piece_index_t piece );
|
||||
static inline uint64_t tr_cpLeftUntilComplete( const tr_completion * cp )
|
||||
{
|
||||
return tr_torrentInfo(cp->tor)->totalSize - cp->sizeNow;
|
||||
}
|
||||
|
||||
void tr_cpPieceRem( tr_completion * completion,
|
||||
tr_piece_index_t piece );
|
||||
static inline uint64_t tr_cpLeftUntilDone( const tr_completion * cp )
|
||||
{
|
||||
return tr_cpSizeWhenDone( cp ) - cp->sizeNow;
|
||||
}
|
||||
|
||||
/* Blocks */
|
||||
extern inline int tr_cpBlockIsComplete( const tr_completion * completion,
|
||||
tr_block_index_t block );
|
||||
static inline float tr_cpPercentComplete( const tr_completion * cp )
|
||||
{
|
||||
return tr_getRatio( cp->sizeNow, tr_torrentInfo(cp->tor)->totalSize );
|
||||
}
|
||||
|
||||
static inline float tr_cpPercentDone( const tr_completion * cp )
|
||||
{
|
||||
return tr_getRatio( cp->sizeNow, tr_cpSizeWhenDone( cp ) );
|
||||
}
|
||||
|
||||
/**
|
||||
*** Pieces
|
||||
**/
|
||||
|
||||
int tr_cpMissingBlocksInPiece( const tr_completion * cp,
|
||||
tr_piece_index_t piece );
|
||||
|
||||
int tr_cpPieceIsComplete( const tr_completion * cp,
|
||||
tr_piece_index_t piece );
|
||||
|
||||
void tr_cpPieceAdd( tr_completion * completion,
|
||||
tr_piece_index_t piece );
|
||||
|
||||
void tr_cpPieceRem( tr_completion * completion,
|
||||
tr_piece_index_t piece );
|
||||
|
||||
/**
|
||||
*** Blocks
|
||||
**/
|
||||
|
||||
static inline int tr_cpBlockIsComplete( const tr_completion * cp, tr_block_index_t block ) {
|
||||
return tr_bitfieldHas( &cp->blockBitfield, block );
|
||||
}
|
||||
|
||||
void tr_cpBlockAdd( tr_completion * completion,
|
||||
tr_block_index_t block );
|
||||
|
@ -82,14 +154,19 @@ void tr_cpBlockAdd( tr_completion * completion,
|
|||
int tr_cpBlockBitfieldSet( tr_completion * completion,
|
||||
struct tr_bitfield * blocks );
|
||||
|
||||
extern inline int tr_cpMissingBlocksInPiece( const tr_completion * completion,
|
||||
tr_piece_index_t piece );
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
||||
static inline const struct tr_bitfield * tr_cpPieceBitfield( const tr_completion * cp ) {
|
||||
return &cp->pieceBitfield;
|
||||
}
|
||||
|
||||
extern inline const struct tr_bitfield *
|
||||
tr_cpPieceBitfield( const tr_completion* );
|
||||
|
||||
extern inline const struct tr_bitfield *
|
||||
tr_cpBlockBitfield( const tr_completion * );
|
||||
static inline const struct tr_bitfield * tr_cpBlockBitfield( const tr_completion * cp ) {
|
||||
assert( cp );
|
||||
assert( cp->blockBitfield.bits );
|
||||
assert( cp->blockBitfield.bitCount );
|
||||
return &cp->blockBitfield;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -282,7 +282,7 @@ parseProgress( tr_torrent * tor,
|
|||
bitfield.byteCount = FR_BLOCK_BITFIELD_LEN( tor );
|
||||
bitfield.bitCount = bitfield.byteCount * 8;
|
||||
bitfield.bits = (uint8_t*) walk;
|
||||
if( tr_cpBlockBitfieldSet( tor->completion, &bitfield ) )
|
||||
if( tr_cpBlockBitfieldSet( &tor->completion, &bitfield ) )
|
||||
ret = TR_FR_PROGRESS;
|
||||
else {
|
||||
tr_torrentUncheck( tor );
|
||||
|
@ -296,7 +296,7 @@ parseProgress( tr_torrent * tor,
|
|||
tr_piece_index_t i;
|
||||
for( i = 0; i < tor->info.pieceCount; ++i )
|
||||
if( !tr_torrentIsPieceChecked( tor, i ) )
|
||||
tr_cpPieceRem( tor->completion, i );
|
||||
tr_cpPieceRem( &tor->completion, i );
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -628,7 +628,7 @@ getPreferredPieces( Torrent * t, tr_piece_index_t * pieceCount )
|
|||
/* make a list of the pieces that we want but don't have */
|
||||
for( i = 0; i < inf->pieceCount; ++i )
|
||||
if( !tor->info.pieces[i].dnd
|
||||
&& !tr_cpPieceIsComplete( tor->completion, i ) )
|
||||
&& !tr_cpPieceIsComplete( &tor->completion, i ) )
|
||||
pool[poolSize++] = i;
|
||||
|
||||
/* sort the pool by which to request next */
|
||||
|
@ -649,7 +649,7 @@ getPreferredPieces( Torrent * t, tr_piece_index_t * pieceCount )
|
|||
setme->random = tr_cryptoWeakRandInt( INT_MAX );
|
||||
setme->pendingRequestCount = getPieceRequests( t, piece );
|
||||
setme->missingBlockCount
|
||||
= tr_cpMissingBlocksInPiece( tor->completion, piece );
|
||||
= tr_cpMissingBlocksInPiece( &tor->completion, piece );
|
||||
|
||||
for( k = 0; k < peerCount; ++k )
|
||||
{
|
||||
|
@ -711,7 +711,7 @@ blockIteratorNext( struct tr_blockIterator * i, tr_block_index_t * setme )
|
|||
i->blockCount = 0;
|
||||
i->blockIndex = 0;
|
||||
for( block=b; block!=e; ++block )
|
||||
if( !tr_cpBlockIsComplete( tor->completion, block ) )
|
||||
if( !tr_cpBlockIsComplete( &tor->completion, block ) )
|
||||
i->blocks[i->blockCount++] = block;
|
||||
}
|
||||
|
||||
|
@ -1081,12 +1081,12 @@ peerCallbackFunc( void * vpeer, void * vevent, void * vt )
|
|||
|
||||
tr_block_index_t block = _tr_block( tor, e->pieceIndex, e->offset );
|
||||
|
||||
tr_cpBlockAdd( tor->completion, block );
|
||||
tr_cpBlockAdd( &tor->completion, block );
|
||||
decrementPieceRequests( t, e->pieceIndex );
|
||||
|
||||
broadcastGotBlock( t, e->pieceIndex, e->offset, e->length );
|
||||
|
||||
if( tr_cpPieceIsComplete( tor->completion, e->pieceIndex ) )
|
||||
if( tr_cpPieceIsComplete( &tor->completion, e->pieceIndex ) )
|
||||
{
|
||||
const tr_piece_index_t p = e->pieceIndex;
|
||||
const tr_bool ok = tr_ioTestPiece( tor, p, NULL, 0 );
|
||||
|
@ -1663,7 +1663,7 @@ tr_peerMgrTorrentAvailability( const tr_peerMgr * manager,
|
|||
t = getExistingTorrent( (tr_peerMgr*)manager, torrentHash );
|
||||
tor = t->tor;
|
||||
interval = tor->info.pieceCount / (float)tabCount;
|
||||
isSeed = tor && ( tr_cpGetStatus ( tor->completion ) == TR_SEED );
|
||||
isSeed = tor && ( tr_cpGetStatus ( &tor->completion ) == TR_SEED );
|
||||
peers = (const tr_peer **) TR_PTR_ARRAY_DATA( &t->peers );
|
||||
peerCount = TR_PTR_ARRAY_LENGTH( &t->peers );
|
||||
|
||||
|
@ -1673,7 +1673,7 @@ tr_peerMgrTorrentAvailability( const tr_peerMgr * manager,
|
|||
{
|
||||
const int piece = i * interval;
|
||||
|
||||
if( isSeed || tr_cpPieceIsComplete( tor->completion, piece ) )
|
||||
if( isSeed || tr_cpPieceIsComplete( &tor->completion, piece ) )
|
||||
tab[i] = -1;
|
||||
else if( peerCount ) {
|
||||
int j;
|
||||
|
@ -2074,10 +2074,10 @@ shouldPeerBeClosed( const Torrent * t,
|
|||
int peerHasEverything;
|
||||
if( atom->flags & ADDED_F_SEED_FLAG )
|
||||
peerHasEverything = TRUE;
|
||||
else if( peer->progress < tr_cpPercentDone( tor->completion ) )
|
||||
else if( peer->progress < tr_cpPercentDone( &tor->completion ) )
|
||||
peerHasEverything = FALSE;
|
||||
else {
|
||||
tr_bitfield * tmp = tr_bitfieldDup( tr_cpPieceBitfield( tor->completion ) );
|
||||
tr_bitfield * tmp = tr_bitfieldDup( tr_cpPieceBitfield( &tor->completion ) );
|
||||
tr_bitfieldDifference( tmp, peer->have );
|
||||
peerHasEverything = tr_bitfieldCountTrueBits( tmp ) == 0;
|
||||
tr_bitfieldFree( tmp );
|
||||
|
|
|
@ -717,7 +717,7 @@ isPieceInteresting( const tr_peermsgs * msgs,
|
|||
const tr_torrent * torrent = msgs->torrent;
|
||||
|
||||
return ( !torrent->info.pieces[piece].dnd ) /* we want it */
|
||||
&& ( !tr_cpPieceIsComplete( torrent->completion, piece ) ) /* !have */
|
||||
&& ( !tr_cpPieceIsComplete( &torrent->completion, piece ) ) /* !have */
|
||||
&& ( tr_bitfieldHas( msgs->peer->have, piece ) ); /* peer has it */
|
||||
}
|
||||
|
||||
|
@ -737,7 +737,7 @@ isPeerInteresting( const tr_peermsgs * msgs )
|
|||
return FALSE;
|
||||
|
||||
torrent = msgs->torrent;
|
||||
bitfield = tr_cpPieceBitfield( torrent->completion );
|
||||
bitfield = tr_cpPieceBitfield( &torrent->completion );
|
||||
|
||||
if( !msgs->peer->have )
|
||||
return TRUE;
|
||||
|
@ -926,7 +926,7 @@ pumpRequestQueue( tr_peermsgs * msgs, const time_t now )
|
|||
|
||||
/* don't ask for it if we've already got it... this block may have
|
||||
* come in from a different peer after we cancelled a request for it */
|
||||
if( !tr_cpBlockIsComplete( msgs->torrent->completion, block ) )
|
||||
if( !tr_cpBlockIsComplete( &msgs->torrent->completion, block ) )
|
||||
{
|
||||
protocolSendRequest( msgs, &req );
|
||||
req.time_requested = now;
|
||||
|
@ -1291,7 +1291,7 @@ peerMadeRequest( tr_peermsgs * msgs,
|
|||
{
|
||||
const tr_bool fext = tr_peerIoSupportsFEXT( msgs->peer->io );
|
||||
const int reqIsValid = requestIsValid( msgs, req );
|
||||
const int clientHasPiece = reqIsValid && tr_cpPieceIsComplete( msgs->torrent->completion, req->index );
|
||||
const int clientHasPiece = reqIsValid && tr_cpPieceIsComplete( &msgs->torrent->completion, req->index );
|
||||
const int peerIsChoked = msgs->peer->peerIsChoked;
|
||||
|
||||
int allow = FALSE;
|
||||
|
@ -1640,7 +1640,7 @@ clientGotBlock( tr_peermsgs * msgs,
|
|||
*** Error checks
|
||||
**/
|
||||
|
||||
if( tr_cpBlockIsComplete( tor->completion, block ) ) {
|
||||
if( tr_cpBlockIsComplete( &tor->completion, block ) ) {
|
||||
dbgmsg( msgs, "we have this block already..." );
|
||||
clientGotUnwantedBlock( msgs, req );
|
||||
return 0;
|
||||
|
@ -1752,7 +1752,7 @@ fillOutputBuffer( tr_peermsgs * msgs, time_t now )
|
|||
&& popNextRequest( msgs, &req ) )
|
||||
{
|
||||
if( requestIsValid( msgs, &req )
|
||||
&& tr_cpPieceIsComplete( msgs->torrent->completion, req.index ) )
|
||||
&& tr_cpPieceIsComplete( &msgs->torrent->completion, req.index ) )
|
||||
{
|
||||
int err;
|
||||
static uint8_t * buf = NULL;
|
||||
|
@ -1849,7 +1849,7 @@ sendBitfield( tr_peermsgs * msgs )
|
|||
size_t i;
|
||||
size_t lazyCount = 0;
|
||||
|
||||
field = tr_bitfieldDup( tr_cpPieceBitfield( msgs->torrent->completion ) );
|
||||
field = tr_bitfieldDup( tr_cpPieceBitfield( &msgs->torrent->completion ) );
|
||||
|
||||
if( tr_sessionIsLazyBitfieldEnabled( msgs->session ) )
|
||||
{
|
||||
|
@ -1898,11 +1898,11 @@ tellPeerWhatWeHave( tr_peermsgs * msgs )
|
|||
{
|
||||
const tr_bool fext = tr_peerIoSupportsFEXT( msgs->peer->io );
|
||||
|
||||
if( fext && ( tr_cpGetStatus( msgs->torrent->completion ) == TR_SEED ) )
|
||||
if( fext && ( tr_cpGetStatus( &msgs->torrent->completion ) == TR_SEED ) )
|
||||
{
|
||||
protocolSendHaveAll( msgs );
|
||||
}
|
||||
else if( fext && ( tr_cpHaveValid( msgs->torrent->completion ) == 0 ) )
|
||||
else if( fext && ( tr_cpHaveValid( &msgs->torrent->completion ) == 0 ) )
|
||||
{
|
||||
protocolSendHaveNone( msgs );
|
||||
}
|
||||
|
|
|
@ -308,7 +308,7 @@ saveProgress( tr_benc * dict,
|
|||
}
|
||||
|
||||
/* add the bitfield */
|
||||
bitfield = tr_cpBlockBitfield( tor->completion );
|
||||
bitfield = tr_cpBlockBitfield( &tor->completion );
|
||||
tr_bencDictAddRaw( p, KEY_PROGRESS_BITFIELD,
|
||||
bitfield->bits, bitfield->byteCount );
|
||||
|
||||
|
@ -376,7 +376,7 @@ loadProgress( tr_benc * dict,
|
|||
tmp.byteCount = rawlen;
|
||||
tmp.bitCount = tmp.byteCount * 8;
|
||||
tmp.bits = (uint8_t*) raw;
|
||||
if( !tr_cpBlockBitfieldSet( tor->completion, &tmp ) )
|
||||
if( !tr_cpBlockBitfieldSet( &tor->completion, &tmp ) )
|
||||
{
|
||||
tr_torrentUncheck( tor );
|
||||
tr_tordbg(
|
||||
|
|
|
@ -87,12 +87,6 @@ tr_torrentFindFromHashString( tr_session * session, const char * str )
|
|||
return NULL;
|
||||
}
|
||||
|
||||
tr_bool
|
||||
tr_torrentExists( const tr_session * session, const uint8_t * torrentHash )
|
||||
{
|
||||
return tr_torrentFindFromHash( (tr_session*)session, torrentHash ) != NULL;
|
||||
}
|
||||
|
||||
tr_torrent*
|
||||
tr_torrentFindFromHash( tr_session * session, const uint8_t * torrentHash )
|
||||
{
|
||||
|
@ -120,22 +114,6 @@ tr_torrentFindFromObfuscatedHash( tr_session * session,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/***
|
||||
**** LOCKS
|
||||
***/
|
||||
|
||||
void
|
||||
tr_torrentLock( const tr_torrent * tor )
|
||||
{
|
||||
tr_globalLock( tor->session );
|
||||
}
|
||||
|
||||
void
|
||||
tr_torrentUnlock( const tr_torrent * tor )
|
||||
{
|
||||
tr_globalUnlock( tor->session );
|
||||
}
|
||||
|
||||
/***
|
||||
**** PER-TORRENT UL / DL SPEEDS
|
||||
***/
|
||||
|
@ -519,7 +497,7 @@ torrentRealInit( tr_session * session,
|
|||
t += tor->blockCountInLastPiece;
|
||||
assert( t == (uint64_t)tor->blockCount );
|
||||
|
||||
tor->completion = tr_cpInit( tor );
|
||||
tr_cpConstruct( &tor->completion, tor );
|
||||
|
||||
tr_torrentInitFilePieces( tor );
|
||||
|
||||
|
@ -556,7 +534,7 @@ torrentRealInit( tr_session * session,
|
|||
TR_DOWN ) );
|
||||
}
|
||||
|
||||
tor->completeness = tr_cpGetStatus( tor->completion );
|
||||
tor->completeness = tr_cpGetStatus( &tor->completion );
|
||||
|
||||
tor->tracker = tr_trackerNew( tor );
|
||||
tor->trackerSubscription =
|
||||
|
@ -802,11 +780,11 @@ tr_torrentStat( tr_torrent * tor )
|
|||
|
||||
usableSeeds += tor->info.webseedCount;
|
||||
|
||||
s->percentComplete = tr_cpPercentComplete ( tor->completion );
|
||||
s->percentComplete = tr_cpPercentComplete ( &tor->completion );
|
||||
|
||||
s->percentDone = tr_cpPercentDone( tor->completion );
|
||||
s->leftUntilDone = tr_cpLeftUntilDone( tor->completion );
|
||||
s->sizeWhenDone = tr_cpSizeWhenDone( tor->completion );
|
||||
s->percentDone = tr_cpPercentDone ( &tor->completion );
|
||||
s->leftUntilDone = tr_cpLeftUntilDone( &tor->completion );
|
||||
s->sizeWhenDone = tr_cpSizeWhenDone ( &tor->completion );
|
||||
|
||||
s->recheckProgress = s->activity == TR_STATUS_CHECK
|
||||
? 1.0 -
|
||||
|
@ -824,8 +802,8 @@ tr_torrentStat( tr_torrent * tor )
|
|||
s->corruptEver = tor->corruptCur + tor->corruptPrev;
|
||||
s->downloadedEver = tor->downloadedCur + tor->downloadedPrev;
|
||||
s->uploadedEver = tor->uploadedCur + tor->uploadedPrev;
|
||||
s->haveValid = tr_cpHaveValid( tor->completion );
|
||||
s->haveUnchecked = tr_cpHaveTotal( tor->completion ) - s->haveValid;
|
||||
s->haveValid = tr_cpHaveValid( &tor->completion );
|
||||
s->haveUnchecked = tr_cpHaveTotal( &tor->completion ) - s->haveValid;
|
||||
|
||||
|
||||
if( usableSeeds > 0 )
|
||||
|
@ -846,8 +824,7 @@ tr_torrentStat( tr_torrent * tor )
|
|||
s->desiredAvailable = 0;
|
||||
for( i = 0; i < tor->info.pieceCount; ++i )
|
||||
if( !tor->info.pieces[i].dnd && tr_bitfieldHas( peerPieces, i ) )
|
||||
s->desiredAvailable += tr_cpMissingBlocksInPiece(
|
||||
tor->completion, i );
|
||||
s->desiredAvailable += tr_cpMissingBlocksInPiece( &tor->completion, i );
|
||||
s->desiredAvailable *= tor->blockSize;
|
||||
tr_bitfieldFree( peerPieces );
|
||||
}
|
||||
|
@ -903,21 +880,21 @@ fileBytesCompleted( const tr_torrent * tor,
|
|||
|
||||
if( firstBlock == lastBlock )
|
||||
{
|
||||
if( tr_cpBlockIsComplete( tor->completion, firstBlock ) )
|
||||
if( tr_cpBlockIsComplete( &tor->completion, firstBlock ) )
|
||||
haveBytes += lastBlockOffset + 1 - firstBlockOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
tr_block_index_t i;
|
||||
|
||||
if( tr_cpBlockIsComplete( tor->completion, firstBlock ) )
|
||||
if( tr_cpBlockIsComplete( &tor->completion, firstBlock ) )
|
||||
haveBytes += tor->blockSize - firstBlockOffset;
|
||||
|
||||
for( i = firstBlock + 1; i < lastBlock; ++i )
|
||||
if( tr_cpBlockIsComplete( tor->completion, i ) )
|
||||
if( tr_cpBlockIsComplete( &tor->completion, i ) )
|
||||
haveBytes += tor->blockSize;
|
||||
|
||||
if( tr_cpBlockIsComplete( tor->completion, lastBlock ) )
|
||||
if( tr_cpBlockIsComplete( &tor->completion, lastBlock ) )
|
||||
haveBytes += lastBlockOffset + 1;
|
||||
}
|
||||
|
||||
|
@ -1000,7 +977,7 @@ tr_torrentAmountFinished( const tr_torrent * tor,
|
|||
int size )
|
||||
{
|
||||
tr_torrentLock( tor );
|
||||
tr_cpGetAmountDone( tor->completion, tab, size );
|
||||
tr_cpGetAmountDone( &tor->completion, tab, size );
|
||||
tr_torrentUnlock( tor );
|
||||
}
|
||||
|
||||
|
@ -1030,9 +1007,9 @@ tr_torrentSetHasPiece( tr_torrent * tor,
|
|||
assert( pieceIndex < tor->info.pieceCount );
|
||||
|
||||
if( has )
|
||||
tr_cpPieceAdd( tor->completion, pieceIndex );
|
||||
tr_cpPieceAdd( &tor->completion, pieceIndex );
|
||||
else
|
||||
tr_cpPieceRem( tor->completion, pieceIndex );
|
||||
tr_cpPieceRem( &tor->completion, pieceIndex );
|
||||
|
||||
tr_torrentUnlock( tor );
|
||||
}
|
||||
|
@ -1055,7 +1032,7 @@ freeTorrent( tr_torrent * tor )
|
|||
|
||||
tr_peerMgrRemoveTorrent( session->peerMgr, tor->info.hash );
|
||||
|
||||
tr_cpClose( tor->completion );
|
||||
tr_cpDestruct( &tor->completion );
|
||||
|
||||
tr_rcClose( tor->swarmSpeed );
|
||||
|
||||
|
@ -1102,7 +1079,7 @@ checkAndStartImpl( void * vtor )
|
|||
tor->isRunning = 1;
|
||||
*tor->errorString = '\0';
|
||||
tr_torrentResetTransferStats( tor );
|
||||
tor->completeness = tr_cpGetStatus( tor->completion );
|
||||
tor->completeness = tr_cpGetStatus( &tor->completion );
|
||||
tr_torrentSaveResume( tor );
|
||||
tor->startDate = time( NULL );
|
||||
tr_trackerStart( tor->tracker );
|
||||
|
@ -1306,7 +1283,7 @@ tr_torrentRecheckCompleteness( tr_torrent * tor )
|
|||
|
||||
tr_torrentLock( tor );
|
||||
|
||||
completeness = tr_cpGetStatus( tor->completion );
|
||||
completeness = tr_cpGetStatus( &tor->completion );
|
||||
|
||||
if( completeness != tor->completeness )
|
||||
{
|
||||
|
@ -1499,7 +1476,7 @@ tr_torrentInitFileDLs( tr_torrent * tor,
|
|||
|
||||
for( i = 0; i < fileCount; ++i )
|
||||
setFileDND( tor, files[i], doDownload );
|
||||
tr_cpInvalidateDND ( tor->completion );
|
||||
tr_cpInvalidateDND ( &tor->completion );
|
||||
|
||||
tr_torrentUnlock( tor );
|
||||
}
|
||||
|
|
|
@ -26,11 +26,13 @@
|
|||
#error only libtransmission should #include this header.
|
||||
#endif
|
||||
|
||||
#include "utils.h" /* tr_bitfield */
|
||||
|
||||
#ifndef TR_TORRENT_H
|
||||
#define TR_TORRENT_H 1
|
||||
|
||||
#include "completion.h" /* tr_completion */
|
||||
#include "session.h" /* tr_globalLock(), tr_globalUnlock() */
|
||||
#include "utils.h" /* tr_bitfield */
|
||||
|
||||
struct tr_bandwidth;
|
||||
struct tr_ratecontrol;
|
||||
|
||||
|
@ -63,20 +65,10 @@ void tr_torrentSetHasPiece( tr_torrent * tor,
|
|||
tr_piece_index_t pieceIndex,
|
||||
tr_bool has );
|
||||
|
||||
extern inline void
|
||||
tr_torrentLock( const tr_torrent * session );
|
||||
|
||||
extern inline void
|
||||
tr_torrentUnlock( const tr_torrent * session );
|
||||
|
||||
tr_bool tr_torrentIsSeed( const tr_torrent * session );
|
||||
|
||||
void tr_torrentChangeMyPort( tr_torrent * session );
|
||||
|
||||
extern inline tr_bool
|
||||
tr_torrentExists( const tr_session * session,
|
||||
const uint8_t * hash );
|
||||
|
||||
tr_torrent* tr_torrentFindFromId( tr_session * session,
|
||||
int id );
|
||||
|
||||
|
@ -183,7 +175,7 @@ struct tr_torrent
|
|||
uint32_t blockCountInPiece;
|
||||
uint32_t blockCountInLastPiece;
|
||||
|
||||
struct tr_completion * completion;
|
||||
struct tr_completion completion;
|
||||
|
||||
struct tr_bitfield checkedPieces;
|
||||
tr_completeness completeness;
|
||||
|
@ -261,4 +253,23 @@ tr_torBlockCountBytes( const tr_torrent * tor, const tr_block_index_t block )
|
|||
: tor->blockSize;
|
||||
}
|
||||
|
||||
static inline void
|
||||
tr_torrentLock( const tr_torrent * tor )
|
||||
{
|
||||
tr_globalLock( tor->session );
|
||||
}
|
||||
|
||||
static inline void
|
||||
tr_torrentUnlock( const tr_torrent * tor )
|
||||
{
|
||||
tr_globalUnlock( tor->session );
|
||||
}
|
||||
|
||||
static inline tr_bool
|
||||
tr_torrentExists( const tr_session * session, const uint8_t * torrentHash )
|
||||
{
|
||||
return tr_torrentFindFromHash( (tr_session*)session, torrentHash ) != NULL;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -767,7 +767,7 @@ buildTrackerRequestURI( tr_tracker * t,
|
|||
torrent->uploadedCur,
|
||||
torrent->downloadedCur,
|
||||
torrent->corruptCur,
|
||||
tr_cpLeftUntilComplete( torrent->completion ),
|
||||
tr_cpLeftUntilComplete( &torrent->completion ),
|
||||
numwant,
|
||||
t->key_param );
|
||||
|
||||
|
@ -793,7 +793,7 @@ createRequest( tr_session * session,
|
|||
|
||||
/* BEP 21: In order to tell the tracker that a peer is a partial seed, it MUST send
|
||||
* an event=paused parameter in every announce while it is a partial seed. */
|
||||
if( tr_cpGetStatus( torrent->completion ) == TR_PARTIAL_SEED )
|
||||
if( tr_cpGetStatus( &torrent->completion ) == TR_PARTIAL_SEED )
|
||||
reqtype = TR_REQ_PAUSED;
|
||||
|
||||
isStopping = reqtype == TR_REQ_STOPPED;
|
||||
|
|
|
@ -826,7 +826,7 @@ uint64_t tr_torrentGetBytesLeftToAllocate( const tr_torrent * torrent );
|
|||
* between sessions. If you need that, use tr_info.hash or
|
||||
* tr_info.hashString.
|
||||
*/
|
||||
extern inline int tr_torrentId( const tr_torrent * torrent );
|
||||
int tr_torrentId( const tr_torrent * torrent );
|
||||
|
||||
/****
|
||||
***** Speed Limits
|
||||
|
|
|
@ -86,7 +86,7 @@ checkFile( tr_torrent * tor,
|
|||
}
|
||||
else if( !tr_torrentIsPieceChecked( tor, i ) )
|
||||
{
|
||||
const int wasComplete = tr_cpPieceIsComplete( tor->completion, i );
|
||||
const int wasComplete = tr_cpPieceIsComplete( &tor->completion, i );
|
||||
|
||||
if( tr_ioTestPiece( tor, i, buffer, buflen ) ) /* yay */
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue