If we use composition on these objects we can save a handful of pointers per peer. This isn't a big deal, but it's an easy/safe change to do.
static int
test1( void )
{
- tr_recentHistory * h;
-
- h = tr_historyNew( 60, 10 );
- tr_historyAdd( h, 10000, 1 );
- check( (int)tr_historyGet( h, 12000, 1000 ) == 0 )
- check( (int)tr_historyGet( h, 12000, 3000 ) == 1 )
- check( (int)tr_historyGet( h, 12000, 5000 ) == 1 )
- tr_historyAdd( h, 20000, 1 );
- check( (int)tr_historyGet( h, 22000, 1000 ) == 0 )
- check( (int)tr_historyGet( h, 22000, 3000 ) == 1 )
- check( (int)tr_historyGet( h, 22000, 15000 ) == 2 )
- check( (int)tr_historyGet( h, 22000, 20000 ) == 2 )
- tr_historyFree( h );
+ tr_recentHistory h;
+
+ tr_historyConstruct( &h, 60, 10 );
+ tr_historyAdd( &h, 10000, 1 );
+ check( (int)tr_historyGet( &h, 12000, 1000 ) == 0 )
+ check( (int)tr_historyGet( &h, 12000, 3000 ) == 1 )
+ check( (int)tr_historyGet( &h, 12000, 5000 ) == 1 )
+ tr_historyAdd( &h, 20000, 1 );
+ check( (int)tr_historyGet( &h, 22000, 1000 ) == 0 )
+ check( (int)tr_historyGet( &h, 22000, 3000 ) == 1 )
+ check( (int)tr_historyGet( &h, 22000, 15000 ) == 2 )
+ check( (int)tr_historyGet( &h, 22000, 20000 ) == 2 )
+ tr_historyDestruct( &h );
return 0;
}
#include "history.h"
#include "utils.h"
-struct history_slice
-{
- unsigned int n;
- time_t date;
-};
-
-struct tr_recentHistory
-{
- int newest;
- int sliceCount;
- unsigned int precision;
- struct history_slice * slices;
-};
-
void
tr_historyAdd( tr_recentHistory * h, time_t now, unsigned int n )
{
return n;
}
-tr_recentHistory *
-tr_historyNew( unsigned int seconds, unsigned int precision )
+void
+tr_historyConstruct( tr_recentHistory * h, unsigned int seconds, unsigned int precision )
{
- tr_recentHistory * h;
+ memset( h, 0, sizeof( tr_recentHistory ) );
assert( precision <= seconds );
- h = tr_new0( tr_recentHistory, 1 );
h->precision = precision;
h->sliceCount = seconds / precision;
- h->slices = tr_new0( struct history_slice, h->sliceCount );
-
- return h;
+ h->slices = tr_new0( struct tr_history_slice, h->sliceCount );
}
void
-tr_historyFree( tr_recentHistory * h )
+tr_historyDestruct( tr_recentHistory * h )
{
tr_free( h->slices );
- tr_free( h );
}
* For example, it could count how many are bytes transferred
* to estimate the speed over the last N seconds.
*/
-typedef struct tr_recentHistory tr_recentHistory;
+
+struct tr_history_slice
+{
+ unsigned int n;
+ time_t date;
+};
+typedef struct tr_recentHistory
+{
+ /* these are PRIVATE IMPLEMENTATION details included for composition only.
+ * Don't access these directly! */
+ int newest;
+ int sliceCount;
+ unsigned int precision;
+ struct tr_history_slice * slices;
+}
+tr_recentHistory;
/**
- * @brief create a new tr_recentHistory object.
+ * @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.
*/
-tr_recentHistory * tr_historyNew( unsigned int seconds, unsigned int precision );
+void tr_historyConstruct( tr_recentHistory *, unsigned int seconds, unsigned int precision );
-/** @brief destroy an existing tr_recentHistory object. */
-void tr_historyFree( tr_recentHistory * );
+/** @brief destruct an existing tr_recentHistory object. */
+void tr_historyDestruct( tr_recentHistory * );
/**
* @brief add a counter to the recent history object.
peer->atom = atom;
atom->peer = peer;
- peer->blocksSentToClient = tr_historyNew( CANCEL_HISTORY_SEC, ( RECHOKE_PERIOD_MSEC / 1000 ) );
- peer->blocksSentToPeer = tr_historyNew( CANCEL_HISTORY_SEC, ( RECHOKE_PERIOD_MSEC / 1000 ) );
- peer->cancelsSentToClient = tr_historyNew( CANCEL_HISTORY_SEC, ( RECHOKE_PERIOD_MSEC / 1000 ) );
- peer->cancelsSentToPeer = tr_historyNew( CANCEL_HISTORY_SEC, ( REFILL_UPKEEP_PERIOD_MSEC / 1000 ) );
+ 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 ) );
return peer;
}
tr_peerIoClear( peer->io );
tr_peerIoUnref( peer->io ); /* balanced by the ref in handshakeDoneCB() */
- tr_historyFree( peer->blocksSentToClient );
- tr_historyFree( peer->blocksSentToPeer );
- tr_historyFree( peer->cancelsSentToClient );
- tr_historyFree( peer->cancelsSentToPeer );
+ tr_historyDestruct( &peer->blocksSentToClient );
+ tr_historyDestruct( &peer->blocksSentToPeer );
+ tr_historyDestruct( &peer->cancelsSentToClient );
+ tr_historyDestruct( &peer->cancelsSentToPeer );
tr_bitsetDestruct( &peer->have );
tr_bitfieldFree( peer->blame );
/* send cancel messages for all the "cancel" ones */
for( it=cancel, end=it+cancelCount; it!=end; ++it ) {
if( ( it->peer != NULL ) && ( it->peer->msgs != NULL ) ) {
- tr_historyAdd( it->peer->cancelsSentToPeer, now, 1 );
+ tr_historyAdd( &it->peer->cancelsSentToPeer, now, 1 );
tr_peerMsgsCancel( it->peer->msgs, it->block );
decrementPendingReqCount( it );
}
tr_peer * p = peers[i];
assert( p != peer );
if( p->msgs ) {
- tr_historyAdd( p->cancelsSentToPeer, tr_time( ), 1 );
+ tr_historyAdd( &p->cancelsSentToPeer, tr_time( ), 1 );
tr_peerMsgsCancel( p->msgs, block );
}
removeRequestFromTables( t, block, p );
tr_ptrArrayDestruct( &peerArr, FALSE );
- if( peer && peer->blocksSentToClient )
- tr_historyAdd( peer->blocksSentToClient, tr_time( ), 1 );
+ if( peer )
+ tr_historyAdd( &peer->blocksSentToClient, tr_time( ), 1 );
if( tr_cpBlockIsComplete( &tor->completion, block ) )
{
stat->isUploadingTo = clientIsUploadingTo( peer );
stat->isSeed = ( atom->uploadOnly == UPLOAD_ONLY_YES ) || ( peer->progress >= 1.0 );
- stat->blocksToPeer = tr_historyGet( peer->blocksSentToPeer, now, CANCEL_HISTORY_SEC );
- stat->blocksToClient = tr_historyGet( peer->blocksSentToClient, now, CANCEL_HISTORY_SEC );
- stat->cancelsToPeer = tr_historyGet( peer->cancelsSentToPeer, now, CANCEL_HISTORY_SEC );
- stat->cancelsToClient = tr_historyGet( peer->cancelsSentToClient, now, CANCEL_HISTORY_SEC );
+ stat->blocksToPeer = tr_historyGet( &peer->blocksSentToPeer, now, CANCEL_HISTORY_SEC );
+ stat->blocksToClient = tr_historyGet( &peer->blocksSentToClient, now, CANCEL_HISTORY_SEC );
+ stat->cancelsToPeer = tr_historyGet( &peer->cancelsSentToPeer, now, CANCEL_HISTORY_SEC );
+ stat->cancelsToClient = tr_historyGet( &peer->cancelsSentToClient, now, CANCEL_HISTORY_SEC );
stat->pendingReqsToPeer = peer->pendingReqsToPeer;
stat->pendingReqsToClient = peer->pendingReqsToClient;
for( i=0; i<peerCount; ++i )
{
const tr_peer * peer = tr_ptrArrayNth( &t->peers, i );
- const int b = tr_historyGet( peer->blocksSentToClient, now, CANCEL_HISTORY_SEC );
- const int c = tr_historyGet( peer->cancelsSentToPeer, now, CANCEL_HISTORY_SEC );
+ const int b = tr_historyGet( &peer->blocksSentToClient, now, CANCEL_HISTORY_SEC );
+ const int c = tr_historyGet( &peer->cancelsSentToPeer, now, CANCEL_HISTORY_SEC );
if( b == 0 ) /* ignore unresponsive peers, as described above */
continue;
}
else
{
- const int blocks = tr_historyGet( peer->blocksSentToClient, now, CANCEL_HISTORY_SEC );
- const int cancels = tr_historyGet( peer->cancelsSentToPeer, now, CANCEL_HISTORY_SEC );
+ const int blocks = tr_historyGet( &peer->blocksSentToClient, now, CANCEL_HISTORY_SEC );
+ const int cancels = tr_historyGet( &peer->cancelsSentToPeer, now, CANCEL_HISTORY_SEC );
if( !blocks && !cancels )
untested[untestedCount++] = peer;
time_t chokeChangedAt;
- tr_recentHistory * blocksSentToClient;
- tr_recentHistory * blocksSentToPeer;
+ tr_recentHistory blocksSentToClient;
+ tr_recentHistory blocksSentToPeer;
- tr_recentHistory * cancelsSentToClient;
- tr_recentHistory * cancelsSentToPeer;
+ tr_recentHistory cancelsSentToClient;
+ tr_recentHistory cancelsSentToPeer;
struct tr_peermsgs * msgs;
}
tr_peerIoReadUint32( msgs->peer->io, inbuf, &r.index );
tr_peerIoReadUint32( msgs->peer->io, inbuf, &r.offset );
tr_peerIoReadUint32( msgs->peer->io, inbuf, &r.length );
- tr_historyAdd( msgs->peer->cancelsSentToClient, tr_time( ), 1 );
+ tr_historyAdd( &msgs->peer->cancelsSentToClient, tr_time( ), 1 );
dbgmsg( msgs, "got a Cancel %u:%u->%u", r.index, r.offset, r.length );
for( i=0; i<msgs->peer->pendingReqsToClient; ++i ) {
tr_peerIoWriteBuf( msgs->peer->io, out, TRUE );
bytesWritten += n;
msgs->clientSentAnythingAt = now;
- tr_historyAdd( msgs->peer->blocksSentToPeer, tr_time( ), 1 );
+ tr_historyAdd( &msgs->peer->blocksSentToPeer, tr_time( ), 1 );
}
evbuffer_free( out );