Changeset 12402


Ignore:
Timestamp:
Apr 29, 2011, 11:25:12 PM (12 years ago)
Author:
jordan
Message:

(trunk libT) simplify the code in peer-mgr.c's rechokeDownloads().

The new code has fewer calls to malloc/free and, more importantly, has less copy-and-pasted code to handle the different rechoke states.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/peer-mgr.c

    r12401 r12402  
    27472747}
    27482748
    2749 /**
    2750 ***
    2751 **/
     2749/***
     2750****
     2751****
     2752***/
    27522753
    27532754void
     
    27962797}
    27972798
     2799typedef enum
     2800{
     2801    RECHOKE_STATE_GOOD,
     2802    RECHOKE_STATE_UNTESTED,
     2803    RECHOKE_STATE_BAD
     2804}
     2805tr_rechoke_state;
     2806
     2807struct tr_rechoke_info
     2808{
     2809    tr_peer * peer;
     2810    int salt;
     2811    int rechoke_state;
     2812};
     2813
     2814static int
     2815compare_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
    27982826/* determines who we send "interested" messages to */
    27992827static void
     
    28012829{
    28022830    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;
    28042834    const int MIN_INTERESTING_PEERS = 5;
    28052835    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 */
    28162839    {
    28172840        int blocks = 0;
     
    28812904    t->maxPeers = maxPeers;
    28822905
    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 ) )
    28922912        {
    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;
    29002929            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++;
    29212939        }
    29222940
    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 );
    29512948
    29522949    /* cleanup */
    2953     tr_free( untested );
    2954     tr_free( good );
    2955     tr_free( bad );
     2950    tr_free( rechoke );
    29562951}
    29572952
Note: See TracChangeset for help on using the changeset viewer.