Changeset 9085


Ignore:
Timestamp:
Sep 10, 2009, 2:20:35 AM (13 years ago)
Author:
charles
Message:

(trunk libT) #2395: caching too many peers between sessions makes startup slow and uses too much memory (KyleK, stdisease, et al)

Location:
trunk/libtransmission
Files:
4 edited

Legend:

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

    r9074 r9085  
    15211521#endif
    15221522
     1523/* better goes first */
     1524static int
     1525compareAtomsByUsefulness( const void * va, const void *vb )
     1526{
     1527    const struct peer_atom * a = * (const struct peer_atom**) va;
     1528    const struct peer_atom * b = * (const struct peer_atom**) vb;
     1529
     1530    assert( ( 0 < a->from ) && ( a->from < TR_PEER_FROM__MAX ) );
     1531    assert( ( 0 < b->from ) && ( b->from < TR_PEER_FROM__MAX ) );
     1532
     1533    if( a->piece_data_time != b->piece_data_time )
     1534        return a->piece_data_time > b->piece_data_time ? -1 : 1;
     1535    if( a->from != b->from )
     1536        return a->from < b->from ? -1 : 1;
     1537    if( a->numFails != b->numFails )
     1538        return a->numFails < b->numFails ? -1 : 1;
     1539
     1540    return 0;
     1541}
     1542
    15231543int
    1524 tr_peerMgrGetPeers( tr_torrent * tor, tr_pex ** setme_pex, uint8_t af )
     1544tr_peerMgrGetPeers( tr_torrent * tor, tr_pex ** setme_pex, uint8_t af, int maxPeerCount )
    15251545{
    15261546    int count = 0;
     
    15311551    {
    15321552        int i;
    1533         const struct peer_atom ** atoms = (const struct peer_atom**) tr_ptrArrayBase( &t->pool );
    15341553        const int atomCount = tr_ptrArraySize( &t->pool );
     1554        const int pexCount = MIN( atomCount, maxPeerCount );
     1555        const struct peer_atom ** atomsBase = (const struct peer_atom**) tr_ptrArrayBase( &t->pool );
     1556        struct peer_atom ** atoms = tr_memdup( atomsBase, atomCount * sizeof( struct peer_atom * ) );
    15351557        /* for now, this will waste memory on torrents that have both
    15361558         * ipv6 and ipv4 peers */
     
    15381560        tr_pex * walk = pex;
    15391561
    1540         for( i=0; i<atomCount; ++i )
     1562        qsort( atoms, atomCount, sizeof( struct peer_atom * ), compareAtomsByUsefulness );
     1563
     1564        for( i=0; i<atomCount && count<pexCount; ++i )
    15411565        {
    15421566            const struct peer_atom * atom = atoms[i];
     
    15531577
    15541578        assert( ( walk - pex ) == count );
    1555         qsort( pex, count, sizeof( tr_pex ), tr_pexCompare );
    15561579        *setme_pex = pex;
     1580
     1581        tr_free( atoms );
    15571582    }
    15581583
  • trunk/libtransmission/peer-mgr.h

    r8695 r9085  
    151151int  tr_peerMgrGetPeers( tr_torrent      * tor,
    152152                         tr_pex         ** setme_pex,
    153                          uint8_t           af);
     153                         uint8_t           af,
     154                         int               maxPeerCount );
    154155
    155156void tr_peerMgrStartTorrent( tr_torrent * tor );
  • trunk/libtransmission/peer-msgs.c

    r8963 r9085  
    7070    TR_LTEP_PEX             = 1,
    7171
    72 
     72    MAX_PEX_PEER_COUNT      = 100,
    7373
    7474    MIN_CHOKE_PERIOD_SEC    = ( 10 ),
     
    19761976        tr_pex * newPex = NULL;
    19771977        tr_pex * newPex6 = NULL;
    1978         const int newCount = tr_peerMgrGetPeers( msgs->torrent, &newPex, TR_AF_INET );
    1979         const int newCount6 = tr_peerMgrGetPeers( msgs->torrent, &newPex6, TR_AF_INET6 );
     1978        const int newCount = tr_peerMgrGetPeers( msgs->torrent, &newPex, TR_AF_INET, MAX_PEX_PEER_COUNT );
     1979        const int newCount6 = tr_peerMgrGetPeers( msgs->torrent, &newPex6, TR_AF_INET6, MAX_PEX_PEER_COUNT );
    19801980
    19811981        /* build the diffs */
  • trunk/libtransmission/resume.c

    r8930 r9085  
    5959#define KEY_PROGRESS_BITFIELD "bitfield"
    6060
     61enum
     62{
     63    MAX_REMEMBERED_PEERS = 200
     64};
     65
    6166static char*
    6267getResumeFilename( const tr_torrent * tor )
     
    7479
    7580static void
    76 savePeers( tr_benc *          dict,
    77            const tr_torrent * tor )
     81savePeers( tr_benc * dict, const tr_torrent * tor )
    7882{
    7983    int count;
    8084    tr_pex * pex;
    8185
    82     count = tr_peerMgrGetPeers( (tr_torrent*) tor, &pex, TR_AF_INET );
     86    count = tr_peerMgrGetPeers( (tr_torrent*) tor, &pex, TR_AF_INET, MAX_REMEMBERED_PEERS );
    8387    if( count > 0 )
    8488        tr_bencDictAddRaw( dict, KEY_PEERS, pex, sizeof( tr_pex ) * count );
    8589    tr_free( pex );
    8690
    87     count = tr_peerMgrGetPeers( (tr_torrent*) tor, &pex, TR_AF_INET6 );
     91    count = tr_peerMgrGetPeers( (tr_torrent*) tor, &pex, TR_AF_INET6, MAX_REMEMBERED_PEERS );
    8892    if( count > 0 )
    8993        tr_bencDictAddRaw( dict, KEY_PEERS6, pex, sizeof( tr_pex ) * count );
     
    9296}
    9397
    94 static uint64_t
    95 loadPeers( tr_benc *    dict,
    96            tr_torrent * tor )
     98static tr_bool
     99tr_isPex( const tr_pex * pex )
     100{
     101    return tr_isAddress( &pex->addr )
     102        && ( pex->flags & 3 ) == pex->flags;
     103}
     104
     105static int
     106addPeers( tr_torrent * tor, const uint8_t * buf, int buflen )
     107{
     108    int i;
     109    int numAdded = 0;
     110    const int count = buflen / sizeof( tr_pex );
     111
     112    for( i=0; i<count && numAdded<MAX_REMEMBERED_PEERS; ++i )
     113    {
     114        tr_pex pex;
     115        memcpy( &pex, buf + ( i * sizeof( tr_pex ) ), sizeof( tr_pex ) );
     116        if( tr_isPex( &pex ) )
     117        {
     118            tr_peerMgrAddPex( tor, TR_PEER_FROM_CACHE, &pex );
     119            ++numAdded;
     120        }
     121    }
     122
     123    return numAdded;
     124}
     125
     126
     127static uint64_t
     128loadPeers( tr_benc * dict, tr_torrent * tor )
    97129{
    98130    uint64_t        ret = 0;
     
    102134    if( tr_bencDictFindRaw( dict, KEY_PEERS, &str, &len ) )
    103135    {
    104         int       i;
    105         const int count = len / sizeof( tr_pex );
    106         for( i = 0; i < count; ++i )
    107         {
    108             tr_pex pex;
    109             memcpy( &pex, str + ( i * sizeof( tr_pex ) ), sizeof( tr_pex ) );
    110             tr_peerMgrAddPex( tor, TR_PEER_FROM_CACHE, &pex );
    111         }
    112         tr_tordbg( tor, "Loaded %d IPv4 peers from resume file", count );
     136        const int numAdded = addPeers( tor, str, len );
     137        tr_tordbg( tor, "Loaded %d IPv4 peers from resume file", numAdded );
    113138        ret = TR_FR_PEERS;
    114139    }
     
    116141    if( tr_bencDictFindRaw( dict, KEY_PEERS6, &str, &len ) )
    117142    {
    118         int       i;
    119         const int count = len / sizeof( tr_pex );
    120         for( i = 0; i < count; ++i )
    121         {
    122             tr_pex pex;
    123             memcpy( &pex, str + ( i * sizeof( tr_pex ) ), sizeof( tr_pex ) );
    124             tr_peerMgrAddPex( tor, TR_PEER_FROM_CACHE, &pex );
    125         }
    126         tr_tordbg( tor, "Loaded %d IPv6 peers from resume file", count );
     143        const int numAdded = addPeers( tor, str, len );
     144        tr_tordbg( tor, "Loaded %d IPv6 peers from resume file", numAdded );
    127145        ret = TR_FR_PEERS;
    128146    }
Note: See TracChangeset for help on using the changeset viewer.