1
0
Fork 0
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:
Charles Kerr 2008-12-29 09:51:54 +00:00
parent 427f639664
commit 7a4002dd3a
5 changed files with 54 additions and 42 deletions

View file

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

View file

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

View file

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

View file

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

View file

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