(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:
Charles Kerr 2009-01-02 17:01:55 +00:00
parent 06d9314be4
commit 199e38dd66
11 changed files with 198 additions and 219 deletions

View File

@ -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 );
}

View File

@ -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

View File

@ -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;

View File

@ -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 );

View File

@ -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 );
}

View File

@ -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(

View File

@ -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 );
}

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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 */
{