From 6197b6665c386074a96657d449c8a4dd5ffe0efd Mon Sep 17 00:00:00 2001 From: Eric Petit Date: Wed, 8 Feb 2006 22:21:58 +0000 Subject: [PATCH] Added optimistic choking --- libtransmission/choking.c | 41 ++++++++++++++++++++++++++++++++++++++- libtransmission/peer.c | 11 +++++++++++ libtransmission/peer.h | 2 ++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/libtransmission/choking.c b/libtransmission/choking.c index 2faa77497..2d7e8fd73 100644 --- a/libtransmission/choking.c +++ b/libtransmission/choking.c @@ -138,7 +138,7 @@ static inline void sortPeers( tr_peer_t ** all, int allCount, void tr_chokingPulse( tr_choking_t * c ) { - int i, peersTotalCount, unchoked; + int i, peersTotalCount, unchoked, mustOptimistic = 1; tr_peer_t ** canChoke, ** canUnchoke; tr_peer_t ** canChokeZero, ** canUnchokeZero; tr_peer_t ** canChokeNonZero, ** canUnchokeNonZero; @@ -182,7 +182,10 @@ void tr_chokingPulse( tr_choking_t * c ) if( !tr_peerIsInterested( peer ) ) { if( tr_peerIsUnchoked( peer ) ) + { tr_peerChoke( peer ); + tr_peerSetOptimistic( peer, 0 ); + } continue; } @@ -192,6 +195,22 @@ void tr_chokingPulse( tr_choking_t * c ) (or the other way around). */ if( tr_peerIsUnchoked( peer ) ) { + if( tr_peerIsOptimistic( peer ) ) + { + if( tr_peerLastChoke( peer ) + 30000 < now ) + { + /* He got his 30 seconds, now we see him like + any other unchoked peer */ + tr_peerSetOptimistic( peer, 0 ); + } + else + { + /* Keep him unchoked for 30 seconds */ + mustOptimistic = 0; + continue; + } + } + unchoked++; if( tr_peerLastChoke( peer ) + 10000 < now ) canChoke[canChokeCount++] = peer; @@ -219,6 +238,26 @@ void tr_chokingPulse( tr_choking_t * c ) free( canChoke ); free( canUnchoke ); + if( mustOptimistic ) + { + tr_peer_t * peer; + + /* Open an extra slot for optimistic choking */ + if( canUnchokeZeroCount ) + { + /* TODO: prefer peers with no pieces at all */ + peer = canUnchokeZero[--canUnchokeZeroCount]; + tr_peerUnchoke( peer ); + tr_peerSetOptimistic( peer, 1 ); + } + else if( canUnchokeNonZeroCount ) + { + peer = canUnchokeNonZero[--canUnchokeNonZeroCount]; + tr_peerUnchoke( peer ); + tr_peerSetOptimistic( peer, 1 ); + } + } + /* If we have more open slots than what we should have (the user has just lowered his upload limit), we need to choke some of the peers we are uploading to. We start with the peers who aren't diff --git a/libtransmission/peer.c b/libtransmission/peer.c index 88f9eeed3..3281e1c27 100644 --- a/libtransmission/peer.c +++ b/libtransmission/peer.c @@ -53,6 +53,7 @@ struct tr_peer_s char peerChoking; char peerInterested; + int optimistic; uint64_t lastChoke; uint8_t id[20]; @@ -489,3 +490,13 @@ uint64_t tr_peerLastChoke( tr_peer_t * peer ) { return peer->lastChoke; } + +void tr_peerSetOptimistic( tr_peer_t * peer, int o ) +{ + peer->optimistic = o; +} + +int tr_peerIsOptimistic( tr_peer_t * peer ) +{ + return peer->optimistic; +} diff --git a/libtransmission/peer.h b/libtransmission/peer.h index ec9286516..e768027d0 100644 --- a/libtransmission/peer.h +++ b/libtransmission/peer.h @@ -44,5 +44,7 @@ int tr_peerIsInterested ( tr_peer_t * ); void tr_peerChoke ( tr_peer_t * ); void tr_peerUnchoke ( tr_peer_t * ); uint64_t tr_peerLastChoke ( tr_peer_t * ); +void tr_peerSetOptimistic ( tr_peer_t *, int ); +int tr_peerIsOptimistic ( tr_peer_t * ); #endif