Changeset 11023


Ignore:
Timestamp:
Jul 19, 2010, 2:44:24 PM (12 years ago)
Author:
charles
Message:

(trunk libT) #3427 "use shortest-job-first scheduling for verifying local data" -- patch from wateenellende and sadface

Location:
trunk/libtransmission
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/list.c

    r10524 r11023  
    145145}
    146146
     147void
     148tr_list_insert_sorted( tr_list            ** list,
     149                       void                * data,
     150                       TrListCompareFunc     compare )
     151{
     152    /* find l, the node that we'll insert this data before */
     153    tr_list * l;
     154
     155    for( l = *list; l != NULL; l = l->next )
     156    {
     157        const int c = (compare)( data, l->data );
     158        if( c <= 0 )
     159            break;
     160    }
     161
     162    if( l == NULL )
     163        tr_list_append( list, data );
     164    else if( l == *list )
     165        tr_list_prepend( list, data );
     166    else {
     167        tr_list * node = node_alloc( );
     168        node->data = data;
     169        node->prev = l->prev;
     170        node->next = l;
     171        node->prev->next = node;
     172        node->next->prev = node;
     173    }
     174}
     175
    147176int
    148177tr_list_size( const tr_list * list )
  • trunk/libtransmission/list.h

    r10783 r11023  
    101101                       TrListCompareFunc compare_func );
    102102
     103/**
     104 * @brief Insert in an ordered list
     105 * @param list pointer to the list
     106 * @param item the item to be inserted
     107 * @param compare the comparison function.
     108 */
     109void tr_list_insert_sorted( tr_list          ** list,
     110                            void              * data,
     111                            TrListCompareFunc   compare );
     112
     113
    103114
    104115/* @} */
  • trunk/libtransmission/verify.c

    r10912 r11023  
    185185    tr_torrent *         torrent;
    186186    tr_verify_done_cb    verify_done_cb;
     187    uint64_t             current_size;
    187188};
    188189
     
    253254}
    254255
    255 static tr_bool
    256 torrentHasAnyLocalData( const tr_torrent * tor )
     256static uint64_t
     257getCurrentSize( tr_torrent * tor )
    257258{
    258259    tr_file_index_t i;
    259     tr_bool hasAny = FALSE;
     260    uint64_t byte_count = 0;
    260261    const tr_file_index_t n = tor->info.fileCount;
    261262
    262     assert( tr_isTorrent( tor ) );
    263 
    264     for( i=0; i<n && !hasAny; ++i )
     263    for( i=0; i<n; ++i )
    265264    {
    266265        struct stat sb;
    267         char * path = tr_torrentFindFile( tor, i );
    268         if( ( path != NULL ) && !stat( path, &sb ) && ( sb.st_size > 0 ) )
    269             hasAny = TRUE;
    270         tr_free( path );
    271     }
    272 
    273     return hasAny;
    274 }
     266        char * filename = tr_torrentFindFile( tor, i );
     267
     268        sb.st_size = 0;
     269        if( filename && !stat( filename, &sb ) )
     270            byte_count += sb.st_size;
     271
     272        tr_free( filename );
     273    }
     274
     275    return byte_count;
     276}
     277
     278static int
     279compareVerifyBySize( const void * va, const void * vb )
     280{
     281    const struct verify_node * a = va;
     282    const struct verify_node * b = vb;
     283
     284    if( a->current_size < b->current_size ) return -1;
     285    if( a->current_size > b->current_size ) return  1;
     286    return 0;
     287}
    275288
    276289void
     
    285298        fireCheckDone( tor, verify_done_cb );
    286299    }
    287     else if( !torrentHasAnyLocalData( tor ) )
    288     {
    289         /* we haven't downloaded anything for this torrent yet...
    290          * no need to leave it waiting in the back of the queue.
    291          * we can mark it as all-missing from here and fire
    292          * the "done" callback */
    293         const tr_bool hadAny = tr_cpHaveTotal( &tor->completion ) != 0;
    294         tr_piece_index_t i;
    295         for( i=0; i<tor->info.pieceCount; ++i ) {
    296             tr_torrentSetHasPiece( tor, i, FALSE );
    297             tr_torrentSetPieceChecked( tor, i, TRUE );
    298         }
    299         if( hadAny ) /* if we thought we had some, flag as dirty */
    300             tr_torrentSetDirty( tor );
    301         fireCheckDone( tor, verify_done_cb );
    302     }
    303300    else
    304301    {
    305         struct verify_node * node;
    306 
    307         tr_torinf( tor, "%s", _( "Queued for verification" ) );
    308 
    309         node = tr_new( struct verify_node, 1 );
    310         node->torrent = tor;
    311         node->verify_done_cb = verify_done_cb;
    312 
    313         tr_lockLock( getVerifyLock( ) );
    314         tr_torrentSetVerifyState( tor, TR_VERIFY_WAIT );
    315         tr_list_append( &verifyList, node );
    316         if( verifyThread == NULL )
    317             verifyThread = tr_threadNew( verifyThreadFunc, NULL );
    318         tr_lockUnlock( getVerifyLock( ) );
     302        const uint64_t current_size = getCurrentSize( tor );
     303
     304        if( !current_size )
     305        {
     306            /* we haven't downloaded anything for this torrent yet...
     307             * no need to leave it waiting in the back of the queue.
     308             * we can mark it as all-missing from here and fire
     309             * the "done" callback */
     310            const tr_bool hadAny = tr_cpHaveTotal( &tor->completion ) != 0;
     311            tr_piece_index_t i;
     312            for( i=0; i<tor->info.pieceCount; ++i ) {
     313                tr_torrentSetHasPiece( tor, i, FALSE );
     314                tr_torrentSetPieceChecked( tor, i, TRUE );
     315            }
     316            if( hadAny ) /* if we thought we had some, flag as dirty */
     317                tr_torrentSetDirty( tor );
     318            fireCheckDone( tor, verify_done_cb );
     319        }
     320        else
     321        {
     322            struct verify_node * node;
     323
     324            tr_torinf( tor, "%s", _( "Queued for verification" ) );
     325
     326            node = tr_new( struct verify_node, 1 );
     327            node->torrent = tor;
     328            node->verify_done_cb = verify_done_cb;
     329            node->current_size = current_size;
     330
     331            tr_lockLock( getVerifyLock( ) );
     332            tr_torrentSetVerifyState( tor, TR_VERIFY_WAIT );
     333            tr_list_insert_sorted( &verifyList, node, compareVerifyBySize );
     334            if( verifyThread == NULL )
     335                verifyThread = tr_threadNew( verifyThreadFunc, NULL );
     336            tr_lockUnlock( getVerifyLock( ) );
     337        }
    319338    }
    320339}
Note: See TracChangeset for help on using the changeset viewer.