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; tr_torrent * tor;
/* do we have this block? */ /* do we have this block? */
tr_bitfield * blockBitfield; tr_bitfield blockBitfield;
/* do we have this piece? */ /* do we have this piece? */
tr_bitfield * pieceBitfield; tr_bitfield pieceBitfield;
/* a block is complete if and only if we have it */ /* a block is complete if and only if we have it */
uint16_t * completeBlocks; uint16_t * completeBlocks;
@ -63,8 +63,8 @@ struct tr_completion
static void static void
tr_cpReset( tr_completion * cp ) tr_cpReset( tr_completion * cp )
{ {
tr_bitfieldClear( cp->pieceBitfield ); tr_bitfieldClear( &cp->pieceBitfield );
tr_bitfieldClear( cp->blockBitfield ); tr_bitfieldClear( &cp->blockBitfield );
memset( cp->completeBlocks, 0, memset( cp->completeBlocks, 0,
sizeof( uint16_t ) * cp->tor->info.pieceCount ); sizeof( uint16_t ) * cp->tor->info.pieceCount );
cp->sizeNow = 0; cp->sizeNow = 0;
@ -78,9 +78,9 @@ tr_cpInit( tr_torrent * tor )
tr_completion * cp = tr_new( tr_completion, 1 ); tr_completion * cp = tr_new( tr_completion, 1 );
cp->tor = tor; 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 ); 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 ); tr_cpReset( cp );
return cp; return cp;
} }
@ -89,8 +89,8 @@ void
tr_cpClose( tr_completion * cp ) tr_cpClose( tr_completion * cp )
{ {
tr_free( cp->completeBlocks ); tr_free( cp->completeBlocks );
tr_bitfieldFree( cp->pieceBitfield ); tr_bitfieldDestruct( &cp->pieceBitfield );
tr_bitfieldFree( cp->blockBitfield ); tr_bitfieldDestruct( &cp->blockBitfield );
tr_free ( cp ); tr_free ( cp );
} }
@ -155,7 +155,7 @@ tr_cpPieceIsComplete( const tr_completion * cp,
const tr_bitfield * const tr_bitfield *
tr_cpPieceBitfield( const tr_completion * cp ) tr_cpPieceBitfield( const tr_completion * cp )
{ {
return cp->pieceBitfield; return &cp->pieceBitfield;
} }
void void
@ -193,15 +193,15 @@ tr_cpPieceRem( tr_completion * cp,
cp->sizeWhenDoneIsDirty = 1; cp->sizeWhenDoneIsDirty = 1;
cp->haveValidIsDirty = 1; cp->haveValidIsDirty = 1;
cp->completeBlocks[piece] = 0; cp->completeBlocks[piece] = 0;
tr_bitfieldRemRange ( cp->blockBitfield, start, end ); tr_bitfieldRemRange ( &cp->blockBitfield, start, end );
tr_bitfieldRem( cp->pieceBitfield, piece ); tr_bitfieldRem( &cp->pieceBitfield, piece );
} }
int int
tr_cpBlockIsComplete( const tr_completion * cp, tr_cpBlockIsComplete( const tr_completion * cp,
tr_block_index_t block ) tr_block_index_t block )
{ {
return tr_bitfieldHas( cp->blockBitfield, block ); return tr_bitfieldHas( &cp->blockBitfield, block );
} }
void void
@ -219,9 +219,9 @@ tr_cpBlockAdd( tr_completion * cp,
++cp->completeBlocks[piece]; ++cp->completeBlocks[piece];
if( tr_cpPieceIsComplete( cp, 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; cp->sizeNow += blockSize;
@ -234,11 +234,10 @@ const tr_bitfield *
tr_cpBlockBitfield( const tr_completion * cp ) tr_cpBlockBitfield( const tr_completion * cp )
{ {
assert( cp ); assert( cp );
assert( cp->blockBitfield ); assert( cp->blockBitfield.bits );
assert( cp->blockBitfield->bits ); assert( cp->blockBitfield.bitCount );
assert( cp->blockBitfield->bitCount );
return cp->blockBitfield; return &cp->blockBitfield;
} }
int int
@ -249,7 +248,6 @@ tr_cpBlockBitfieldSet( tr_completion * cp,
assert( cp ); assert( cp );
assert( bitfield ); assert( bitfield );
assert( cp->blockBitfield );
if( tr_bitfieldTestFast( bitfield, cp->tor->blockCount - 1 ) ) if( tr_bitfieldTestFast( bitfield, cp->tor->blockCount - 1 ) )
{ {

View file

@ -537,7 +537,7 @@ torrentRealInit( tr_session * session,
tor->error = 0; tor->error = 0;
tor->checkedPieces = tr_bitfieldNew( tor->info.pieceCount ); tr_bitfieldConstruct( &tor->checkedPieces, tor->info.pieceCount );
tr_torrentUncheck( tor ); tr_torrentUncheck( tor );
tor->addedDate = time( NULL ); /* this is a default value to be tor->addedDate = time( NULL ); /* this is a default value to be
@ -1063,7 +1063,7 @@ freeTorrent( tr_torrent * tor )
tr_trackerFree( tor->tracker ); tr_trackerFree( tor->tracker );
tor->tracker = NULL; tor->tracker = NULL;
tr_bitfieldFree( tor->checkedPieces ); tr_bitfieldDestruct( &tor->checkedPieces );
tr_free( tor->downloadDir ); tr_free( tor->downloadDir );
tr_free( tor->peer_id ); tr_free( tor->peer_id );
@ -1601,7 +1601,7 @@ tr_bool
tr_torrentIsPieceChecked( const tr_torrent * tor, tr_torrentIsPieceChecked( const tr_torrent * tor,
tr_piece_index_t piece ) tr_piece_index_t piece )
{ {
return tr_bitfieldHas( tor->checkedPieces, piece ); return tr_bitfieldHas( &tor->checkedPieces, piece );
} }
void void
@ -1610,9 +1610,9 @@ tr_torrentSetPieceChecked( tr_torrent * tor,
tr_bool isChecked ) tr_bool isChecked )
{ {
if( isChecked ) if( isChecked )
tr_bitfieldAdd( tor->checkedPieces, piece ); tr_bitfieldAdd( &tor->checkedPieces, piece );
else else
tr_bitfieldRem( tor->checkedPieces, piece ); tr_bitfieldRem( &tor->checkedPieces, piece );
} }
void void
@ -1625,9 +1625,9 @@ tr_torrentSetFileChecked( tr_torrent * tor,
const tr_piece_index_t end = file->lastPiece + 1; const tr_piece_index_t end = file->lastPiece + 1;
if( isChecked ) if( isChecked )
tr_bitfieldAddRange ( tor->checkedPieces, begin, end ); tr_bitfieldAddRange ( &tor->checkedPieces, begin, end );
else else
tr_bitfieldRemRange ( tor->checkedPieces, begin, end ); tr_bitfieldRemRange ( &tor->checkedPieces, begin, end );
} }
tr_bool tr_bool
@ -1650,14 +1650,13 @@ tr_torrentIsFileChecked( const tr_torrent * tor,
void void
tr_torrentUncheck( tr_torrent * tor ) tr_torrentUncheck( tr_torrent * tor )
{ {
tr_bitfieldRemRange ( tor->checkedPieces, 0, tor->info.pieceCount ); tr_bitfieldRemRange ( &tor->checkedPieces, 0, tor->info.pieceCount );
} }
int int
tr_torrentCountUncheckedPieces( const tr_torrent * tor ) tr_torrentCountUncheckedPieces( const tr_torrent * tor )
{ {
return tor->info.pieceCount - tr_bitfieldCountTrueBits( return tor->info.pieceCount - tr_bitfieldCountTrueBits( &tor->checkedPieces );
tor->checkedPieces );
} }
time_t* time_t*

View file

@ -26,6 +26,8 @@
#error only libtransmission should #include this header. #error only libtransmission should #include this header.
#endif #endif
#include "utils.h" /* tr_bitfield */
#ifndef TR_TORRENT_H #ifndef TR_TORRENT_H
#define TR_TORRENT_H 1 #define TR_TORRENT_H 1
@ -205,7 +207,7 @@ struct tr_torrent
struct tr_completion * completion; struct tr_completion * completion;
struct tr_bitfield * checkedPieces; struct tr_bitfield checkedPieces;
tr_completeness completeness; tr_completeness completeness;
struct tr_tracker * tracker; 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_bitfield*
tr_bitfieldNew( size_t bitCount ) tr_bitfieldNew( size_t bitCount )
{ {
tr_bitfield * ret = tr_new0( tr_bitfield, 1 ); return tr_bitfieldConstruct( tr_new0( tr_bitfield, 1 ), bitCount );
ret->bitCount = bitCount;
ret->byteCount = ( bitCount + 7u ) / 8u;
ret->bits = tr_new0( uint8_t, ret->byteCount );
return ret;
} }
tr_bitfield* tr_bitfield*
@ -772,7 +782,7 @@ tr_bitfieldFree( tr_bitfield * bitfield )
{ {
if( bitfield ) if( bitfield )
{ {
tr_free( bitfield->bits ); tr_bitfieldDestruct( bitfield );
tr_free( 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; uint8_t * bits;
size_t bitCount; size_t bitCount;
size_t byteCount; 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; 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 need to call tr_bitfieldTestFast() first before you
start looping. */ start looping. */
#define tr_bitfieldHasFast( bitfield, nth ) \ #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 */ /** @param high the highest nth bit you're going to access */
#define tr_bitfieldTestFast( bitfield, high ) \ #define tr_bitfieldTestFast( bitfield, high ) \