Changeset 12402
- Timestamp:
- Apr 29, 2011, 11:25:12 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/peer-mgr.c
r12401 r12402 2747 2747 } 2748 2748 2749 /** 2750 *** 2751 **/ 2749 /*** 2750 **** 2751 **** 2752 ***/ 2752 2753 2753 2754 void … … 2796 2797 } 2797 2798 2799 typedef enum 2800 { 2801 RECHOKE_STATE_GOOD, 2802 RECHOKE_STATE_UNTESTED, 2803 RECHOKE_STATE_BAD 2804 } 2805 tr_rechoke_state; 2806 2807 struct tr_rechoke_info 2808 { 2809 tr_peer * peer; 2810 int salt; 2811 int rechoke_state; 2812 }; 2813 2814 static int 2815 compare_rechoke_info( const void * va, const void * vb ) 2816 { 2817 const struct tr_rechoke_info * a = va; 2818 const struct tr_rechoke_info * b = vb; 2819 2820 if( a->rechoke_state != b->rechoke_state ) 2821 return a->rechoke_state - b->rechoke_state; 2822 2823 return a->salt - b->salt; 2824 } 2825 2798 2826 /* determines who we send "interested" messages to */ 2799 2827 static void … … 2801 2829 { 2802 2830 int i; 2803 const time_t now = tr_time( ); 2831 int maxPeers = 0; 2832 int rechoke_count = 0; 2833 struct tr_rechoke_info * rechoke = NULL; 2804 2834 const int MIN_INTERESTING_PEERS = 5; 2805 2835 const int peerCount = tr_ptrArraySize( &t->peers ); 2806 int maxPeers = 0; 2807 2808 int badCount = 0; 2809 int goodCount = 0; 2810 int untestedCount = 0; 2811 tr_peer ** bad = tr_new( tr_peer*, peerCount ); 2812 tr_peer ** good = tr_new( tr_peer*, peerCount ); 2813 tr_peer ** untested = tr_new( tr_peer*, peerCount ); 2814 2815 /* decide how many peers to be interested in */ 2836 const time_t now = tr_time( ); 2837 2838 /* decide HOW MANY peers to be interested in */ 2816 2839 { 2817 2840 int blocks = 0; … … 2881 2904 t->maxPeers = maxPeers; 2882 2905 2883 /* separate the peers into "good" (ones with a low cancel-to-block ratio), 2884 * untested peers, and "bad" (ones with a high cancel-to-block ratio). 2885 * That's the order in which we'll choose who to show interest in */ 2886 { 2887 /* Randomize the peer array so the peers in the three groups will be unsorted... */ 2888 int n = peerCount; 2889 tr_peer ** peers = tr_memdup( tr_ptrArrayBase( &t->peers ), n * sizeof( tr_peer * ) ); 2890 2891 while( n > 0 ) 2906 /* decide WHICH peers to be interested in (based on their cancel-to-block ratio) */ 2907 for( i=0; i<peerCount; ++i ) 2908 { 2909 tr_peer * peer = tr_ptrArrayNth( &t->peers, i ); 2910 2911 if( !isPeerInteresting( t->tor, peer ) ) 2892 2912 { 2893 const int i = tr_cryptoWeakRandInt( n ); 2894 tr_peer * peer = peers[i]; 2895 2896 if( !isPeerInteresting( t->tor, peer ) ) 2897 { 2898 tr_peerMsgsSetInterested( peer->msgs, false ); 2899 } 2913 tr_peerMsgsSetInterested( peer->msgs, false ); 2914 } 2915 else 2916 { 2917 tr_rechoke_state rechoke_state; 2918 const int blocks = tr_historyGet( &peer->blocksSentToClient, now, CANCEL_HISTORY_SEC ); 2919 const int cancels = tr_historyGet( &peer->cancelsSentToPeer, now, CANCEL_HISTORY_SEC ); 2920 2921 if( !blocks && !cancels ) 2922 rechoke_state = RECHOKE_STATE_UNTESTED; 2923 else if( !cancels ) 2924 rechoke_state = RECHOKE_STATE_GOOD; 2925 else if( !blocks ) 2926 rechoke_state = RECHOKE_STATE_BAD; 2927 else if( ( cancels * 10 ) < blocks ) 2928 rechoke_state = RECHOKE_STATE_GOOD; 2900 2929 else 2901 { 2902 const int blocks = tr_historyGet( &peer->blocksSentToClient, now, CANCEL_HISTORY_SEC ); 2903 const int cancels = tr_historyGet( &peer->cancelsSentToPeer, now, CANCEL_HISTORY_SEC ); 2904 2905 if( !blocks && !cancels ) 2906 untested[untestedCount++] = peer; 2907 else if( !cancels ) 2908 good[goodCount++] = peer; 2909 else if( !blocks ) 2910 bad[badCount++] = peer; 2911 else if( ( cancels * 10 ) < blocks ) 2912 good[goodCount++] = peer; 2913 else 2914 bad[badCount++] = peer; 2915 } 2916 2917 /* remove 'peer' from the array 'peers' */ 2918 if( i != n - 1 ) 2919 peers[i] = peers[n-1]; 2920 --n; 2930 rechoke_state = RECHOKE_STATE_BAD; 2931 2932 if( rechoke == NULL ) 2933 rechoke = tr_new( struct tr_rechoke_info, peerCount ); 2934 2935 rechoke[rechoke_count].peer = peer; 2936 rechoke[rechoke_count].rechoke_state = rechoke_state; 2937 rechoke[rechoke_count].salt = tr_cryptoWeakRandInt( INT_MAX ); 2938 rechoke_count++; 2921 2939 } 2922 2940 2923 tr_free( peers ); 2924 } 2925 2926 t->interestedCount = 0; 2927 2928 /* We've decided (1) how many peers to be interested in, 2929 * and (2) which peers are the best candidates, 2930 * Now it's time to update our `interest' flags. */ 2931 for( i=0; i<goodCount; ++i ) { 2932 const bool b = t->interestedCount < maxPeers; 2933 tr_peerMsgsSetInterested( good[i]->msgs, b ); 2934 if( b ) 2935 ++t->interestedCount; 2936 } 2937 for( i=0; i<untestedCount; ++i ) { 2938 const bool b = t->interestedCount < maxPeers; 2939 tr_peerMsgsSetInterested( untested[i]->msgs, b ); 2940 if( b ) 2941 ++t->interestedCount; 2942 } 2943 for( i=0; i<badCount; ++i ) { 2944 const bool b = t->interestedCount < maxPeers; 2945 tr_peerMsgsSetInterested( bad[i]->msgs, b ); 2946 if( b ) 2947 ++t->interestedCount; 2948 } 2949 2950 /*fprintf( stderr, "num interested: %d\n", t->interestedCount );*/ 2941 } 2942 2943 /* now that we know which & how many peers to be interested in... update the peer interest */ 2944 qsort( rechoke, rechoke_count, sizeof( struct tr_rechoke_info ), compare_rechoke_info ); 2945 t->interestedCount = MIN( maxPeers, rechoke_count ); 2946 for( i=0; i<rechoke_count; ++i ) 2947 tr_peerMsgsSetInterested( rechoke[i].peer->msgs, i<t->interestedCount ); 2951 2948 2952 2949 /* cleanup */ 2953 tr_free( untested ); 2954 tr_free( good ); 2955 tr_free( bad ); 2950 tr_free( rechoke ); 2956 2951 } 2957 2952
Note: See TracChangeset
for help on using the changeset viewer.