(trunk libT) more heap pruning: avoid four unnecessary malloc() + free() calls per tr_peer.
This commit also changes tr_recentHistory from being a general-purpose tool to being a little more hardcoded for the only purpose it's used, in tr_peerMgr. If its files (history.[ch]) don't find any other "customers" in libtransmission, eventually it should be demoted to being a private helper class inside of peer-mgr.c and have the history.[ch] files removed from the build.
This commit is contained in:
parent
0a0bf016b1
commit
712ee263de
|
@ -1,4 +1,5 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h> /* memset() */
|
||||||
|
|
||||||
#include "transmission.h"
|
#include "transmission.h"
|
||||||
#include "history.h"
|
#include "history.h"
|
||||||
|
@ -34,7 +35,8 @@ test1( void )
|
||||||
{
|
{
|
||||||
tr_recentHistory h;
|
tr_recentHistory h;
|
||||||
|
|
||||||
tr_historyConstruct( &h, 60, 10 );
|
memset( &h, 0, sizeof( tr_recentHistory ) );
|
||||||
|
|
||||||
tr_historyAdd( &h, 10000, 1 );
|
tr_historyAdd( &h, 10000, 1 );
|
||||||
check( (int)tr_historyGet( &h, 12000, 1000 ) == 0 )
|
check( (int)tr_historyGet( &h, 12000, 1000 ) == 0 )
|
||||||
check( (int)tr_historyGet( &h, 12000, 3000 ) == 1 )
|
check( (int)tr_historyGet( &h, 12000, 3000 ) == 1 )
|
||||||
|
@ -44,7 +46,6 @@ test1( void )
|
||||||
check( (int)tr_historyGet( &h, 22000, 3000 ) == 1 )
|
check( (int)tr_historyGet( &h, 22000, 3000 ) == 1 )
|
||||||
check( (int)tr_historyGet( &h, 22000, 15000 ) == 2 )
|
check( (int)tr_historyGet( &h, 22000, 15000 ) == 2 )
|
||||||
check( (int)tr_historyGet( &h, 22000, 20000 ) == 2 )
|
check( (int)tr_historyGet( &h, 22000, 20000 ) == 2 )
|
||||||
tr_historyDestruct( &h );
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,10 +20,10 @@
|
||||||
void
|
void
|
||||||
tr_historyAdd( tr_recentHistory * h, time_t now, unsigned int n )
|
tr_historyAdd( tr_recentHistory * h, time_t now, unsigned int n )
|
||||||
{
|
{
|
||||||
if( h->slices[h->newest].date + (time_t)h->precision >= now )
|
if( h->slices[h->newest].date == now )
|
||||||
h->slices[h->newest].n += n;
|
h->slices[h->newest].n += n;
|
||||||
else {
|
else {
|
||||||
if( ++h->newest == h->sliceCount ) h->newest = 0;
|
if( ++h->newest == TR_RECENT_HISTORY_PERIOD_SEC ) h->newest = 0;
|
||||||
h->slices[h->newest].date = now;
|
h->slices[h->newest].date = now;
|
||||||
h->slices[h->newest].n = n;
|
h->slices[h->newest].n = n;
|
||||||
}
|
}
|
||||||
|
@ -43,27 +43,9 @@ tr_historyGet( const tr_recentHistory * h, time_t now, unsigned int sec )
|
||||||
|
|
||||||
n += h->slices[i].n;
|
n += h->slices[i].n;
|
||||||
|
|
||||||
if( --i == -1 ) i = h->sliceCount - 1; /* circular history */
|
if( --i == -1 ) i = TR_RECENT_HISTORY_PERIOD_SEC - 1; /* circular history */
|
||||||
if( i == h->newest ) break; /* we've come all the way around */
|
if( i == h->newest ) break; /* we've come all the way around */
|
||||||
}
|
}
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
tr_historyConstruct( tr_recentHistory * h, unsigned int seconds, unsigned int precision )
|
|
||||||
{
|
|
||||||
memset( h, 0, sizeof( tr_recentHistory ) );
|
|
||||||
|
|
||||||
assert( precision <= seconds );
|
|
||||||
|
|
||||||
h->precision = precision;
|
|
||||||
h->sliceCount = seconds / precision;
|
|
||||||
h->slices = tr_new0( struct tr_history_slice, h->sliceCount );
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
tr_historyDestruct( tr_recentHistory * h )
|
|
||||||
{
|
|
||||||
tr_free( h->slices );
|
|
||||||
}
|
|
||||||
|
|
|
@ -25,33 +25,26 @@
|
||||||
* to estimate the speed over the last N seconds.
|
* to estimate the speed over the last N seconds.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct tr_history_slice
|
enum
|
||||||
{
|
{
|
||||||
unsigned int n;
|
TR_RECENT_HISTORY_PERIOD_SEC = 60
|
||||||
time_t date;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef struct tr_recentHistory
|
typedef struct tr_recentHistory
|
||||||
{
|
{
|
||||||
/* these are PRIVATE IMPLEMENTATION details included for composition only.
|
/* these are PRIVATE IMPLEMENTATION details included for composition only.
|
||||||
* Don't access these directly! */
|
* Don't access these directly! */
|
||||||
|
|
||||||
int newest;
|
int newest;
|
||||||
int sliceCount;
|
|
||||||
unsigned int precision;
|
struct {
|
||||||
struct tr_history_slice * slices;
|
unsigned int n;
|
||||||
|
time_t date;
|
||||||
|
} slices[TR_RECENT_HISTORY_PERIOD_SEC];
|
||||||
}
|
}
|
||||||
tr_recentHistory;
|
tr_recentHistory;
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief construct a new tr_recentHistory object
|
|
||||||
* @param seconds how many seconds of history this object should remember
|
|
||||||
* @param precision how precise the history should be, in seconds
|
|
||||||
* For a precision of 10 seconds and a history of 2 minutes, makes 12 bins.
|
|
||||||
*/
|
|
||||||
void tr_historyConstruct( tr_recentHistory *, unsigned int seconds, unsigned int precision );
|
|
||||||
|
|
||||||
/** @brief destruct an existing tr_recentHistory object. */
|
|
||||||
void tr_historyDestruct( tr_recentHistory * );
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief add a counter to the recent history object.
|
* @brief add a counter to the recent history object.
|
||||||
* @param when the current time in sec, such as from tr_time()
|
* @param when the current time in sec, such as from tr_time()
|
||||||
|
|
|
@ -375,11 +375,6 @@ tr_peerConstruct( tr_peer * peer )
|
||||||
memset( peer, 0, sizeof( tr_peer ) );
|
memset( peer, 0, sizeof( tr_peer ) );
|
||||||
|
|
||||||
peer->have = TR_BITFIELD_INIT;
|
peer->have = TR_BITFIELD_INIT;
|
||||||
|
|
||||||
tr_historyConstruct( &peer->blocksSentToClient, CANCEL_HISTORY_SEC, ( RECHOKE_PERIOD_MSEC / 1000 ) );
|
|
||||||
tr_historyConstruct( &peer->blocksSentToPeer, CANCEL_HISTORY_SEC, ( RECHOKE_PERIOD_MSEC / 1000 ) );
|
|
||||||
tr_historyConstruct( &peer->cancelsSentToClient, CANCEL_HISTORY_SEC, ( RECHOKE_PERIOD_MSEC / 1000 ) );
|
|
||||||
tr_historyConstruct( &peer->cancelsSentToPeer, CANCEL_HISTORY_SEC, ( REFILL_UPKEEP_PERIOD_MSEC / 1000 ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static tr_peer*
|
static tr_peer*
|
||||||
|
@ -431,11 +426,6 @@ tr_peerDestruct( tr_torrent * tor, tr_peer * peer )
|
||||||
tr_peerIoUnref( peer->io ); /* balanced by the ref in handshakeDoneCB() */
|
tr_peerIoUnref( peer->io ); /* balanced by the ref in handshakeDoneCB() */
|
||||||
}
|
}
|
||||||
|
|
||||||
tr_historyDestruct( &peer->blocksSentToClient );
|
|
||||||
tr_historyDestruct( &peer->blocksSentToPeer );
|
|
||||||
tr_historyDestruct( &peer->cancelsSentToClient );
|
|
||||||
tr_historyDestruct( &peer->cancelsSentToPeer );
|
|
||||||
|
|
||||||
tr_bitfieldDestruct( &peer->have );
|
tr_bitfieldDestruct( &peer->have );
|
||||||
tr_bitfieldDestruct( &peer->blame );
|
tr_bitfieldDestruct( &peer->blame );
|
||||||
tr_free( peer->client );
|
tr_free( peer->client );
|
||||||
|
|
Loading…
Reference in New Issue