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.
#include <stdio.h>
+#include <string.h> /* memset() */
#include "transmission.h"
#include "history.h"
{
tr_recentHistory h;
- tr_historyConstruct( &h, 60, 10 );
+ memset( &h, 0, sizeof( tr_recentHistory ) );
+
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, 22000, 3000 ) == 1 )
check( (int)tr_historyGet( &h, 22000, 15000 ) == 2 )
check( (int)tr_historyGet( &h, 22000, 20000 ) == 2 )
- tr_historyDestruct( &h );
return 0;
}
void
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;
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].n = 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 */
}
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 );
-}
* to estimate the speed over the last N seconds.
*/
-struct tr_history_slice
+enum
{
- unsigned int n;
- time_t date;
+ TR_RECENT_HISTORY_PERIOD_SEC = 60
};
+
+
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;
+
+ struct {
+ unsigned int n;
+ time_t date;
+ } slices[TR_RECENT_HISTORY_PERIOD_SEC];
}
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.
* @param when the current time in sec, such as from tr_time()
memset( peer, 0, sizeof( tr_peer ) );
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*
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->blame );
tr_free( peer->client );