mirror of
https://github.com/transmission/transmission
synced 2025-03-04 10:38:13 +00:00
(trunk libT) avoid some unnecessary memory fragmentation... for composited objects that have a tr_bitfield, contain it directly rather than a pointer to one allocated elsewhere on the heap.
This commit is contained in:
parent
427f639664
commit
7a4002dd3a
5 changed files with 54 additions and 42 deletions
|
@ -38,10 +38,10 @@ struct tr_completion
|
|||
tr_torrent * tor;
|
||||
|
||||
/* do we have this block? */
|
||||
tr_bitfield * blockBitfield;
|
||||
tr_bitfield blockBitfield;
|
||||
|
||||
/* do we have this piece? */
|
||||
tr_bitfield * pieceBitfield;
|
||||
tr_bitfield pieceBitfield;
|
||||
|
||||
/* a block is complete if and only if we have it */
|
||||
uint16_t * completeBlocks;
|
||||
|
@ -63,8 +63,8 @@ struct tr_completion
|
|||
static void
|
||||
tr_cpReset( tr_completion * cp )
|
||||
{
|
||||
tr_bitfieldClear( cp->pieceBitfield );
|
||||
tr_bitfieldClear( cp->blockBitfield );
|
||||
tr_bitfieldClear( &cp->pieceBitfield );
|
||||
tr_bitfieldClear( &cp->blockBitfield );
|
||||
memset( cp->completeBlocks, 0,
|
||||
sizeof( uint16_t ) * cp->tor->info.pieceCount );
|
||||
cp->sizeNow = 0;
|
||||
|
@ -78,9 +78,9 @@ tr_cpInit( tr_torrent * tor )
|
|||
tr_completion * cp = tr_new( tr_completion, 1 );
|
||||
|
||||
cp->tor = tor;
|
||||
cp->blockBitfield = tr_bitfieldNew( tor->blockCount );
|
||||
cp->pieceBitfield = tr_bitfieldNew( tor->info.pieceCount );
|
||||
cp->completeBlocks = tr_new( uint16_t, tor->info.pieceCount );
|
||||
tr_bitfieldConstruct( &cp->blockBitfield, tor->blockCount );
|
||||
tr_bitfieldConstruct( &cp->pieceBitfield, tor->info.pieceCount );
|
||||
tr_cpReset( cp );
|
||||
return cp;
|
||||
}
|
||||
|
@ -88,9 +88,9 @@ tr_cpInit( tr_torrent * tor )
|
|||
void
|
||||
tr_cpClose( tr_completion * cp )
|
||||
{
|
||||
tr_free ( cp->completeBlocks );
|
||||
tr_bitfieldFree( cp->pieceBitfield );
|
||||
tr_bitfieldFree( cp->blockBitfield );
|
||||
tr_free( cp->completeBlocks );
|
||||
tr_bitfieldDestruct( &cp->pieceBitfield );
|
||||
tr_bitfieldDestruct( &cp->blockBitfield );
|
||||
tr_free ( cp );
|
||||
}
|
||||
|
||||
|
@ -155,7 +155,7 @@ tr_cpPieceIsComplete( const tr_completion * cp,
|
|||
const tr_bitfield *
|
||||
tr_cpPieceBitfield( const tr_completion * cp )
|
||||
{
|
||||
return cp->pieceBitfield;
|
||||
return &cp->pieceBitfield;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -193,15 +193,15 @@ tr_cpPieceRem( tr_completion * cp,
|
|||
cp->sizeWhenDoneIsDirty = 1;
|
||||
cp->haveValidIsDirty = 1;
|
||||
cp->completeBlocks[piece] = 0;
|
||||
tr_bitfieldRemRange ( cp->blockBitfield, start, end );
|
||||
tr_bitfieldRem( cp->pieceBitfield, piece );
|
||||
tr_bitfieldRemRange ( &cp->blockBitfield, start, end );
|
||||
tr_bitfieldRem( &cp->pieceBitfield, piece );
|
||||
}
|
||||
|
||||
int
|
||||
tr_cpBlockIsComplete( const tr_completion * cp,
|
||||
tr_block_index_t block )
|
||||
{
|
||||
return tr_bitfieldHas( cp->blockBitfield, block );
|
||||
return tr_bitfieldHas( &cp->blockBitfield, block );
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -219,9 +219,9 @@ tr_cpBlockAdd( tr_completion * cp,
|
|||
++cp->completeBlocks[piece];
|
||||
|
||||
if( tr_cpPieceIsComplete( cp, piece ) )
|
||||
tr_bitfieldAdd( cp->pieceBitfield, piece );
|
||||
tr_bitfieldAdd( &cp->pieceBitfield, piece );
|
||||
|
||||
tr_bitfieldAdd( cp->blockBitfield, block );
|
||||
tr_bitfieldAdd( &cp->blockBitfield, block );
|
||||
|
||||
cp->sizeNow += blockSize;
|
||||
|
||||
|
@ -234,11 +234,10 @@ const tr_bitfield *
|
|||
tr_cpBlockBitfield( const tr_completion * cp )
|
||||
{
|
||||
assert( cp );
|
||||
assert( cp->blockBitfield );
|
||||
assert( cp->blockBitfield->bits );
|
||||
assert( cp->blockBitfield->bitCount );
|
||||
assert( cp->blockBitfield.bits );
|
||||
assert( cp->blockBitfield.bitCount );
|
||||
|
||||
return cp->blockBitfield;
|
||||
return &cp->blockBitfield;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -249,7 +248,6 @@ tr_cpBlockBitfieldSet( tr_completion * cp,
|
|||
|
||||
assert( cp );
|
||||
assert( bitfield );
|
||||
assert( cp->blockBitfield );
|
||||
|
||||
if( tr_bitfieldTestFast( bitfield, cp->tor->blockCount - 1 ) )
|
||||
{
|
||||
|
|
|
@ -537,7 +537,7 @@ torrentRealInit( tr_session * session,
|
|||
|
||||
tor->error = 0;
|
||||
|
||||
tor->checkedPieces = tr_bitfieldNew( tor->info.pieceCount );
|
||||
tr_bitfieldConstruct( &tor->checkedPieces, tor->info.pieceCount );
|
||||
tr_torrentUncheck( tor );
|
||||
|
||||
tor->addedDate = time( NULL ); /* this is a default value to be
|
||||
|
@ -1063,7 +1063,7 @@ freeTorrent( tr_torrent * tor )
|
|||
tr_trackerFree( tor->tracker );
|
||||
tor->tracker = NULL;
|
||||
|
||||
tr_bitfieldFree( tor->checkedPieces );
|
||||
tr_bitfieldDestruct( &tor->checkedPieces );
|
||||
|
||||
tr_free( tor->downloadDir );
|
||||
tr_free( tor->peer_id );
|
||||
|
@ -1601,7 +1601,7 @@ tr_bool
|
|||
tr_torrentIsPieceChecked( const tr_torrent * tor,
|
||||
tr_piece_index_t piece )
|
||||
{
|
||||
return tr_bitfieldHas( tor->checkedPieces, piece );
|
||||
return tr_bitfieldHas( &tor->checkedPieces, piece );
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1610,9 +1610,9 @@ tr_torrentSetPieceChecked( tr_torrent * tor,
|
|||
tr_bool isChecked )
|
||||
{
|
||||
if( isChecked )
|
||||
tr_bitfieldAdd( tor->checkedPieces, piece );
|
||||
tr_bitfieldAdd( &tor->checkedPieces, piece );
|
||||
else
|
||||
tr_bitfieldRem( tor->checkedPieces, piece );
|
||||
tr_bitfieldRem( &tor->checkedPieces, piece );
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1625,9 +1625,9 @@ tr_torrentSetFileChecked( tr_torrent * tor,
|
|||
const tr_piece_index_t end = file->lastPiece + 1;
|
||||
|
||||
if( isChecked )
|
||||
tr_bitfieldAddRange ( tor->checkedPieces, begin, end );
|
||||
tr_bitfieldAddRange ( &tor->checkedPieces, begin, end );
|
||||
else
|
||||
tr_bitfieldRemRange ( tor->checkedPieces, begin, end );
|
||||
tr_bitfieldRemRange ( &tor->checkedPieces, begin, end );
|
||||
}
|
||||
|
||||
tr_bool
|
||||
|
@ -1650,14 +1650,13 @@ tr_torrentIsFileChecked( const tr_torrent * tor,
|
|||
void
|
||||
tr_torrentUncheck( tr_torrent * tor )
|
||||
{
|
||||
tr_bitfieldRemRange ( tor->checkedPieces, 0, tor->info.pieceCount );
|
||||
tr_bitfieldRemRange ( &tor->checkedPieces, 0, tor->info.pieceCount );
|
||||
}
|
||||
|
||||
int
|
||||
tr_torrentCountUncheckedPieces( const tr_torrent * tor )
|
||||
{
|
||||
return tor->info.pieceCount - tr_bitfieldCountTrueBits(
|
||||
tor->checkedPieces );
|
||||
return tor->info.pieceCount - tr_bitfieldCountTrueBits( &tor->checkedPieces );
|
||||
}
|
||||
|
||||
time_t*
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#error only libtransmission should #include this header.
|
||||
#endif
|
||||
|
||||
#include "utils.h" /* tr_bitfield */
|
||||
|
||||
#ifndef TR_TORRENT_H
|
||||
#define TR_TORRENT_H 1
|
||||
|
||||
|
@ -205,7 +207,7 @@ struct tr_torrent
|
|||
|
||||
struct tr_completion * completion;
|
||||
|
||||
struct tr_bitfield * checkedPieces;
|
||||
struct tr_bitfield checkedPieces;
|
||||
tr_completeness completeness;
|
||||
|
||||
struct tr_tracker * tracker;
|
||||
|
|
|
@ -745,15 +745,25 @@ tr_strstrip( char * str )
|
|||
*****
|
||||
****/
|
||||
|
||||
tr_bitfield*
|
||||
tr_bitfieldConstruct( tr_bitfield * b, size_t bitCount )
|
||||
{
|
||||
b->bitCount = bitCount;
|
||||
b->byteCount = ( bitCount + 7u ) / 8u;
|
||||
b->bits = tr_new0( uint8_t, b->byteCount );
|
||||
return b;
|
||||
}
|
||||
|
||||
void
|
||||
tr_bitfieldDestruct( tr_bitfield * b )
|
||||
{
|
||||
tr_free( b->bits );
|
||||
}
|
||||
|
||||
tr_bitfield*
|
||||
tr_bitfieldNew( size_t bitCount )
|
||||
{
|
||||
tr_bitfield * ret = tr_new0( tr_bitfield, 1 );
|
||||
|
||||
ret->bitCount = bitCount;
|
||||
ret->byteCount = ( bitCount + 7u ) / 8u;
|
||||
ret->bits = tr_new0( uint8_t, ret->byteCount );
|
||||
return ret;
|
||||
return tr_bitfieldConstruct( tr_new0( tr_bitfield, 1 ), bitCount );
|
||||
}
|
||||
|
||||
tr_bitfield*
|
||||
|
@ -772,7 +782,7 @@ tr_bitfieldFree( tr_bitfield * bitfield )
|
|||
{
|
||||
if( bitfield )
|
||||
{
|
||||
tr_free( bitfield->bits );
|
||||
tr_bitfieldDestruct( bitfield );
|
||||
tr_free( bitfield );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -299,14 +299,17 @@ int tr_httpParseURL( const char * url,
|
|||
****
|
||||
***/
|
||||
|
||||
struct tr_bitfield
|
||||
typedef struct tr_bitfield
|
||||
{
|
||||
uint8_t * bits;
|
||||
size_t bitCount;
|
||||
size_t byteCount;
|
||||
};
|
||||
}
|
||||
tr_bitfield;
|
||||
|
||||
typedef struct tr_bitfield tr_bitfield;
|
||||
tr_bitfield* tr_bitfieldConstruct( tr_bitfield*, size_t bitcount );
|
||||
|
||||
void tr_bitfieldDestruct( tr_bitfield* );
|
||||
|
||||
tr_bitfield* tr_bitfieldNew( size_t bitcount ) TR_GNUC_MALLOC;
|
||||
|
||||
|
@ -346,7 +349,7 @@ tr_bitfield* tr_bitfieldOr( tr_bitfield*,
|
|||
need to call tr_bitfieldTestFast() first before you
|
||||
start looping. */
|
||||
#define tr_bitfieldHasFast( bitfield, nth ) \
|
||||
( ( bitfield->bits[( nth ) >> 3u] << ( ( nth ) & 7u ) & 0x80 ) != 0 )
|
||||
( ( (bitfield)->bits[( nth ) >> 3u] << ( ( nth ) & 7u ) & 0x80 ) != 0 )
|
||||
|
||||
/** @param high the highest nth bit you're going to access */
|
||||
#define tr_bitfieldTestFast( bitfield, high ) \
|
||||
|
|
Loading…
Add table
Reference in a new issue