1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2025-02-23 14:40:43 +00:00

this should improve download speeds. test it!

This commit is contained in:
Charles Kerr 2007-11-18 03:18:26 +00:00
parent f3c153234f
commit e371009606
3 changed files with 90 additions and 75 deletions

View file

@ -30,7 +30,7 @@
#define IO_TIMEOUT_SECS 8 #define IO_TIMEOUT_SECS 8
/* arbitrary */ /* arbitrary */
#define TR_RDBUF (1024*3) #define TR_RDBUF (1024*8)
/** /**
*** ***
@ -407,8 +407,9 @@ void
tr_peerIoWriteBuf( tr_peerIo * io, tr_peerIoWriteBuf( tr_peerIo * io,
struct evbuffer * buf ) struct evbuffer * buf )
{ {
tr_peerIoWrite( io, EVBUFFER_DATA(buf), EVBUFFER_LENGTH(buf) ); const size_t n = EVBUFFER_LENGTH( buf );
evbuffer_drain( buf, ~0 ); tr_peerIoWrite( io, EVBUFFER_DATA(buf), n );
evbuffer_drain( buf, n );
} }
/** /**

View file

@ -1593,28 +1593,28 @@ swiftPulse( void * vtorrent )
tr_peer ** peers = getConnectedPeers( t, &peerCount ); tr_peer ** peers = getConnectedPeers( t, &peerCount );
tr_peer ** deadbeats = tr_new( tr_peer*, peerCount ); tr_peer ** deadbeats = tr_new( tr_peer*, peerCount );
for( i=0; i<peerCount; ++i ) {
tr_peer * peer = peers[i];
if( peer->credit < 0 )
deadbeats[deadbeatCount++] = peer;
}
if( deadbeatCount )
{
const double ul_KiBsec = tr_rcRate( t->tor->upload ); const double ul_KiBsec = tr_rcRate( t->tor->upload );
const double ul_KiB = ul_KiBsec * (SWIFT_PERIOD_MSEC/1000.0); const double ul_KiB = ul_KiBsec * (SWIFT_PERIOD_MSEC/1000.0);
const double ul_bytes = ul_KiB * 1024; const double ul_bytes = ul_KiB * 1024;
const double freeCreditTotal = ul_bytes * SWIFT_LARGESSE; const double freeCreditTotal = ul_bytes * SWIFT_LARGESSE;
const int freeCreditPerPeer = (int)( freeCreditTotal / deadbeatCount ); int freeCreditPerPeer;
for( i=0; i<peerCount; ++i ) {
tr_peer * peer = peers[i];
if( peer->credit <= 0 )
deadbeats[deadbeatCount++] = peer;
}
freeCreditPerPeer = (int)( freeCreditTotal / deadbeatCount );
for( i=0; i<deadbeatCount; ++i ) for( i=0; i<deadbeatCount; ++i )
deadbeats[i]->credit = freeCreditPerPeer; deadbeats[i]->credit = freeCreditPerPeer;
tordbg( t, "%d deadbeats, " tordbg( t, "%d deadbeats, "
"who are each being granted %d bytes' credit " "who are each being granted %d bytes' credit "
"for a total of %.1f KiB, " "for a total of %.1f KiB, "
"%d%% of the torrent's ul speed %.1f\n", "%d%% of the torrent's ul speed %.1f\n",
deadbeatCount, freeCreditPerPeer, deadbeatCount, freeCreditPerPeer,
ul_KiBsec*SWIFT_LARGESSE, (int)(SWIFT_LARGESSE*100), ul_KiBsec ); ul_KiBsec*SWIFT_LARGESSE, (int)(SWIFT_LARGESSE*100), ul_KiBsec );
}
tr_free( deadbeats ); tr_free( deadbeats );
tr_free( peers ); tr_free( peers );
@ -1731,29 +1731,37 @@ getPeerCandidates( Torrent * t, int * setmeSize )
/* peer fed us too much bad data ... we only keep it around /* peer fed us too much bad data ... we only keep it around
* now to weed it out in case someone sends it to us via pex */ * now to weed it out in case someone sends it to us via pex */
if( atom->myflags & MYFLAG_BANNED ) { if( atom->myflags & MYFLAG_BANNED ) {
#if 0
tordbg( t, "RECONNECT peer %d (%s) is banned...", tordbg( t, "RECONNECT peer %d (%s) is banned...",
i, tr_peerIoAddrStr(&atom->addr,atom->port) ); i, tr_peerIoAddrStr(&atom->addr,atom->port) );
#endif
continue; continue;
} }
/* we don't need two connections to the same peer... */ /* we don't need two connections to the same peer... */
if( peerIsInUse( t, &atom->addr ) ) { if( peerIsInUse( t, &atom->addr ) ) {
#if 0
tordbg( t, "RECONNECT peer %d (%s) is in use..", tordbg( t, "RECONNECT peer %d (%s) is in use..",
i, tr_peerIoAddrStr(&atom->addr,atom->port) ); i, tr_peerIoAddrStr(&atom->addr,atom->port) );
#endif
continue; continue;
} }
/* no need to connect if we're both seeds... */ /* no need to connect if we're both seeds... */
if( seed && (atom->flags & ADDED_F_SEED_FLAG) ) { if( seed && (atom->flags & ADDED_F_SEED_FLAG) ) {
#if 0
tordbg( t, "RECONNECT peer %d (%s) is a seed and so are we..", tordbg( t, "RECONNECT peer %d (%s) is a seed and so are we..",
i, tr_peerIoAddrStr(&atom->addr,atom->port) ); i, tr_peerIoAddrStr(&atom->addr,atom->port) );
#endif
continue; continue;
} }
/* we're wasting our time trying to connect to this bozo. */ /* we're wasting our time trying to connect to this bozo. */
if( atom->numFails > 10 ) { if( atom->numFails > 10 ) {
#if 0
tordbg( t, "RECONNECT peer %d (%s) gives us nothing but failure.", tordbg( t, "RECONNECT peer %d (%s) gives us nothing but failure.",
i, tr_peerIoAddrStr(&atom->addr,atom->port) ); i, tr_peerIoAddrStr(&atom->addr,atom->port) );
#endif
continue; continue;
} }

