Ticket #2551: prefetch.3.patch

File prefetch.3.patch, 3.2 KB (added by charles, 11 years ago)

revision of jch's prefetch.2.patch, tweaked to handle r9494

  • peer-msgs.c

     
    172172    int             activeRequestCount;
    173173    int             desiredRequestCount;
    174174
     175    int             prefetchCount;
     176
    175177    /* how long the outMessages batch should be allowed to grow before
    176178     * it's flushed -- some messages (like requests >:) should be sent
    177179     * very quickly; others aren't as urgent. */
     
    197199
    198200    struct peer_request    peerAskedFor[REQQ];
    199201    int                    peerAskedForCount;
    200     
     202 
    201203    tr_pex               * pex;
    202204    tr_pex               * pex6;
    203205
     
    833835    tr_bencInitDict( &val, 5 );
    834836    tr_bencDictAddInt( &val, "e", getSession(msgs)->encryptionMode != TR_CLEAR_PREFERRED );
    835837    tr_bencDictAddInt( &val, "p", tr_sessionGetPeerPort( getSession(msgs) ) );
    836     tr_bencDictAddInt( &val, "reqq", REQQ ); 
     838    tr_bencDictAddInt( &val, "reqq", REQQ );
    837839    tr_bencDictAddInt( &val, "upload_only", tr_torrentIsSeed( msgs->torrent ) );
    838840    tr_bencDictAddStr( &val, "v", TR_NAME " " USERAGENT_PREFIX );
    839841    m  = tr_bencDictAddDict( &val, "m", 1 );
     
    15291531        int estimatedBlocksInPeriod;
    15301532        double rate;
    15311533        const int floor = 16;
    1532         const int seconds = REQUEST_BUF_SECS; 
     1534        const int seconds = REQUEST_BUF_SECS;
    15331535
    15341536        /* Get the rate limit we should use.
    15351537         * FIXME: this needs to consider all the other peers as well... */
     
    15671569        int n;
    15681570        tr_block_index_t * blocks = tr_new( tr_block_index_t, numwant );
    15691571
    1570         tr_peerMgrGetNextRequests( msgs->torrent, msgs->peer, numwant, blocks, &n ); 
     1572        tr_peerMgrGetNextRequests( msgs->torrent, msgs->peer, numwant, blocks, &n );
    15711573
    15721574        for( i=0; i<n; ++i )
    15731575        {
     
    15821584    }
    15831585}
    15841586
     1587static void
     1588prefetchPieces( tr_peermsgs *msgs )
     1589{
     1590    int i;
     1591    uint64_t next = 0;
     1592
     1593    /* Maintain at least 8 prefetched blocks per unchoked peer, but allow
     1594       up to 4 extra blocks if that would cause sequential writes. */
     1595    for( i=msgs->prefetchCount; i<msgs->peerAskedForCount; ++i )
     1596    {
     1597        const struct peer_request * req = msgs->peerAskedFor + i;
     1598        const uint64_t begin = tr_pieceOffset( msgs->torrent, req->index, req->offset, 0 );
     1599        const uint64_t end = begin + req->length;
     1600        const tr_bool isSequential = next == begin;
     1601
     1602        if( ( i >= 12 ) || ( !isSequential && ( i >= 8 ) ) )
     1603            break;
     1604
     1605        tr_ioPrefetch( msgs->torrent, req->index, req->offset, req->length );
     1606        ++msgs->prefetchCount;
     1607
     1608        next = end;
     1609    }
     1610}
     1611
    15851612static size_t
    15861613fillOutputBuffer( tr_peermsgs * msgs, time_t now )
    15871614{
     
    16181645    if( ( tr_peerIoGetWriteBufferSpace( msgs->peer->io, now ) >= msgs->torrent->blockSize )
    16191646        && popNextRequest( msgs, &req ) )
    16201647    {
     1648        --msgs->prefetchCount;
     1649
    16211650        if( requestIsValid( msgs, &req )
    16221651            && tr_cpPieceIsComplete( &msgs->torrent->completion, req.index ) )
    16231652        {
     
    16631692        {
    16641693            protocolSendReject( msgs, &req );
    16651694        }
     1695
     1696        prefetchPieces( msgs );
    16661697    }
    16671698
    16681699    /**