Ignore:
Timestamp:
Aug 2, 2011, 3:59:54 AM (10 years ago)
Author:
jordan
Message:

#671 "torrent queuing" -- modify the queue implementation s.t. every torrent has a queuePosition, even if it's not currently in the queue.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/torrent.c

    r12609 r12611  
    803803    tor->uniqueId = nextUniqueId++;
    804804    tor->magicNumber = TORRENT_MAGIC_NUMBER;
    805     tor->queuePosition = -1;
     805    tor->queuePosition = session->torrentCount;
    806806
    807807    tr_peerIdInit( tor->peer_id );
     
    871871
    872872    /* add the torrent to tr_session.torrentList */
    873     ++session->torrentCount;
     873    session->torrentCount++;
    874874    if( session->torrentList == NULL )
    875875        session->torrentList = tor;
     
    11061106        return is_seed ? TR_STATUS_SEED : TR_STATUS_DOWNLOAD;
    11071107
    1108     if( tor->queuePosition >= 0 ) {
     1108    if( tr_torrentIsQueued( tor ) ) {
    11091109        if( is_seed && tr_sessionGetQueueEnabled( tor->session, TR_UP ) )
    11101110            return TR_STATUS_SEED_WAIT;
     
    14971497***/
    14981498
     1499static bool queueIsSequenced( tr_session * );
     1500
    14991501static void
    15001502freeTorrent( tr_torrent * tor )
     
    15031505    tr_session *  session = tor->session;
    15041506    tr_info *    inf = &tor->info;
     1507    const time_t now = tr_time( );
    15051508
    15061509    assert( !tor->isRunning );
     
    15261529    }
    15271530
     1531    /* decrement the torrent count */
    15281532    assert( session->torrentCount >= 1 );
    15291533    session->torrentCount--;
     1534
     1535    /* resequence the queue positions */
     1536    t = NULL;
     1537    while(( t = tr_torrentNext( session, tor ))) {
     1538        if( t->queuePosition > tor->queuePosition ) {
     1539            t->queuePosition--;
     1540            t->anyDate = now;
     1541        }
     1542    }
     1543    assert( queueIsSequenced( session ) );
    15301544
    15311545    tr_bandwidthDestruct( &tor->bandwidth );
     
    15411555**/
    15421556
    1543 static void queueRemove( tr_torrent * tor );
     1557static void torrentSetQueued( tr_torrent * tor, bool queued );
    15441558
    15451559static void
     
    15541568
    15551569    tr_torrentRecheckCompleteness( tor );
    1556     queueRemove( tor );
     1570    torrentSetQueued( tor, false );
    15571571
    15581572    now = tr_time( );
     
    16021616    return tr_sessionCountQueueFreeSlots( tor->session, dir ) == 0;
    16031617}
    1604 
    1605 static void queueAppend( tr_torrent * tor );
    16061618
    16071619static void
     
    16311643        case TR_STATUS_STOPPED:
    16321644            if( !bypass_queue && torrentShouldQueue( tor ) ) {
    1633                 queueAppend( tor );
     1645                torrentSetQueued( tor, true );
    16341646                return;
    16351647            }
     
    17551767
    17561768    tr_verifyRemove( tor );
    1757     queueRemove( tor );
     1769    torrentSetQueued( tor, false );
    17581770    tr_peerMgrStopTorrent( tor );
    17591771    tr_announcerTorrentStopped( tor );
     
    31753187
    31763188static bool
    3177 queueIsSequenced( tr_torrent * tor )
     3189queueIsSequenced( tr_session * session )
    31783190{
    31793191    int i ;
    31803192    int n ;
    31813193    bool is_sequenced = true;
    3182     tr_session * session = tor->session;
    3183     tr_direction direction = tr_torrentGetQueueDirection( tor );
     3194    tr_torrent * tor;
    31843195    tr_torrent ** tmp = tr_new( tr_torrent *, session->torrentCount );
    31853196
    3186     /* get all the torrents in that queue */
     3197    /* get all the torrents */
    31873198    n = 0;
    31883199    tor = NULL;
    31893200    while(( tor = tr_torrentNext( session, tor )))
    3190         if( tr_torrentIsQueued( tor ) && ( direction == tr_torrentGetQueueDirection( tor ) ) )
    3191             tmp[n++] = tor;
     3201        tmp[n++] = tor;
    31923202
    31933203    /* sort them by position */
     
    31953205
    31963206#if 0
    3197     /* print them */
    3198     fprintf( stderr, "sequence: " );
     3207    fprintf( stderr, "%s", "queue: " );
    31993208    for( i=0; i<n; ++i )
    32003209        fprintf( stderr, "%d ", tmp[i]->queuePosition );
    3201     fprintf( stderr, "\n" );
     3210    fputc( '\n', stderr );
    32023211#endif
    32033212
     
    32203229tr_torrentSetQueuePosition( tr_torrent * tor, int pos )
    32213230{
    3222     if( tr_torrentIsQueued( tor ) )
    3223     {
    3224         int back = -1;
    3225         tr_torrent * walk;
    3226         const tr_direction direction = tr_torrentGetQueueDirection( tor );
    3227         const int old_pos = tor->queuePosition;
    3228         const time_t now = tr_time( );
    3229 
    3230         if( pos < 0 )
    3231             pos = 0;
    3232 
    3233         tor->queuePosition = -1;
    3234 
    3235         walk = NULL;
    3236         while(( walk = tr_torrentNext( tor->session, walk )))
    3237         {
    3238             if( tr_torrentIsQueued( walk ) && ( tr_torrentGetQueueDirection( walk ) == direction ) )
    3239             {
    3240                 if( old_pos < pos ) {
    3241                     if( ( old_pos <= walk->queuePosition ) && ( walk->queuePosition <= pos ) ) {
    3242                         walk->queuePosition--;
    3243                         walk->anyDate = now;
    3244                     }
    3245                 }
    3246 
    3247                 if( old_pos > pos ) {
    3248                     if( ( pos <= walk->queuePosition ) && ( walk->queuePosition < old_pos ) ) {
    3249                         walk->queuePosition++;
    3250                         walk->anyDate = now;
    3251                     }
    3252                 }
    3253 
    3254                 if( back < walk->queuePosition )
    3255                     back = walk->queuePosition;
     3231    int back = -1;
     3232    tr_torrent * walk;
     3233    const int old_pos = tor->queuePosition;
     3234    const time_t now = tr_time( );
     3235
     3236    if( pos < 0 )
     3237        pos = 0;
     3238
     3239    tor->queuePosition = -1;
     3240
     3241    walk = NULL;
     3242    while(( walk = tr_torrentNext( tor->session, walk )))
     3243    {
     3244        if( old_pos < pos ) {
     3245            if( ( old_pos <= walk->queuePosition ) && ( walk->queuePosition <= pos ) ) {
     3246                walk->queuePosition--;
     3247                walk->anyDate = now;
    32563248            }
    32573249        }
    32583250
    3259         tor->queuePosition = MIN( pos, (back+1) );
    3260         tor->anyDate = now;
    3261     }
    3262 
    3263     assert( queueIsSequenced( tor ) );
     3251        if( old_pos > pos ) {
     3252            if( ( pos <= walk->queuePosition ) && ( walk->queuePosition < old_pos ) ) {
     3253                walk->queuePosition++;
     3254                walk->anyDate = now;
     3255            }
     3256        }
     3257
     3258        if( back < walk->queuePosition )
     3259            back = walk->queuePosition;
     3260    }
     3261
     3262    tor->queuePosition = MIN( pos, (back+1) );
     3263    tor->anyDate = now;
     3264
     3265    assert( queueIsSequenced( tor->session ) );
    32643266}
    32653267
     
    33083310}
    33093311
    3310 /* Ensure that the torrents queued for downloads have queuePositions contiguous from [0...n] */
    33113312static void
    3312 queueResequence( tr_session * session, tr_direction direction )
    3313 {
    3314     int i;
    3315     int n;
    3316     tr_torrent * tor = NULL;
    3317     tr_torrent ** tmp = tr_new( tr_torrent *, session->torrentCount );
    3318     const time_t now = tr_time( );
    3319 
    3320     assert( tr_isSession( session ) );
    3321     assert( tr_isDirection( direction ) );
    3322 
    3323     /* get all the torrents in that queue */
    3324     n = 0;
    3325     while(( tor = tr_torrentNext( session, tor ))) {
    3326         if( direction == tr_torrentGetQueueDirection( tor )) {
    3327             const int position = tr_torrentGetQueuePosition( tor );
    3328             if( position >= 0 )
    3329                 tmp[n++] = tor;
    3330         }
    3331     }
    3332 
    3333     /* sort them by position */
    3334     qsort( tmp, n, sizeof( tr_torrent * ), compareTorrentByQueuePosition );
    3335 
    3336     /* sequence them... */
    3337     for( i=0; i<n; ++i ) {
    3338         tr_torrent * tor = tmp[i];
    3339         if( tor->queuePosition != i ) {
    3340             tor->queuePosition = i;
    3341             tor->anyDate = now;
    3342         }
    3343     }
    3344 
    3345     tr_free( tmp );
    3346 }
    3347 
    3348 static void
    3349 queueRemove( tr_torrent * tor )
    3350 {
    3351     if( tr_torrentIsQueued( tor ) )
    3352     {
    3353         tor->queuePosition = -1;
    3354         queueResequence( tor->session, tr_torrentGetQueueDirection( tor ) );
    3355     }
    3356 }
    3357 
    3358 static void
    3359 queueAppend( tr_torrent * tor )
    3360 {
    3361     if( !tr_torrentIsQueued( tor ) )
    3362     {
    3363         /* tr_torrentSetQueuePosition() requres the torrent to be queued,
    3364            so init tor->queuePosition to the back... */
    3365         tor->queuePosition = INT_MAX;
    3366 
    3367         tr_torrentSetQueuePosition( tor, INT_MAX );
    3368     }
    3369 }
     3313torrentSetQueued( tr_torrent * tor, bool queued )
     3314{
     3315    assert( tr_isTorrent( tor ) );
     3316    assert( tr_isBool( queued ) );
     3317
     3318    if( tr_torrentIsQueued( tor ) != queued )
     3319    {
     3320        tor->isQueued = queued;
     3321        tor->anyDate = tr_time( );
     3322    }
     3323}
Note: See TracChangeset for help on using the changeset viewer.