View file

@ -144,6 +144,7 @@ struct tr_peermsgs
unsigned int peerSupportsPex : 1; unsigned int peerSupportsPex : 1;
unsigned int clientSentLtepHandshake : 1; unsigned int clientSentLtepHandshake : 1;
unsigned int peerSentLtepHandshake : 1; unsigned int peerSentLtepHandshake : 1;
unsigned int sendingBlock : 1;
tr_bitfield * clientAllowedPieces; tr_bitfield * clientAllowedPieces;
tr_bitfield * peerAllowedPieces; tr_bitfield * peerAllowedPieces;
@ -565,6 +566,8 @@ pumpRequestQueue( tr_peermsgs * msgs )
while( ( count < max ) && ( msgs->clientWillAskFor != NULL ) ) while( ( count < max ) && ( msgs->clientWillAskFor != NULL ) )
{ {
struct peer_request * r = tr_list_pop_front( &msgs->clientWillAskFor ); struct peer_request * r = tr_list_pop_front( &msgs->clientWillAskFor );
assert( requestIsValid( msgs, r ) );
assert( tr_bitfieldHas( msgs->info->have, r->index ) );
protocolSendRequest( msgs, r ); protocolSendRequest( msgs, r );
r->time_requested = msgs->lastReqAddedAt = time( NULL ); r->time_requested = msgs->lastReqAddedAt = time( NULL );
tr_list_append( &msgs->clientAskedFor, r ); tr_list_append( &msgs->clientAskedFor, r );
@ -639,7 +642,6 @@ tr_peerMsgsAddRequest( tr_peermsgs * msgs,
req = tr_new0( struct peer_request, 1 ); req = tr_new0( struct peer_request, 1 );
*req = tmp; *req = tmp;
tr_list_append( &msgs->clientWillAskFor, req ); tr_list_append( &msgs->clientWillAskFor, req );
pulse( msgs );
return TR_ADDREQ_OK; return TR_ADDREQ_OK;
} }
@ -1442,15 +1444,7 @@ static int
canWrite( const tr_peermsgs * msgs ) canWrite( const tr_peermsgs * msgs )
{ {
/* don't let our outbuffer get too large */ /* don't let our outbuffer get too large */
if( tr_peerIoWriteBytesWaiting( msgs->io ) > 4096 ) return tr_peerIoWriteBytesWaiting( msgs->io ) < 4096;
return FALSE;
/* SWIFT */
if( SWIFT_ENABLED && !tr_torrentIsSeed( msgs->torrent )
&& ( msgs->info->credit < 0 ) )
return FALSE;
return TRUE;
} }
static size_t static size_t
@ -1458,18 +1452,22 @@ getUploadMax( const tr_peermsgs * msgs )
{ {
static const size_t maxval = ~0; static const size_t maxval = ~0;
const tr_torrent * tor = msgs->torrent; const tr_torrent * tor = msgs->torrent;
const int useSwift = SWIFT_ENABLED && !tr_torrentIsSeed( msgs->torrent );
const size_t swiftBytes = msgs->info->credit;
size_t speedBytes;
if( !canWrite( msgs ) ) if( !canWrite( msgs ) )
return 0; return 0;
if( tor->uploadLimitMode == TR_SPEEDLIMIT_GLOBAL ) if( tor->uploadLimitMode == TR_SPEEDLIMIT_GLOBAL )
return tor->handle->useUploadLimit speedBytes = tor->handle->useUploadLimit ? tr_rcBytesLeft( tor->handle->upload ) : maxval;
? tr_rcBytesLeft( tor->handle->upload ) : maxval; else if( tor->uploadLimitMode == TR_SPEEDLIMIT_SINGLE )
speedBytes = tr_rcBytesLeft( tor->upload );
else
speedBytes = ~0;
if( tor->uploadLimitMode == TR_SPEEDLIMIT_SINGLE ) return useSwift ? MIN( speedBytes, swiftBytes )
return tr_rcBytesLeft( tor->upload ); : speedBytes;
return maxval;
} }
static int static int
@ -1533,32 +1531,36 @@ pulse( void * vmsgs )
pumpRequestQueue( msgs ); pumpRequestQueue( msgs );
updatePeerStatus( msgs ); updatePeerStatus( msgs );
if( !canWrite( msgs ) ) if( msgs->sendingBlock )
{
}
else if(( len = EVBUFFER_LENGTH( msgs->outBlock ) ))
{ {
const size_t uploadMax = getUploadMax( msgs ); const size_t uploadMax = getUploadMax( msgs );
size_t len = EVBUFFER_LENGTH( msgs->outBlock );
const size_t outlen = MIN( len, uploadMax ); const size_t outlen = MIN( len, uploadMax );
assert( len );
if( outlen && canWrite( msgs ) )
{
tr_peerIoWrite( msgs->io, EVBUFFER_DATA( msgs->outBlock ), outlen ); tr_peerIoWrite( msgs->io, EVBUFFER_DATA( msgs->outBlock ), outlen );
evbuffer_drain( msgs->outBlock, outlen ); evbuffer_drain( msgs->outBlock, outlen );
msgs->clientSentAnythingAt = now;
peerGotBytes( msgs, outlen ); peerGotBytes( msgs, outlen );
len -= outlen; len -= outlen;
msgs->clientSentAnythingAt = now;
msgs->sendingBlock = len!=0;
dbgmsg( msgs, "wrote %d bytes; %d left in block", (int)outlen, (int)len ); dbgmsg( msgs, "wrote %d bytes; %d left in block", (int)outlen, (int)len );
fflush( stdout );
} }
else if(( len = EVBUFFER_LENGTH( msgs->outMessages ) )) }
if( !msgs->sendingBlock )
{
if(( len = EVBUFFER_LENGTH( msgs->outMessages ) ))
{ {
tr_peerIoWriteBuf( msgs->io, msgs->outMessages ); tr_peerIoWriteBuf( msgs->io, msgs->outMessages );
msgs->clientSentAnythingAt = now; msgs->clientSentAnythingAt = now;
} }
else if( ( now - msgs->clientSentAnythingAt ) > KEEPALIVE_INTERVAL_SECS ) else if( !EVBUFFER_LENGTH( msgs->outBlock )
{
sendKeepalive( msgs );
}
if( !EVBUFFER_LENGTH( msgs->outBlock )
&& (( r = popNextRequest( msgs ))) && (( r = popNextRequest( msgs )))
&& requestIsValid( msgs, r ) && requestIsValid( msgs, r )
&& tr_cpPieceIsComplete( msgs->torrent->completion, r->index ) ) && tr_cpPieceIsComplete( msgs->torrent->completion, r->index ) )
@ -1576,12 +1578,16 @@ pulse( void * vmsgs )
tr_peerIoWriteUint32( io, out, r->index ); tr_peerIoWriteUint32( io, out, r->index );
tr_peerIoWriteUint32( io, out, r->offset ); tr_peerIoWriteUint32( io, out, r->offset );
tr_peerIoWriteBytes ( io, out, buf, r->length ); tr_peerIoWriteBytes ( io, out, buf, r->length );
msgs->sendingBlock = 1;
} }
tr_free( buf ); tr_free( buf );
tr_free( r ); tr_free( r );
}
pulse( msgs ); /* start sending it right away */ else if( ( now - msgs->clientSentAnythingAt ) > KEEPALIVE_INTERVAL_SECS )
{
sendKeepalive( msgs );
}
} }
return TRUE; /* loop forever */ return TRUE; /* loop forever */