Changeset 12248


Ignore:
Timestamp:
Mar 28, 2011, 4:31:05 PM (11 years ago)
Author:
jordan
Message:

(trunk libT) break the mac build and introduce new crashes.

This is partially to address #4145 "Downloads stuck at 100%" by refactoring the bitset, bitfield, and tr_completion; however, the ripple effect is larger than usual so things may get worse in the short term before getting better.

livings124: to fix the mac build, remove bitset.[ch] from xcode

Location:
trunk/libtransmission
Files:
2 deleted
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/Makefile.am

    r12141 r12248  
    2424    bencode.c \
    2525    bitfield.c \
    26     bitset.c \
    2726    blocklist.c \
    2827    cache.c \
     
    7675    bencode.h \
    7776    bitfield.h \
    78     bitset.h \
    7977    blocklist.h \
    8078    cache.h \
  • trunk/libtransmission/bitfield.c

    r12096 r12248  
    1616#include "transmission.h"
    1717#include "bitfield.h"
    18 #include "bitset.h"
    1918#include "utils.h" /* tr_new0() */
    2019
    21 const tr_bitfield TR_BITFIELD_INIT = { NULL, 0, 0 };
    22 
    23 tr_bitfield*
    24 tr_bitfieldConstruct( tr_bitfield * b, size_t bitCount )
    25 {
    26     b->bitCount = bitCount;
    27     b->byteCount = ( bitCount + 7u ) / 8u;
    28     b->bits = tr_new0( uint8_t, b->byteCount );
    29     return b;
    30 }
    31 
    32 tr_bitfield*
    33 tr_bitfieldDestruct( tr_bitfield * b )
    34 {
    35     if( b )
    36         tr_free( b->bits );
    37     return b;
    38 }
    39 
    40 tr_bitfield*
    41 tr_bitfieldNew( size_t bitCount )
    42 {
    43     return tr_bitfieldConstruct( tr_new( tr_bitfield, 1 ), bitCount );
    44 }
    45 
    46 void
    47 tr_bitfieldFree( tr_bitfield * b )
    48 {
    49     tr_free( tr_bitfieldDestruct( b ) );
    50 }
    51 
    52 void
    53 tr_bitfieldClear( tr_bitfield * bitfield )
    54 {
    55     memset( bitfield->bits, 0, bitfield->byteCount );
    56 }
    57 
    58 int
    59 tr_bitfieldAdd( tr_bitfield * bitfield,
    60                 size_t        nth )
    61 {
    62     assert( bitfield );
    63     assert( bitfield->bits );
    64 
    65     if( nth >= bitfield->bitCount )
    66         return -1;
    67 
    68     bitfield->bits[nth >> 3u] |= ( 0x80 >> ( nth & 7u ) );
    69     return 0;
    70 }
    71 
    72 /* Sets bit range [begin, end) to 1 */
    73 int
    74 tr_bitfieldAddRange( tr_bitfield * b,
    75                      size_t        begin,
    76                      size_t        end )
    77 {
    78     size_t        sb, eb;
    79     unsigned char sm, em;
    80 
    81     end--;
    82 
    83     if( ( end >= b->bitCount ) || ( begin > end ) )
    84         return -1;
    85 
    86     sb = begin >> 3;
    87     sm = ~( 0xff << ( 8 - ( begin & 7 ) ) );
    88     eb = end >> 3;
    89     em = 0xff << ( 7 - ( end & 7 ) );
    90 
    91     if( sb == eb )
    92     {
    93         b->bits[sb] |= ( sm & em );
    94     }
    95     else
    96     {
    97         b->bits[sb] |= sm;
    98         b->bits[eb] |= em;
    99         if( ++sb < eb )
    100             memset ( b->bits + sb, 0xff, eb - sb );
    101     }
    102 
    103     return 0;
    104 }
    105 
    106 int
    107 tr_bitfieldRem( tr_bitfield * bitfield,
    108                 size_t        nth )
    109 {
    110     assert( bitfield );
    111     assert( bitfield->bits );
    112 
    113     if( nth >= bitfield->bitCount )
    114         return -1;
    115 
    116     bitfield->bits[nth >> 3u] &= ( 0xff7f >> ( nth & 7u ) );
    117     return 0;
    118 }
    119 
    120 /* Clears bit range [begin, end) to 0 */
    121 int
    122 tr_bitfieldRemRange( tr_bitfield * b,
    123                      size_t        begin,
    124                      size_t        end )
    125 {
    126     size_t        sb, eb;
    127     unsigned char sm, em;
    128 
    129     end--;
    130 
    131     if( ( end >= b->bitCount ) || ( begin > end ) )
    132         return -1;
    133 
    134     sb = begin >> 3;
    135     sm = 0xff << ( 8 - ( begin & 7 ) );
    136     eb = end >> 3;
    137     em = ~( 0xff << ( 7 - ( end & 7 ) ) );
    138 
    139     if( sb == eb )
    140     {
    141         b->bits[sb] &= ( sm | em );
    142     }
    143     else
    144     {
    145         b->bits[sb] &= sm;
    146         b->bits[eb] &= em;
    147         if( ++sb < eb )
    148             memset ( b->bits + sb, 0, eb - sb );
    149     }
    150 
    151     return 0;
    152 }
    153 
    154 tr_bitfield*
    155 tr_bitfieldOr( tr_bitfield * a, const tr_bitfield * b )
    156 {
    157     uint8_t * ait = a->bits;
    158     const uint8_t * aend = ait + a->byteCount;
    159     const uint8_t * bit = b->bits;
    160     const uint8_t * bend = bit + b->byteCount;
    161 
    162     while( ait!=aend && bit!=bend )
    163         *ait++ |= *bit++;
    164 
    165     return a;
    166 }
    167 
    168 static const int trueBitCount[256] =
     20const tr_bitfield TR_BITFIELD_INIT = { NULL, 0, 0, 0, false, false };
     21
     22/****
     23*****
     24****/
     25
     26static const int8_t trueBitCount[256] =
    16927{
    17028    0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
     
    18644};
    18745
    188 size_t
    189 tr_bitfieldCountTrueBits( const tr_bitfield* b )
    190 {
    191     size_t           ret = 0;
    192     const uint8_t *  it, *end;
    193 
    194     if( !b )
    195         return 0;
    196 
    197     for( it = b->bits, end = it + b->byteCount; it != end; ++it )
    198         ret += trueBitCount[*it];
    199 
    200     return ret;
    201 }
    202 
    203 size_t
    204 tr_bitfieldCountRange( const tr_bitfield * b, size_t begin, size_t end )
     46static size_t
     47countRange( const tr_bitfield * b, size_t begin, size_t end )
    20548{
    20649    size_t ret = 0;
     
    20851    const int last_byte = ( end - 1 ) >> 3u;
    20952
    210     assert( begin < end );
     53    assert( b->bits != NULL );
    21154
    21255    if( first_byte == last_byte )
     
    25194    return ret;
    25295}
     96
     97size_t
     98tr_bitfieldCountRange( const tr_bitfield * b, size_t begin, size_t end )
     99{
     100    assert( begin < end );
     101
     102    if( tr_bitfieldHasAll( b ) )
     103        return end - begin;
     104
     105    if( tr_bitfieldHasNone( b ) )
     106        return 0;
     107
     108    return countRange( b, begin, end );
     109}
     110
     111/***
     112****
     113***/
     114
     115static bool
     116tr_bitfieldIsValid( const tr_bitfield * b )
     117{
     118    return ( b != NULL )
     119        && ( b->bits || ( tr_bitfieldHasAll( b ) || tr_bitfieldHasNone( b )))
     120        && ( b->byte_count <= b->bit_count )
     121        && ( b->true_count <= b->bit_count )
     122        && ( !b->bits || ( b->true_count == countRange( b, 0, b->bit_count )));
     123}
     124
     125void*
     126tr_bitfieldGetRaw( const tr_bitfield * b, size_t * byte_count )
     127{
     128    uint8_t * bits;
     129
     130    if( b->bits )
     131    {
     132        bits = tr_memdup( b->bits, b->byte_count );
     133    }
     134    else
     135    {
     136        assert( tr_bitfieldHasAll( b ) || tr_bitfieldHasNone( b ) );
     137
     138        bits = tr_new0( uint8_t, b->byte_count );
     139
     140        if( tr_bitfieldHasAll( b ) )
     141        {
     142            uint8_t val = 0xFF;
     143            const int n = b->byte_count - 1;
     144            memset( bits, val, n );
     145            bits[n] = val << (b->byte_count*8 - b->bit_count);
     146        }
     147    }
     148
     149    *byte_count = b->byte_count;
     150    return bits;
     151}
     152
     153static void
     154tr_bitfieldEnsureBitsAlloced( tr_bitfield * b )
     155{
     156    if( b->bits == NULL )
     157        b->bits = tr_bitfieldGetRaw( b, &b->byte_count );
     158
     159    assert( tr_bitfieldIsValid( b ) );
     160}
     161
     162static void
     163tr_bitfieldSetTrueCount( tr_bitfield * b, size_t n )
     164{
     165    b->true_count = n;
     166
     167    if( tr_bitfieldHasAll( b ) || tr_bitfieldHasNone( b ) )
     168    {
     169        tr_free( b->bits );
     170        b->bits = NULL;
     171    }
     172
     173    assert( tr_bitfieldIsValid(  b ) );
     174}
     175
     176static void
     177tr_bitfieldRebuildTrueCount( tr_bitfield * b )
     178{
     179    tr_bitfieldSetTrueCount( b, countRange( b, 0, b->bit_count ) );
     180}
     181
     182static void
     183tr_bitfieldIncTrueCount( tr_bitfield * b, int i )
     184{
     185    tr_bitfieldSetTrueCount( b, b->true_count + i );
     186}
     187
     188/****
     189*****
     190****/
     191
     192void
     193tr_bitfieldConstruct( tr_bitfield * b, size_t bit_count )
     194{
     195    b->bit_count = bit_count;
     196    b->byte_count = ( bit_count + 7u ) / 8u;
     197    b->true_count = 0;
     198    b->bits = NULL;
     199    b->have_all_hint = false;
     200    b->have_none_hint = false;
     201
     202    assert( tr_bitfieldIsValid( b ) );
     203}
     204
     205void
     206tr_bitfieldDestruct( tr_bitfield * b )
     207{
     208    tr_bitfieldSetHasNone( b );
     209}
     210
     211static void
     212tr_bitfieldClear( tr_bitfield * b )
     213{
     214    tr_free( b->bits );
     215    b->bits = NULL;
     216    b->true_count = 0;
     217
     218    assert( tr_bitfieldIsValid( b ) );
     219}
     220
     221void
     222tr_bitfieldSetHasNone( tr_bitfield * b )
     223{
     224    tr_bitfieldClear( b );
     225    b->have_all_hint = false;
     226    b->have_none_hint = true;
     227}
     228
     229void
     230tr_bitfieldSetHasAll( tr_bitfield * b )
     231{
     232    tr_bitfieldClear( b );
     233    b->true_count = b->bit_count;
     234    b->have_all_hint = true;
     235    b->have_none_hint = false;
     236}
     237
     238bool
     239tr_bitfieldSetFromBitfield( tr_bitfield * b, const tr_bitfield * src )
     240{
     241    bool success = true;
     242
     243    if( tr_bitfieldHasAll( src ) )
     244        tr_bitfieldSetHasAll( b );
     245    else if( tr_bitfieldHasNone( src ) )
     246        tr_bitfieldSetHasNone( b );
     247    else
     248        success = tr_bitfieldSetRaw( b, src->bits, src->byte_count );
     249
     250    return success;
     251}
     252
     253bool
     254tr_bitfieldSetRaw( tr_bitfield * b, const void * bits, size_t byte_count )
     255{
     256    const bool success = b->byte_count == byte_count;
     257
     258    if( success )
     259    {
     260        tr_bitfieldSetHasNone( b );
     261        b->bits = tr_memdup( bits, byte_count );
     262        tr_bitfieldRebuildTrueCount( b );
     263    }
     264
     265    return success;
     266}
     267
     268void
     269tr_bitfieldAdd( tr_bitfield * b, size_t nth )
     270{
     271    assert( nth < b->bit_count );
     272
     273    if( !tr_bitfieldHas( b, nth ) )
     274    {
     275        tr_bitfieldEnsureBitsAlloced( b );
     276        b->bits[nth >> 3u] |= ( 0x80 >> ( nth & 7u ) );
     277        tr_bitfieldIncTrueCount( b, 1 );
     278    }
     279}
     280
     281/* Sets bit range [begin, end) to 1 */
     282void
     283tr_bitfieldAddRange( tr_bitfield * b, size_t begin, size_t end )
     284{
     285    size_t sb, eb;
     286    unsigned char sm, em;
     287    const size_t diff = (end-begin) - tr_bitfieldCountRange( b, begin, end );
     288
     289    if( diff == 0 )
     290        return;
     291
     292    end--;
     293    if( ( end >= b->bit_count ) || ( begin > end ) )
     294        return;
     295
     296    sb = begin >> 3;
     297    sm = ~( 0xff << ( 8 - ( begin & 7 ) ) );
     298    eb = end >> 3;
     299    em = 0xff << ( 7 - ( end & 7 ) );
     300
     301    tr_bitfieldEnsureBitsAlloced( b );
     302    if( sb == eb )
     303    {
     304        b->bits[sb] |= ( sm & em );
     305    }
     306    else
     307    {
     308        b->bits[sb] |= sm;
     309        b->bits[eb] |= em;
     310        if( ++sb < eb )
     311            memset ( b->bits + sb, 0xff, eb - sb );
     312    }
     313
     314    tr_bitfieldIncTrueCount( b, diff );
     315}
     316
     317void
     318tr_bitfieldRem( tr_bitfield * b, size_t nth )
     319{
     320    assert( tr_bitfieldIsValid( b ) );
     321
     322    if( !tr_bitfieldHas( b, nth ) )
     323    {
     324        tr_bitfieldEnsureBitsAlloced( b );
     325        b->bits[nth >> 3u] &= ( 0xff7f >> ( nth & 7u ) );
     326        tr_bitfieldIncTrueCount( b, -1 );
     327    }
     328}
     329
     330/* Clears bit range [begin, end) to 0 */
     331void
     332tr_bitfieldRemRange( tr_bitfield * b, size_t begin, size_t end )
     333{
     334    size_t sb, eb;
     335    unsigned char sm, em;
     336    const size_t diff = tr_bitfieldCountRange( b, begin, end );
     337
     338    if( !diff )
     339        return;
     340
     341    end--;
     342
     343    if( ( end >= b->bit_count ) || ( begin > end ) )
     344        return;
     345
     346    sb = begin >> 3;
     347    sm = 0xff << ( 8 - ( begin & 7 ) );
     348    eb = end >> 3;
     349    em = ~( 0xff << ( 7 - ( end & 7 ) ) );
     350
     351    tr_bitfieldEnsureBitsAlloced( b );
     352    if( sb == eb )
     353    {
     354        b->bits[sb] &= ( sm | em );
     355    }
     356    else
     357    {
     358        b->bits[sb] &= sm;
     359        b->bits[eb] &= em;
     360        if( ++sb < eb )
     361            memset ( b->bits + sb, 0, eb - sb );
     362    }
     363
     364    tr_bitfieldIncTrueCount( b, -diff );
     365}
  • trunk/libtransmission/bitfield.h

    r12204 r12248  
    1818#define TR_BITFIELD_H 1
    1919
     20#include <assert.h>
    2021#include "transmission.h"
    2122
     
    2425{
    2526    uint8_t *  bits;
    26     size_t     bitCount;
    27     size_t     byteCount;
     27    size_t     bit_count;
     28    size_t     byte_count;
     29    size_t     true_count;
     30
     31    /* Special cases for when full or empty but we don't know the bitCount.
     32       This occurs when a magnet link's peers send have all / have none */
     33    bool       have_all_hint;
     34    bool       have_none_hint;
    2835}
    2936tr_bitfield;
    3037
     38/***
     39****  life cycle
     40***/
     41
    3142extern const tr_bitfield TR_BITFIELD_INIT;
    3243
    33 tr_bitfield* tr_bitfieldConstruct( tr_bitfield*, size_t bitCount );
     44void   tr_bitfieldConstruct( tr_bitfield*, size_t bit_count );
    3445
    35 tr_bitfield* tr_bitfieldDestruct( tr_bitfield* );
     46void  tr_bitfieldDestruct( tr_bitfield* );
    3647
    37 tr_bitfield* tr_bitfieldNew( size_t bitCount );
     48/***
     49****
     50***/
    3851
    39 void tr_bitfieldFree( tr_bitfield * b );
     52void   tr_bitfieldSetHasAll( tr_bitfield* );
    4053
    41 void         tr_bitfieldClear( tr_bitfield* );
     54void   tr_bitfieldSetHasNone( tr_bitfield* );
    4255
    43 int          tr_bitfieldAdd( tr_bitfield*, size_t bit );
     56void   tr_bitfieldAdd( tr_bitfield*, size_t bit );
    4457
    45 int          tr_bitfieldRem( tr_bitfield*, size_t bit );
     58void   tr_bitfieldRem( tr_bitfield*, size_t bit );
    4659
    47 int          tr_bitfieldAddRange( tr_bitfield *, size_t begin, size_t end );
     60void   tr_bitfieldAddRange( tr_bitfield*, size_t begin, size_t end );
    4861
    49 int          tr_bitfieldRemRange( tr_bitfield*, size_t begin, size_t end );
     62void   tr_bitfieldRemRange( tr_bitfield*, size_t begin, size_t end );
    5063
    51 size_t       tr_bitfieldCountTrueBits( const tr_bitfield* );
     64/***
     65****
     66***/
    5267
    53 size_t       tr_bitfieldCountRange( const tr_bitfield * b, size_t begin, size_t end );
     68bool   tr_bitfieldSetFromBitfield( tr_bitfield*, const tr_bitfield* );
    5469
     70bool   tr_bitfieldSetRaw( tr_bitfield*, const void * bits, size_t byte_count );
    5571
    56 tr_bitfield* tr_bitfieldOr( tr_bitfield*, const tr_bitfield* );
     72void*  tr_bitfieldGetRaw( const tr_bitfield * b, size_t * byte_count );
     73
     74/***
     75****
     76***/
     77
     78size_t  tr_bitfieldCountRange( const tr_bitfield*, size_t begin, size_t end );
     79
     80static inline size_t
     81tr_bitfieldCountTrueBits( const tr_bitfield * b )
     82{
     83    assert( b->true_count == tr_bitfieldCountRange( b, 0, b->bit_count ) );
     84    return b->true_count;
     85}
     86
     87static inline bool
     88tr_bitfieldHasAll( const tr_bitfield * b )
     89{
     90    return b->bit_count ? ( b->true_count == b->bit_count ) : b->have_all_hint;
     91}
     92
     93static inline bool
     94tr_bitfieldHasNone( const tr_bitfield * b )
     95{
     96    return b->bit_count ? ( b->true_count == 0 ) : b->have_none_hint;
     97}
    5798
    5899/** A stripped-down version of bitfieldHas to be used
     
    61102    need to call tr_bitfieldTestFast() first before you
    62103    start looping. */
    63 static inline bool tr_bitfieldHasFast( const tr_bitfield * b, const size_t nth )
     104static inline bool
     105tr_bitfieldHasFast( const tr_bitfield * b, const size_t n )
    64106{
    65     return ( b->bits[nth>>3u] << ( nth & 7u ) & 0x80 ) != 0;
     107    if( tr_bitfieldHasAll( b ) ) return true;
     108    if( tr_bitfieldHasNone( b ) ) return false;
     109    return ( b->bits[n>>3u] << ( n & 7u ) & 0x80 ) != 0;
    66110}
    67111
    68112/** @param high the highest nth bit you're going to access */
    69 static inline bool tr_bitfieldTestFast( const tr_bitfield * b, const size_t high )
     113static inline bool
     114tr_bitfieldTestFast( const tr_bitfield * b, const size_t high )
    70115{
    71116    return ( b != NULL )
    72         && ( b->bits != NULL )
    73         && ( high < b->bitCount );
     117        && ( high < b->bit_count );
    74118}
    75119
    76 static inline bool tr_bitfieldHas( const tr_bitfield * b, size_t nth )
     120static inline bool
     121tr_bitfieldHas( const tr_bitfield * b, size_t n )
    77122{
    78     return tr_bitfieldTestFast( b, nth ) && tr_bitfieldHasFast( b, nth );
     123    return tr_bitfieldTestFast( b, n )
     124        && tr_bitfieldHasFast( b, n );
    79125}
    80126
  • trunk/libtransmission/completion.c

    r12204 r12248  
    1111 */
    1212
    13 #include <string.h> /* memcpy() */
    14 
    1513#include "transmission.h"
    1614#include "completion.h"
     
    2523tr_cpReset( tr_completion * cp )
    2624{
    27     tr_bitsetSetHaveNone( &cp->blockBitset );
    28     tr_free( cp->completeBlocks );
    29     cp->completeBlocks = NULL;
    3025    cp->sizeNow = 0;
    3126    cp->sizeWhenDoneIsDirty = true;
    32     cp->blocksWantedIsDirty = true;
    3327    cp->haveValidIsDirty = true;
    34 }
    35 
    36 tr_completion *
     28    tr_bitfieldSetHasNone( &cp->blockBitfield );
     29}
     30
     31void
    3732tr_cpConstruct( tr_completion * cp, tr_torrent * tor )
    3833{
    3934    cp->tor = tor;
    40     cp->completeBlocks = NULL;
    41     tr_bitsetConstruct( &cp->blockBitset, tor->blockCount );
     35    tr_bitfieldConstruct( &cp->blockBitfield, tor->blockCount );
    4236    tr_cpReset( cp );
    43     return cp;
    44 }
    45 
    46 tr_completion*
     37}
     38
     39void
    4740tr_cpDestruct( tr_completion * cp )
    4841{
    49     tr_free( cp->completeBlocks );
    50     tr_bitsetDestruct( &cp->blockBitset );
    51     return cp;
     42    tr_bitfieldDestruct( &cp->blockBitfield );
     43}
     44
     45bool
     46tr_cpBlockInit( tr_completion * cp, const tr_bitfield * b )
     47{
     48    bool success;
     49
     50    tr_cpReset( cp );
     51
     52    /* set blockBitfield */
     53    success = tr_bitfieldSetFromBitfield( &cp->blockBitfield, b );
     54
     55    /* set sizeNow */
     56    cp->sizeNow = tr_bitfieldCountTrueBits( &cp->blockBitfield );
     57    cp->sizeNow *= cp->tor->blockSize;
     58    if( tr_bitfieldHas( b, cp->tor->blockCount-1 ) )
     59        cp->sizeNow -= ( cp->tor->blockSize - cp->tor->lastBlockSize );
     60
     61    return success;
    5262}
    5363
     
    5969isSeed( const tr_completion * cp )
    6070{
    61     return cp->blockBitset.haveAll;
     71    return tr_bitfieldHasAll( &cp->blockBitfield );
    6272}
    6373
     
    6575tr_cpGetStatus( const tr_completion * cp )
    6676{
     77    if( isSeed( cp ) ) return TR_SEED;
    6778    if( !tr_torrentHasMetadata( cp->tor ) ) return TR_LEECH;
    68     if( cp->sizeNow == cp->tor->info.totalSize ) return TR_SEED;
    6979    if( cp->sizeNow == tr_cpSizeWhenDone( cp ) ) return TR_PARTIAL_SEED;
    7080    return TR_LEECH;
    7181}
    7282
    73 /* how many blocks are in this piece? */
    74 static inline uint16_t
    75 countBlocksInPiece( const tr_torrent * tor, const tr_piece_index_t piece )
    76 {
    77     return piece + 1 == tor->info.pieceCount ? tor->blockCountInLastPiece
    78                                              : tor->blockCountInPiece;
    79 }
    80 
    81 static uint16_t *
    82 getCompleteBlocks( const tr_completion * ccp )
    83 {
    84     if( ccp->completeBlocks == NULL )
    85     {
    86         tr_completion * cp = (tr_completion*) ccp;
    87         cp->completeBlocks = tr_new0( uint16_t, ccp->tor->info.pieceCount );
    88     }
    89 
    90     return ccp->completeBlocks;
    91 }
    92 
    9383void
    9484tr_cpInvalidateDND( tr_completion * cp )
    9585{
    9686    cp->sizeWhenDoneIsDirty = true;
    97     cp->blocksWantedIsDirty = true;
    98 }
    99 
    100 tr_block_index_t
    101 tr_cpBlocksMissing( const tr_completion * ccp )
    102 {
    103     if( isSeed( ccp ) )
    104         return 0;
    105 
    106     if( ccp->blocksWantedIsDirty )
    107     {
    108         tr_piece_index_t   i;
    109         tr_block_index_t   wanted = 0;
    110         tr_block_index_t   complete = 0;
    111         tr_completion    * cp = (tr_completion *) ccp; /* mutable */
    112         const uint16_t   * complete_blocks = getCompleteBlocks( cp );
    113         const tr_torrent * tor = ccp->tor;
    114         const tr_info    * info = &tor->info;
    115 
    116         for( i = 0; i < info->pieceCount; ++i )
    117         {
    118             if( !info->pieces[i].dnd )
    119             {
    120                 wanted += countBlocksInPiece( tor, i );
    121                 complete += complete_blocks[i];
    122             }
    123         }
    124 
    125         cp->blocksWantedLazy = wanted;
    126         cp->blocksWantedCompleteLazy = complete;
    127         cp->blocksWantedIsDirty = false;
    128     }
    129 
    130     return ccp->blocksWantedLazy - ccp->blocksWantedCompleteLazy;
    13187}
    13288
     
    13490tr_cpPieceRem( tr_completion *  cp, tr_piece_index_t piece )
    13591{
    136     tr_block_index_t i;
    137     tr_block_index_t first;
    138     tr_block_index_t last;
     92    tr_block_index_t i, f, l;
    13993    const tr_torrent * tor = cp->tor;
    140     uint16_t * complete_blocks = getCompleteBlocks( cp );
    141 
    142     tr_torGetPieceBlockRange( cp->tor, piece, &first, &last );
    143     for( i=first; i<=last; ++i )
     94
     95    tr_torGetPieceBlockRange( cp->tor, piece, &f, &l );
     96
     97    for( i=f; i<=l; ++i )
    14498        if( tr_cpBlockIsComplete( cp, i ) )
    14599            cp->sizeNow -= tr_torBlockCountBytes( tor, i );
    146100
    147     if( !tor->info.pieces[piece].dnd )
    148         cp->blocksWantedCompleteLazy -= complete_blocks[piece];
    149 
     101    cp->haveValidIsDirty = true;
    150102    cp->sizeWhenDoneIsDirty = true;
    151     cp->haveValidIsDirty = true;
    152     complete_blocks[piece] = 0;
    153     tr_bitsetRemRange( &cp->blockBitset, first, last+1 );
     103    tr_bitfieldRemRange( &cp->blockBitfield, f, l+1 );
    154104}
    155105
     
    157107tr_cpPieceAdd( tr_completion * cp, tr_piece_index_t piece )
    158108{
    159     tr_block_index_t i;
    160     tr_block_index_t first;
    161     tr_block_index_t last;
    162     tr_torGetPieceBlockRange( cp->tor, piece, &first, &last );
    163 
    164     for( i=first; i<=last; ++i )
     109    tr_block_index_t i, f, l;
     110    tr_torGetPieceBlockRange( cp->tor, piece, &f, &l );
     111
     112    for( i=f; i<=l; ++i )
    165113        tr_cpBlockAdd( cp, i );
    166114}
     
    173121    if( !tr_cpBlockIsComplete( cp, block ) )
    174122    {
    175         const tr_piece_index_t piece = tr_torBlockPiece( tor, block );
    176         const int blockSize = tr_torBlockCountBytes( tor, block );
    177 
    178         getCompleteBlocks(cp)[piece]++;
    179 
    180         tr_bitsetAdd( &cp->blockBitset, block );
    181 
    182         cp->sizeNow += blockSize;
    183         if( !tor->info.pieces[piece].dnd )
    184             cp->blocksWantedCompleteLazy++;
    185 
     123        tr_bitfieldAdd( &cp->blockBitfield, block );
     124        cp->sizeNow += tr_torBlockCountBytes( tor, block );
     125
     126        cp->haveValidIsDirty = true;
    186127        cp->sizeWhenDoneIsDirty = true;
    187         cp->haveValidIsDirty = true;
    188     }
    189 }
    190 
    191 
    192 bool
    193 tr_cpBlockBitsetInit( tr_completion * cp, const tr_bitset * blocks )
    194 {
    195     bool success = false;
    196     tr_torrent * tor = cp->tor;
    197 
    198     /* start cp with a state where it thinks we have nothing */
    199     tr_cpReset( cp );
    200 
    201     if( blocks->haveAll )
    202     {
    203         tr_bitsetSetHaveAll( &cp->blockBitset );
    204         cp->sizeNow = tor->info.totalSize;
    205 
    206         success = true;
    207     }
    208     else if( blocks->haveNone )
    209     {
    210         /* already reset... */
    211         success = true;
    212     }
    213     else
    214     {
    215         const tr_bitfield * src = &blocks->bitfield;
    216         tr_bitfield * tgt = &cp->blockBitset.bitfield;
    217 
    218         tr_bitfieldConstruct( tgt, tor->blockCount );
    219 
    220         /* The bitfield of block flags is typically loaded from a resume file.
    221            Test the bitfield's length in case the resume file is corrupt */
    222         if(( success = src->byteCount == tgt->byteCount ))
    223         {
    224             size_t i = 0;
    225             uint16_t * complete_blocks_in_piece = getCompleteBlocks( cp );
    226 
    227             /* init our block bitfield from the one passed in */
    228             memcpy( tgt->bits, src->bits, src->byteCount );
    229 
    230             /* update cp.sizeNow and the cp.blockBitset flags */
    231             i = tr_bitfieldCountTrueBits( tgt );
    232             if( i == tor->blockCount ) {
    233                 tr_bitsetSetHaveAll( &cp->blockBitset );
    234                 cp->sizeNow = cp->tor->info.totalSize;
    235             } else if( !i ) {
    236                 tr_bitsetSetHaveNone( &cp->blockBitset );
    237                 cp->sizeNow = 0;
    238             } else {
    239                 cp->blockBitset.haveAll = cp->blockBitset.haveNone = false;
    240                 cp->sizeNow = tr_bitfieldCountRange( tgt, 0, tor->blockCount-1 );
    241                 cp->sizeNow *= tor->blockSize;
    242                 if( tr_bitfieldHas( tgt, tor->blockCount-1 ) )
    243                     cp->sizeNow += tr_torBlockCountBytes( tor, tor->blockCount-1 );
    244             }
    245 
    246             /* update complete_blocks_in_piece */
    247             for( i=0; i<tor->info.pieceCount; ++i ) {
    248                  tr_block_index_t first, last;
    249                  tr_torGetPieceBlockRange( tor, i, &first, &last );
    250                  complete_blocks_in_piece[i] = tr_bitfieldCountRange( src, first, last+1 );
    251             }
    252         }
    253     }
    254 
    255     return success;
     128    }
    256129}
    257130
     
    265138    if( ccp->haveValidIsDirty )
    266139    {
    267         tr_piece_index_t   i;
    268         uint64_t           size = 0;
    269         tr_completion    * cp = (tr_completion *) ccp; /* mutable */
     140        tr_piece_index_t i;
     141        uint64_t size = 0;
     142        tr_completion * cp = (tr_completion *) ccp; /* mutable */
    270143        const tr_torrent * tor = ccp->tor;
    271         const tr_info    * info = &tor->info;
     144        const tr_info * info = &tor->info;
    272145
    273146        for( i=0; i<info->pieceCount; ++i )
     
    275148                size += tr_torPieceCountBytes( tor, i );
    276149
     150        cp->haveValidLazy = size;
    277151        cp->haveValidIsDirty = false;
    278         cp->haveValidLazy = size;
    279152    }
    280153
     
    287160    if( ccp->sizeWhenDoneIsDirty )
    288161    {
    289         tr_piece_index_t   i;
    290         uint64_t           size = 0;
    291         tr_completion    * cp = (tr_completion *) ccp; /* mutable */
     162        tr_piece_index_t i;
     163        uint64_t size = 0;
     164        tr_completion * cp = (tr_completion *) ccp; /* mutable */
    292165        const tr_torrent * tor = ccp->tor;
    293         const tr_info    * info = &tor->info;
     166        const tr_info * info = &tor->info;
    294167
    295168        for( i=0; i<info->pieceCount; ++i )
     
    297170                size += tr_torPieceCountBytes( tor, i );
    298171
     172        cp->sizeWhenDoneLazy = size;
    299173        cp->sizeWhenDoneIsDirty = false;
    300         cp->sizeWhenDoneLazy = size;
    301174    }
    302175
     
    304177}
    305178
     179uint64_t
     180tr_cpLeftUntilDone( const tr_completion * cp )
     181{
     182    return tr_cpSizeWhenDone( cp ) - cp->sizeNow;
     183}
     184
     185uint64_t
     186tr_cpLeftUntilComplete( const tr_completion * cp )
     187{
     188    return cp->tor->info.totalSize - cp->sizeNow;
     189}
     190
    306191void
    307192tr_cpGetAmountDone( const tr_completion * cp, float * tab, int tabCount )
    308193{
    309194    int i;
     195    const bool seed = isSeed( cp );
    310196    const float interval = cp->tor->info.pieceCount / (float)tabCount;
    311     const bool seed = isSeed( cp );
    312197
    313198    for( i=0; i<tabCount; ++i ) {
     
    315200            tab[i] = 1.0f;
    316201        else {
     202            tr_block_index_t f, l;
    317203            const tr_piece_index_t piece = (tr_piece_index_t)i * interval;
    318             tab[i] = getCompleteBlocks(cp)[piece] / (float)countBlocksInPiece( cp->tor, piece );
     204            tr_torGetPieceBlockRange( cp->tor, piece, &f, &l );
     205            tab[i] = tr_bitfieldCountRange( &cp->blockBitfield, f, l+1 )
     206                                                            / (float)(l+1-f);
    319207        }
    320208    }
    321209}
    322210
    323 int
    324 tr_cpMissingBlocksInPiece( const tr_completion * cp, tr_piece_index_t i )
     211size_t
     212tr_cpMissingBlocksInPiece( const tr_completion * cp, tr_piece_index_t piece )
    325213{
    326214    if( isSeed( cp ) )
    327215        return 0;
    328 
    329     return countBlocksInPiece( cp->tor, i ) - getCompleteBlocks(cp)[i];
     216    else {
     217        tr_block_index_t f, l;
     218        tr_torGetPieceBlockRange( cp->tor, piece, &f, &l );
     219        return (l+1-f) - tr_bitfieldCountRange( &cp->blockBitfield, f, l+1 );
     220    }
     221}
     222
     223size_t
     224tr_cpMissingBytesInPiece( const tr_completion * cp, tr_piece_index_t piece )
     225{
     226    if( isSeed( cp ) )
     227        return 0;
     228    else {
     229        size_t haveBytes = 0;
     230        tr_block_index_t f, l;
     231        tr_torGetPieceBlockRange( cp->tor, piece, &f, &l );
     232        haveBytes = tr_bitfieldCountRange( &cp->blockBitfield, f, l );
     233        haveBytes *= cp->tor->blockSize;
     234        if( tr_bitfieldHas( &cp->blockBitfield, l ) )
     235            haveBytes += tr_torBlockCountBytes( cp->tor, l );
     236        return tr_torPieceCountBytes( cp->tor, piece ) - haveBytes;
     237    }
    330238}
    331239
     
    333241tr_cpFileIsComplete( const tr_completion * cp, tr_file_index_t i )
    334242{
    335     tr_block_index_t f, l;
    336 
    337243    if( cp->tor->info.files[i].length == 0 )
    338244        return true;
    339 
    340     tr_torGetFileBlockRange( cp->tor, i, &f, &l );
    341     return tr_bitsetCountRange( &cp->blockBitset, f, l+1 ) == (l+1-f);
    342 }
    343 
    344 tr_bitfield *
    345 tr_cpCreatePieceBitfield( const tr_completion * cp )
    346 {
    347     tr_piece_index_t i;
     245    else {
     246        tr_block_index_t f, l;
     247        tr_torGetFileBlockRange( cp->tor, i, &f, &l );
     248        return tr_bitfieldCountRange( &cp->blockBitfield, f, l+1 ) == (l+1-f);
     249    }
     250}
     251
     252void *
     253tr_cpCreatePieceBitfield( const tr_completion * cp, size_t * byte_count )
     254{
     255    void * ret;
     256    tr_bitfield pieces;
    348257    const tr_piece_index_t n = cp->tor->info.pieceCount;
    349     tr_bitfield * bf = tr_bitfieldNew( n );
    350 
    351     for( i=0; i<n; ++i )
    352         if( tr_cpPieceIsComplete( cp, i ) )
    353             tr_bitfieldAdd( bf, i );
    354 
    355     return bf;
    356 }
     258    tr_bitfieldConstruct( &pieces, n );
     259
     260    if( tr_cpHasAll( cp ) )
     261        tr_bitfieldSetHasAll( &pieces );
     262    else if( !tr_cpHasNone( cp ) ) {
     263        tr_piece_index_t i;
     264        for( i=0; i<n; ++i )
     265            if( tr_cpPieceIsComplete( cp, i ) )
     266                tr_bitfieldAdd( &pieces, i );
     267    }
     268
     269    ret = tr_bitfieldGetRaw( &pieces, byte_count );
     270    tr_bitfieldDestruct( &pieces );
     271    return ret;
     272}
     273
     274double
     275tr_cpPercentComplete( const tr_completion * cp )
     276{
     277    const double ratio = tr_getRatio( cp->sizeNow, cp->tor->info.totalSize );
     278
     279    if( (int)ratio == TR_RATIO_NA )
     280        return 0.0;
     281    else if( (int)ratio == TR_RATIO_INF )
     282        return 1.0;
     283    else
     284        return ratio;
     285}
     286
     287double
     288tr_cpPercentDone( const tr_completion * cp )
     289{
     290    const double ratio = tr_getRatio( cp->sizeNow, tr_cpSizeWhenDone( cp ) );
     291    const int iratio = (int)ratio;
     292    return ((iratio == TR_RATIO_NA) || (iratio == TR_RATIO_INF)) ? 0.0 : ratio;
     293}
  • trunk/libtransmission/completion.h

    r12204 r12248  
    1818#define TR_COMPLETION_H
    1919
    20 #include <assert.h>
    21 
    2220#include "transmission.h"
    23 #include "bitset.h"
     21#include "bitfield.h"
    2422#include "utils.h" /* tr_getRatio() */
    2523
    2624typedef struct tr_completion
    2725{
    28     bool  sizeWhenDoneIsDirty;
    29     bool  blocksWantedIsDirty;
    30     bool  haveValidIsDirty;
    31 
    32     tr_torrent *    tor;
     26    tr_torrent * tor;
    3327
    3428    /* do we have this block? */
    35     tr_bitset    blockBitset;
    36 
    37     /* a block is complete if and only if we have it */
    38     uint16_t *  completeBlocks;
    39 
    40     /* total number of blocks that we want downloaded
    41        DON'T access this directly; it's a lazy field.
    42        Used by tr_cpBlocksMissing(). */
    43     tr_block_index_t    blocksWantedLazy;
    44 
    45     /* total number of completed blocks that we want downloaded
    46        DON'T access this directly; it's a lazy field.
    47        Used by tr_cpBlocksMissing(). */
    48     tr_block_index_t    blocksWantedCompleteLazy;
     29    tr_bitfield blockBitfield;
    4930
    5031    /* number of bytes we'll have when done downloading. [0..info.totalSize]
    5132       DON'T access this directly; it's a lazy field.
    5233       use tr_cpSizeWhenDone() instead! */
    53     uint64_t    sizeWhenDoneLazy;
     34    uint64_t sizeWhenDoneLazy;
     35
     36    /* whether or not sizeWhenDone needs to be recalculated */
     37    bool sizeWhenDoneIsDirty;
    5438
    5539    /* number of bytes we'll have when done downloading. [0..info.totalSize]
    5640       DON'T access this directly; it's a lazy field.
    5741       use tr_cpHaveValid() instead! */
    58     uint64_t    haveValidLazy;
     42    uint64_t haveValidLazy;
     43
     44    /* whether or not haveValidLazy needs to be recalculated */
     45    bool haveValidIsDirty;
    5946
    6047    /* number of bytes we want or have now. [0..sizeWhenDone] */
    61     uint64_t    sizeNow;
     48    uint64_t sizeNow;
    6249}
    6350tr_completion;
     
    6754**/
    6855
    69 tr_completion * tr_cpConstruct( tr_completion *, tr_torrent * );
     56void              tr_cpConstruct( tr_completion *, tr_torrent * );
    7057
    71 tr_completion * tr_cpDestruct( tr_completion * );
     58void              tr_cpDestruct( tr_completion * );
    7259
    7360/**
     
    7562**/
    7663
    77 tr_completeness    tr_cpGetStatus( const tr_completion * );
     64double            tr_cpPercentComplete( const tr_completion * cp );
    7865
    79 uint64_t           tr_cpHaveValid( const tr_completion * );
     66double            tr_cpPercentDone( const tr_completion * cp );
    8067
    81 tr_block_index_t   tr_cpBlocksMissing( const tr_completion * );
     68tr_completeness   tr_cpGetStatus( const tr_completion * );
    8269
    83 uint64_t           tr_cpSizeWhenDone( const tr_completion * );
     70uint64_t          tr_cpHaveValid( const tr_completion * );
    8471
    85 void               tr_cpInvalidateDND( tr_completion * );
     72uint64_t          tr_cpSizeWhenDone( const tr_completion * );
    8673
    87 void               tr_cpGetAmountDone( const   tr_completion * completion,
    88                                        float                 * tab,
    89                                        int                     tabCount );
     74uint64_t          tr_cpLeftUntilComplete( const tr_completion * );
     75
     76uint64_t          tr_cpLeftUntilDone( const tr_completion * );
     77
     78void              tr_cpGetAmountDone( const   tr_completion * completion,
     79                                      float                 * tab,
     80                                      int                     tabCount );
     81
     82static inline bool tr_cpHasAll( const tr_completion * cp )
     83{
     84    return tr_bitfieldHasAll( &cp->blockBitfield );
     85}
     86
     87static inline bool tr_cpHasNone( const tr_completion * cp )
     88{
     89    return tr_bitfieldHasNone( &cp->blockBitfield );
     90}
    9091
    9192static inline uint64_t tr_cpHaveTotal( const tr_completion * cp )
     
    9495}
    9596
    96 static inline uint64_t tr_cpLeftUntilComplete( const tr_completion * cp )
    97 {
    98     return tr_torrentInfo(cp->tor)->totalSize - cp->sizeNow;
    99 }
    100 
    101 static inline uint64_t tr_cpLeftUntilDone( const tr_completion * cp )
    102 {
    103     return tr_cpSizeWhenDone( cp ) - cp->sizeNow;
    104 }
    105 
    106 static inline double tr_cpPercentComplete( const tr_completion * cp )
    107 {
    108     const double ratio = tr_getRatio( cp->sizeNow, tr_torrentInfo(cp->tor)->totalSize );
    109     if( (int)ratio == TR_RATIO_NA )
    110         return 0.0;
    111     else if( (int)ratio == TR_RATIO_INF )
    112         return 1.0;
    113     else
    114         return ratio;
    115 }
    116 
    117 static inline double tr_cpPercentDone( const tr_completion * cp )
    118 {
    119     const double ratio = tr_getRatio( cp->sizeNow, tr_cpSizeWhenDone( cp ) );
    120     const int iratio = (int)ratio;
    121     return ((iratio == TR_RATIO_NA) || (iratio == TR_RATIO_INF)) ? 0.0 : ratio;
    122 }
    123 
    12497/**
    125 *** Pieces
     98***  Pieces
    12699**/
    127100
    128 int tr_cpMissingBlocksInPiece( const tr_completion * cp, tr_piece_index_t i );
     101void    tr_cpPieceAdd( tr_completion * cp, tr_piece_index_t i );
     102
     103void    tr_cpPieceRem( tr_completion * cp, tr_piece_index_t i );
     104
     105size_t  tr_cpMissingBlocksInPiece( const tr_completion *, tr_piece_index_t );
     106
     107size_t  tr_cpMissingBytesInPiece ( const tr_completion *, tr_piece_index_t );
    129108
    130109static inline bool
     
    134113}
    135114
    136 void tr_cpPieceAdd( tr_completion * cp, tr_piece_index_t i );
    137 
    138 void tr_cpPieceRem( tr_completion * cp, tr_piece_index_t i );
    139 
    140 bool tr_cpFileIsComplete( const tr_completion * cp, tr_file_index_t );
    141 
    142115/**
    143 *** Blocks
     116***  Blocks
    144117**/
    145118
     
    147120tr_cpBlockIsComplete( const tr_completion * cp, tr_block_index_t i )
    148121{
    149     return tr_bitsetHas( &cp->blockBitset, i );
     122    return tr_bitfieldHas( &cp->blockBitfield, i );
    150123}
    151124
    152 void tr_cpBlockAdd( tr_completion * cp, tr_block_index_t i );
     125void  tr_cpBlockAdd( tr_completion * cp, tr_block_index_t i );
    153126
    154 bool tr_cpBlockBitsetInit( tr_completion * cp, const tr_bitset * blocks );
     127bool  tr_cpBlockInit( tr_completion * cp, const tr_bitfield * blocks );
    155128
    156129/***
    157 ****
     130****  Misc
    158131***/
    159132
    160 static inline const tr_bitset *
    161 tr_cpBlockBitset( const tr_completion * cp )
    162 {
    163     return &cp->blockBitset;
    164 }
     133bool  tr_cpFileIsComplete( const tr_completion * cp, tr_file_index_t );
    165134
    166 tr_bitfield * tr_cpCreatePieceBitfield( const tr_completion * cp );
     135void  tr_cpInvalidateDND( tr_completion * );
     136
     137void* tr_cpCreatePieceBitfield( const tr_completion * cp, size_t * byte_count );
     138
    167139
    168140#endif
  • trunk/libtransmission/peer-io.c

    r12233 r12248  
    130130
    131131    dbgmsg( io, "canRead" );
     132
     133fprintf( stderr, "[%p] in canRead; refcount is %d (%s:%d)\n", io, io->refCount, __FILE__, __LINE__ );
    132134
    133135    tr_peerIoRef( io );
     
    569571        UTP_SetSockopt( utp_socket, SO_RCVBUF, UTP_READ_BUFFER_SIZE );
    570572        dbgmsg( io, "%s", "calling UTP_SetCallbacks &utp_function_table" );
     573fprintf( stderr, "[%p] setting utp callbacks (%s:%d)\n", io, __FILE__, __LINE__ );
    571574        UTP_SetCallbacks( utp_socket,
    572575                          &utp_function_table,
     
    607610{
    608611    int fd = -1;
    609     struct UTPSocket *utp_socket = NULL;
     612    struct UTPSocket * utp_socket = NULL;
    610613
    611614    assert( session );
     
    722725#ifdef WITH_UTP
    723726    if( io->utp_socket ) {
     727fprintf( stderr, "[%p] clearing utp callbacks (%s:%d)\n", io, __FILE__, __LINE__ );
    724728        UTP_SetCallbacks( io->utp_socket,
    725729                          &dummy_utp_function_table,
  • trunk/libtransmission/peer-mgr.c

    r12229 r12248  
    375375    memset( peer, 0, sizeof( tr_peer ) );
    376376
    377     peer->have = TR_BITSET_INIT;
     377    peer->have = TR_BITFIELD_INIT;
    378378
    379379    tr_historyConstruct( &peer->blocksSentToClient,  CANCEL_HISTORY_SEC, ( RECHOKE_PERIOD_MSEC / 1000 ) );
     
    407407    {
    408408        peer = peerNew( atom );
     409        tr_bitfieldConstruct( &peer->have, torrent->tor->blockCount );
     410        tr_bitfieldConstruct( &peer->blame, torrent->tor->blockCount );
    409411        tr_ptrArrayInsertSorted( &torrent->peers, peer, peerCompare );
    410412    }
     
    420422    assert( peer != NULL );
    421423
    422     peerDeclinedAllRequests( tor->torrentPeers, peer );
     424    if( tor->torrentPeers->isRunning )
     425        peerDeclinedAllRequests( tor->torrentPeers, peer );
    423426
    424427    if( peer->msgs != NULL )
     
    426429
    427430    if( peer->io ) {
     431fprintf( stderr, "[%p] peer %p clearing/unreffing its io (%s:%d)\n", peer->io, peer, __FILE__, __LINE__ );
    428432        tr_peerIoClear( peer->io );
    429433        tr_peerIoUnref( peer->io ); /* balanced by the ref in handshakeDoneCB() */
     
    435439    tr_historyDestruct( &peer->cancelsSentToPeer   );
    436440
    437     tr_bitsetDestruct( &peer->have );
    438     tr_bitfieldFree( peer->blame );
     441    tr_bitfieldDestruct( &peer->have );
     442    tr_bitfieldDestruct( &peer->blame );
    439443    tr_free( peer->client );
    440444
     
    483487
    484488        for( peer_i=0; peer_i<peer_count; ++peer_i )
    485             if( tr_bitsetHas( &peers[peer_i]->have, piece_i ) )
     489            if( tr_bitfieldHas( &peers[peer_i]->have, piece_i ) )
    486490                ++r;
    487491
     
    867871}
    868872
     873static bool
     874testForEndgame( const Torrent * t )
     875{
     876    /* we consider ourselves to be in endgame if the number of bytes
     877       we've got requested is >= the number of bytes left to download */
     878    return ( t->requestCount * t->tor->blockSize )
     879               <= tr_cpLeftUntilDone( &t->tor->completion );
     880}
     881
    869882static void
    870883updateEndgame( Torrent * t )
    871884{
    872     const tr_torrent * tor = t->tor;
    873     const tr_block_index_t missing = tr_cpBlocksMissing( &tor->completion );
    874 
    875885    assert( t->requestCount >= 0 );
    876886
    877     if( (tr_block_index_t) t->requestCount < missing )
     887    if( !testForEndgame( t ) )
    878888    {
    879889        /* not in endgame */
     
    12681278 */
    12691279static void
    1270 tr_decrReplicationFromBitset( Torrent * t, const tr_bitset * bitset )
     1280tr_decrReplicationFromBitfield( Torrent * t, const tr_bitfield * b )
    12711281{
    12721282    int i;
     
    12761286    assert( t->pieceReplicationSize == t->tor->info.pieceCount );
    12771287
    1278     if( bitset->haveAll )
     1288    if( tr_bitfieldHasAll( b ) )
    12791289    {
    12801290        for( i=0; i<n; ++i )
    12811291            --t->pieceReplication[i];
    12821292    }
    1283     else if ( !bitset->haveNone )
    1284     {
    1285         const tr_bitfield * const b = &bitset->bitfield;
    1286 
     1293    else if ( !tr_bitfieldHasNone( b ) )
     1294    {
    12871295        for( i=0; i<n; ++i )
    12881296            if( tr_bitfieldHas( b, i ) )
     
    13171325    Torrent * t;
    13181326    struct weighted_piece * pieces;
    1319     const tr_bitset * have = &peer->have;
     1327    const tr_bitfield * const have = &peer->have;
    13201328
    13211329    /* sanity clause */
     
    13461354
    13471355        /* if the peer has this piece that we want... */
    1348         if( tr_bitsetHas( have, p->index ) )
     1356        if( tr_bitfieldHas( have, p->index ) )
    13491357        {
    13501358            tr_block_index_t b;
     
    22132221        {
    22142222            tr_peer * peer = peers[i];
    2215             if( tr_bitfieldHas( peer->blame, pieceIndex ) )
     2223            if( tr_bitfieldHas( &peer->blame, pieceIndex ) )
    22162224            {
    22172225                tordbg( t, "peer %s contributed to corrupt piece (%d); now has %d strikes",
     
    24032411stopTorrent( Torrent * t )
    24042412{
    2405     int i, n;
     2413    tr_peer * peer;
    24062414
    24072415    t->isRunning = false;
     
    24112419
    24122420    /* disconnect the peers. */
    2413     for( i=0, n=tr_ptrArraySize( &t->peers ); i<n; ++i )
    2414         peerDelete( t, tr_ptrArrayNth( &t->peers, i ) );
    2415     tr_ptrArrayClear( &t->peers );
     2421    while(( peer = tr_ptrArrayPop( &t->peers )))
     2422        peerDelete( t, peer );
    24162423
    24172424    /* disconnect the handshakes. handshakeAbort calls handshakeDoneCB(),
     
    24532460tr_peerUpdateProgress( tr_torrent * tor, tr_peer * peer )
    24542461{
    2455     const tr_bitset * have = &peer->have;
    2456 
    2457     if( have->haveAll )
     2462    const tr_bitfield * have = &peer->have;
     2463
     2464    if( tr_bitfieldHasAll( have ) )
    24582465    {
    24592466        peer->progress = 1.0;
    24602467    }
    2461     else if( have->haveNone )
     2468    else if( tr_bitfieldHasNone( have ) )
    24622469    {
    24632470        peer->progress = 0.0;
     
    24652472    else
    24662473    {
    2467         const float trueCount = tr_bitfieldCountTrueBits( &have->bitfield );
     2474        const float true_count = tr_bitfieldCountTrueBits( have );
    24682475
    24692476        if( tr_torrentHasMetadata( tor ) )
    2470             peer->progress = trueCount / tor->info.pieceCount;
     2477            peer->progress = true_count / tor->info.pieceCount;
    24712478        else /* without pieceCount, this result is only a best guess... */
    2472             peer->progress = trueCount / ( have->bitfield.bitCount + 1 );
     2479            peer->progress = true_count / ( have->bit_count + 1 );
    24732480    }
    24742481
     
    25172524                int j;
    25182525                for( j=0; j<peerCount; ++j )
    2519                     if( tr_bitsetHas( &peers[j]->have, piece ) )
     2526                    if( tr_bitfieldHas( &peers[j]->have, piece ) )
    25202527                        ++tab[i];
    25212528            }
     
    25242531}
    25252532
    2526 /* Returns the pieces that are available from peers */
    2527 tr_bitfield*
    2528 tr_peerMgrGetAvailable( const tr_torrent * tor )
    2529 {
    2530     int i;
    2531     Torrent * t = tor->torrentPeers;
    2532     const int peerCount = tr_ptrArraySize( &t->peers );
    2533     const tr_peer ** peers = (const tr_peer**) tr_ptrArrayBase( &t->peers );
    2534     tr_bitfield * pieces = tr_bitfieldNew( t->tor->info.pieceCount );
    2535 
    2536     assert( tr_torrentIsLocked( tor ) );
    2537 
    2538     for( i=0; i<peerCount; ++i )
    2539         tr_bitsetOr( pieces, &peers[i]->have );
    2540 
    2541     return pieces;
     2533static bool
     2534peerIsSeed( const tr_peer * peer )
     2535{
     2536    if( peer->progress >= 1.0 )
     2537        return true;
     2538
     2539    if( peer->atom && atomIsSeed( peer->atom ) )
     2540        return true;
     2541
     2542    return false;
     2543}
     2544
     2545/* count how many pieces we want that connected peers have */
     2546uint64_t
     2547tr_peerMgrGetDesiredAvailable( const tr_torrent * tor )
     2548{
     2549    size_t i;
     2550    size_t n;
     2551    uint64_t desiredAvailable;
     2552    const Torrent * t = tor->torrentPeers;
     2553
     2554    /* common shortcuts... */
     2555
     2556    if( tr_torrentIsSeed( t->tor ) )
     2557        return 0;
     2558
     2559    if( !tr_torrentHasMetadata( tor ) )
     2560        return 0;
     2561
     2562    n = tr_ptrArraySize( &t->peers );
     2563    if( n == 0 )
     2564        return 0;
     2565    else {
     2566        const tr_peer ** peers = (const tr_peer**) tr_ptrArrayBase( &t->peers );
     2567        for( i=0; i<n; ++i )
     2568            if( peers[i]->atom && atomIsSeed( peers[i]->atom ) )
     2569                return tr_cpLeftUntilDone( &tor->completion );
     2570    }
     2571
     2572    if( !t->pieceReplication || !t->pieceReplicationSize )
     2573        return 0;
     2574
     2575    /* do it the hard way */
     2576
     2577    desiredAvailable = 0;
     2578    for( i=0, n=tor->info.pieceCount; i<n; ++i )
     2579    {
     2580        if( tor->info.pieces[i].dnd )
     2581            continue;
     2582        if( t->pieceReplicationSize >= i )
     2583            continue;
     2584        if( t->pieceReplication[i] == 0 )
     2585            continue;
     2586
     2587        desiredAvailable += tr_cpMissingBytesInPiece( &t->tor->completion, i );
     2588    }
     2589
     2590    return desiredAvailable;
    25422591}
    25432592
     
    25452594tr_peerMgrTorrentStats( tr_torrent  * tor,
    25462595                        int         * setmePeersConnected,
    2547                         int         * setmeSeedsConnected,
    25482596                        int         * setmeWebseedsSendingToUs,
    25492597                        int         * setmePeersSendingToUs,
     
    25612609
    25622610    *setmePeersConnected       = 0;
    2563     *setmeSeedsConnected       = 0;
    25642611    *setmePeersGettingFromUs   = 0;
    25652612    *setmePeersSendingToUs     = 0;
     
    25862633        if( clientIsUploadingTo( peer ) )
    25872634            ++*setmePeersGettingFromUs;
    2588 
    2589         if( atomIsSeed( atom ) )
    2590             ++*setmeSeedsConnected;
    25912635    }
    25922636
     
    26242668{
    26252669    return peer->io ? tr_peerIoGetPieceSpeed_Bps( peer->io, now, direction ) : 0.0;
    2626 }
    2627 
    2628 static bool
    2629 peerIsSeed( const tr_peer * peer )
    2630 {
    2631     if( peer->progress >= 1.0 )
    2632         return true;
    2633 
    2634     if( peer->atom && atomIsSeed( peer->atom ) )
    2635         return true;
    2636 
    2637     return false;
    26382670}
    26392671
     
    27352767    return ( !tor->info.pieces[index].dnd ) /* we want it */
    27362768        && ( !tr_cpPieceIsComplete( &tor->completion, index ) )  /* we don't have it */
    2737         && ( tr_bitsetHas( &peer->have, index ) ); /* peer has it */
     2769        && ( tr_bitfieldHas( &peer->have, index ) ); /* peer has it */
    27382770}
    27392771
     
    32343266
    32353267    if( replicationExists( t ) )
    3236         tr_decrReplicationFromBitset( t, &peer->have );
     3268        tr_decrReplicationFromBitfield( t, &peer->have );
    32373269
    32383270    assert( removed == peer );
  • trunk/libtransmission/peer-mgr.h

    r12229 r12248  
    2525
    2626#include "bitfield.h"
    27 #include "bitset.h"
    2827#include "history.h"
    2928#include "net.h" /* tr_address */
     
    111110    struct peer_atom       * atom;
    112111
    113     struct tr_bitfield     * blame;
    114     struct tr_bitset         have;
     112    struct tr_bitfield       blame;
     113    struct tr_bitfield       have;
    115114
    116115    /** how complete the peer's copy of the torrent is. [0.0...1.0] */
     
    230229                                    unsigned int       tabCount );
    231230
    232 struct tr_bitfield* tr_peerMgrGetAvailable( const tr_torrent * tor );
     231uint64_t tr_peerMgrGetDesiredAvailable( const tr_torrent * tor );
    233232
    234233void tr_peerMgrOnTorrentGotMetainfo( tr_torrent * tor );
     
    238237void tr_peerMgrTorrentStats( tr_torrent * tor,
    239238                             int * setmePeersConnected,
    240                              int * setmeSeedsConnected,
    241239                             int * setmeWebseedsSendingToUs,
    242240                             int * setmePeersSendingToUs,
  • trunk/libtransmission/peer-msgs.c

    r12233 r12248  
    1414#include <errno.h>
    1515#include <stdarg.h>
    16 #include <stdio.h>
    1716#include <stdlib.h>
    1817#include <string.h>
     
    217216***
    218217**/
    219 
    220 #if 0
    221 static tr_bitfield*
    222 getHave( const struct tr_peermsgs * msgs )
    223 {
    224     if( msgs->peer->have == NULL )
    225         msgs->peer->have = tr_bitfieldNew( msgs->torrent->info.pieceCount );
    226     return msgs->peer->have;
    227 }
    228 #endif
    229218
    230219static inline tr_session*
     
    14181407
    14191408            /* a peer can send the same HAVE message twice... */
    1420             if( !tr_bitsetHas( &msgs->peer->have, ui32 ) ) {
    1421                 tr_bitsetAdd( &msgs->peer->have, ui32 );
     1409            if( !tr_bitfieldHas( &msgs->peer->have, ui32 ) ) {
     1410                tr_bitfieldAdd( &msgs->peer->have, ui32 );
    14221411                fireClientGotHave( msgs, ui32 );
    14231412            }
     
    14261415
    14271416        case BT_BITFIELD: {
    1428             tr_bitfield tmp = TR_BITFIELD_INIT;
    1429             const size_t bitCount = tr_torrentHasMetadata( msgs->torrent )
    1430                                   ? msgs->torrent->info.pieceCount
    1431                                   : msglen * 8;
    1432             tr_bitfieldConstruct( &tmp, bitCount );
     1417            uint8_t * tmp = tr_new( uint8_t, msglen );
    14331418            dbgmsg( msgs, "got a bitfield" );
    1434             tr_peerIoReadBytes( msgs->peer->io, inbuf, tmp.bits, msglen );
    1435             tr_bitsetSetBitfield( &msgs->peer->have, &tmp );
    1436             fireClientGotBitfield( msgs, &tmp );
    1437             tr_bitfieldDestruct( &tmp );
     1419            tr_peerIoReadBytes( msgs->peer->io, inbuf, tmp, msglen );
     1420            tr_bitfieldSetRaw( &msgs->peer->have, tmp, msglen );
     1421            fireClientGotBitfield( msgs, &msgs->peer->have );
    14381422            updatePeerProgress( msgs );
     1423            tr_free( tmp );
    14391424            break;
    14401425        }
     
    15111496            dbgmsg( msgs, "Got a BT_FEXT_HAVE_ALL" );
    15121497            if( fext ) {
    1513                 tr_bitsetSetHaveAll( &msgs->peer->have );
     1498                tr_bitfieldSetHasAll( &msgs->peer->have );
     1499assert( tr_bitfieldHasAll( &msgs->peer->have ) );
    15141500                fireClientGotHaveAll( msgs );
    15151501                updatePeerProgress( msgs );
     
    15231509            dbgmsg( msgs, "Got a BT_FEXT_HAVE_NONE" );
    15241510            if( fext ) {
    1525                 tr_bitsetSetHaveNone( &msgs->peer->have );
     1511                tr_bitfieldSetHasNone( &msgs->peer->have );
    15261512                fireClientGotHaveNone( msgs );
    15271513                updatePeerProgress( msgs );
     
    15661552}
    15671553
    1568 static void
    1569 addPeerToBlamefield( tr_peermsgs * msgs, uint32_t index )
    1570 {
    1571     if( !msgs->peer->blame )
    1572          msgs->peer->blame = tr_bitfieldNew( msgs->torrent->info.pieceCount );
    1573     tr_bitfieldAdd( msgs->peer->blame, index );
    1574 }
    1575 
    15761554/* returns 0 on success, or an errno on failure */
    15771555static int
     
    16111589        return err;
    16121590
    1613     addPeerToBlamefield( msgs, req->index );
     1591    tr_bitfieldAdd( &msgs->peer->blame, req->index );
    16141592    fireGotBlock( msgs, req );
    16151593    return 0;
     
    20161994sendBitfield( tr_peermsgs * msgs )
    20171995{
     1996    size_t byte_count = 0;
    20181997    struct evbuffer * out = msgs->outMessages;
    2019     tr_bitfield * bf = tr_cpCreatePieceBitfield( &msgs->torrent->completion );
    2020 
    2021     evbuffer_add_uint32( out, sizeof( uint8_t ) + bf->byteCount );
     1998    void * bytes = tr_cpCreatePieceBitfield( &msgs->torrent->completion, &byte_count );
     1999
     2000    evbuffer_add_uint32( out, sizeof( uint8_t ) + byte_count );
    20222001    evbuffer_add_uint8 ( out, BT_BITFIELD );
    2023     evbuffer_add       ( out, bf->bits, bf->byteCount );
     2002    evbuffer_add       ( out, bytes, byte_count );
    20242003    dbgmsg( msgs, "sending bitfield... outMessage size is now %zu", evbuffer_get_length( out ) );
    20252004    pokeBatchPeriod( msgs, IMMEDIATE_PRIORITY_INTERVAL_SECS );
    20262005
    2027     tr_bitfieldFree( bf );
     2006    tr_free( bytes );
    20282007}
    20292008
     
    20332012    const bool fext = tr_peerIoSupportsFEXT( msgs->peer->io );
    20342013
    2035     if( fext && ( tr_cpBlockBitset( &msgs->torrent->completion )->haveAll ) )
     2014    if( fext && tr_cpHasAll( &msgs->torrent->completion ) )
    20362015    {
    20372016        protocolSendHaveAll( msgs );
    20382017    }
    2039     else if( fext && ( tr_cpBlockBitset( &msgs->torrent->completion )->haveNone ) )
     2018    else if( fext && tr_cpHasNone( &msgs->torrent->completion ) )
    20402019    {
    20412020        protocolSendHaveNone( msgs );
    20422021    }
    2043     else
     2022    else if( !tr_cpHasNone( &msgs->torrent->completion ) )
    20442023    {
    20452024        sendBitfield( msgs );
  • trunk/libtransmission/resume.c

    r12204 r12248  
    1717#include "transmission.h"
    1818#include "bencode.h"
    19 #include "bitset.h"
    2019#include "completion.h"
    2120#include "metainfo.h" /* tr_metainfoGetBasename() */
     
    410409
    411410static void
     411bitfieldToBenc( const tr_bitfield * b, tr_benc * benc )
     412{
     413    if( tr_bitfieldHasAll( b ) )
     414        tr_bencInitStr( benc, "all", 3 );
     415    else if( tr_bitfieldHasNone( b ) )
     416        tr_bencInitStr( benc, "none", 4 );
     417    else
     418        tr_bencInitRaw( benc, b->bits, b->byte_count );
     419}
     420
     421
     422static void
    412423saveProgress( tr_benc * dict, tr_torrent * tor )
    413424{
     
    470481
    471482    /* add the blocks bitfield */
    472     tr_bitsetToBenc( tr_cpBlockBitset( &tor->completion ),
    473                      tr_bencDictAdd( prog, KEY_PROGRESS_BLOCKS ) );
     483    bitfieldToBenc( &tor->completion.blockBitfield,
     484                    tr_bencDictAdd( prog, KEY_PROGRESS_BLOCKS ) );
    474485}
    475486
     
    493504        tr_benc * l;
    494505        tr_benc * b;
    495         struct tr_bitset bitset = TR_BITSET_INIT;
     506        struct tr_bitfield blocks = TR_BITFIELD_INIT;
    496507
    497508        if( tr_bencDictFindList( prog, KEY_PROGRESS_CHECKTIME, &l ) )
     
    568579
    569580        err = NULL;
     581        tr_bitfieldConstruct( &blocks, tor->blockCount );
    570582
    571583        if(( b = tr_bencDictFind( prog, KEY_PROGRESS_BLOCKS )))
    572584        {
    573             if( !tr_bitsetFromBenc( &bitset, b ) )
    574                 err = "Invalid value for PIECES";
     585            size_t buflen;
     586            const uint8_t * buf;
     587
     588            if( !tr_bencGetRaw( b, &buf, &buflen ) )
     589                err = "Invalid value for \"blocks\"";
     590            else if( ( buflen == 3 ) && !memcmp( buf, "all", 3 ) )
     591                tr_bitfieldSetHasAll( &blocks );
     592            else if( ( buflen == 4 ) && !memcmp( buf, "none", 4 ) )
     593                tr_bitfieldSetHasNone( &blocks );
     594            else
     595                tr_bitfieldSetRaw( &blocks, buf, buflen );
    575596        }
    576597        else if( tr_bencDictFindStr( prog, KEY_PROGRESS_HAVE, &str ) )
    577598        {
    578599            if( !strcmp( str, "all" ) )
    579                 tr_bitsetSetHaveAll( &bitset );
     600                tr_bitfieldSetHasAll( &blocks );
    580601            else
    581602                err = "Invalid value for HAVE";
     
    583604        else if( tr_bencDictFindRaw( prog, KEY_PROGRESS_BITFIELD, &raw, &rawlen ) )
    584605        {
    585             bitset.bitfield.bits = (void*) raw;
    586             bitset.bitfield.byteCount = rawlen;
    587             bitset.bitfield.bitCount = rawlen * 8;
     606            tr_bitfieldSetRaw( &blocks, raw, rawlen );
    588607        }
    589608        else err = "Couldn't find 'pieces' or 'have' or 'bitfield'";
    590609
    591         if( !err && !tr_cpBlockBitsetInit( &tor->completion, &bitset ) )
     610        if( !err && !tr_cpBlockInit( &tor->completion, &blocks ) )
    592611            err = "Error loading bitfield";
    593612        if( err != NULL )
    594613            tr_tordbg( tor, "Torrent needs to be verified - %s", err );
    595614
     615        tr_bitfieldDestruct( &blocks );
    596616        ret = TR_FR_PROGRESS;
    597617    }
  • trunk/libtransmission/rpcimpl.c

    r12228 r12248  
    559559        tr_bencDictAddInt( d, key, st->peersSendingToUs );
    560560    else if( tr_streq( key, keylen, "pieces" ) ) {
    561         tr_bitfield * bf = tr_cpCreatePieceBitfield( &tor->completion );
    562         char * str = tr_base64_encode( bf->bits, bf->byteCount, NULL );
     561        size_t byte_count = 0;
     562        void * bytes = tr_cpCreatePieceBitfield( &tor->completion, &byte_count );
     563        char * str = tr_base64_encode( bytes, byte_count, NULL );
    563564        tr_bencDictAddStr( d, key, str!=NULL ? str : "" );
    564565        tr_free( str );
    565         tr_bitfieldFree( bf );
     566        tr_free( bytes );
    566567    }
    567568    else if( tr_streq( key, keylen, "pieceCount" ) )
  • trunk/libtransmission/session.c

    r12237 r12248  
    12631263    tr_bitfield * b = &t->minutes;
    12641264
    1265     tr_bitfieldClear( b );
     1265    tr_bitfieldSetHasNone( b );
    12661266
    12671267    for( day=0; day<7; ++day )
  • trunk/libtransmission/torrent.c

    r12233 r12248  
    11391139{
    11401140    tr_stat *               s;
    1141     int                     usableSeeds;
    11421141    uint64_t                now;
    11431142    uint64_t                seedRatioBytesLeft;
     
    11641163    tr_peerMgrTorrentStats( tor,
    11651164                            &s->peersConnected,
    1166                             &usableSeeds,
    11671165                            &s->webseedsSendingToUs,
    11681166                            &s->peersSendingToUs,
     
    11751173    s->rawDownloadSpeed_KBps   = toSpeedKBps( tr_bandwidthGetRawSpeed_Bps  ( tor->bandwidth, now, TR_DOWN ) );
    11761174    s->pieceDownloadSpeed_KBps = toSpeedKBps( tr_bandwidthGetPieceSpeed_Bps( tor->bandwidth, now, TR_DOWN ) );
    1177 
    1178     usableSeeds += tor->info.webseedCount;
    11791175
    11801176    s->percentComplete = tr_cpPercentComplete ( &tor->completion );
     
    11971193        s->idleSecs = -1;
    11981194
    1199     s->corruptEver     = tor->corruptCur    + tor->corruptPrev;
    1200     s->downloadedEver  = tor->downloadedCur + tor->downloadedPrev;
    1201     s->uploadedEver    = tor->uploadedCur   + tor->uploadedPrev;
    1202     s->haveValid       = tr_cpHaveValid( &tor->completion );
    1203     s->haveUnchecked   = tr_cpHaveTotal( &tor->completion ) - s->haveValid;
    1204 
    1205     if( usableSeeds > 0 )
    1206     {
    1207         s->desiredAvailable = s->leftUntilDone;
    1208     }
    1209     else if( !s->leftUntilDone || !s->peersConnected )
    1210     {
    1211         s->desiredAvailable = 0;
    1212     }
    1213     else
    1214     {
    1215         tr_piece_index_t i;
    1216         tr_bitfield *    peerPieces = tr_peerMgrGetAvailable( tor );
    1217         s->desiredAvailable = 0;
    1218         for( i = 0; i < tor->info.pieceCount; ++i )
    1219             if( !tor->info.pieces[i].dnd && tr_bitfieldHasFast( peerPieces, i ) )
    1220                 s->desiredAvailable += tr_cpMissingBlocksInPiece( &tor->completion, i );
    1221         s->desiredAvailable *= tor->blockSize;
    1222         tr_bitfieldFree( peerPieces );
    1223     }
     1195    s->corruptEver      = tor->corruptCur    + tor->corruptPrev;
     1196    s->downloadedEver   = tor->downloadedCur + tor->downloadedPrev;
     1197    s->uploadedEver     = tor->uploadedCur   + tor->uploadedPrev;
     1198    s->haveValid        = tr_cpHaveValid( &tor->completion );
     1199    s->haveUnchecked    = tr_cpHaveTotal( &tor->completion ) - s->haveValid;
     1200    s->desiredAvailable = tr_peerMgrGetDesiredAvailable( tor );
    12241201
    12251202    s->ratio = tr_getRatio( s->uploadedEver,
     
    13281305            /* the middle blocks */
    13291306            if( first + 1 < last ) {
    1330                 uint64_t u = tr_bitsetCountRange( tr_cpBlockBitset( &tor->completion ), first+1, last );
     1307                uint64_t u = tr_bitfieldCountRange( &tor->completion.blockBitfield, first+1, last );
    13311308                u *= tor->blockSize;
    13321309                total += u;
  • trunk/libtransmission/utils-test.c

    r12204 r12248  
    5656    int count2;
    5757    const int bitCount = 100 + tr_cryptoWeakRandInt( 1000 );
    58     tr_bitfield * bf;
     58    tr_bitfield bf;
    5959
    6060    /* generate a random bitfield */
    61     bf = tr_bitfieldNew( bitCount );
     61    tr_bitfieldConstruct( &bf, bitCount );
    6262    for( i=0, n=tr_cryptoWeakRandInt(bitCount); i<n; ++i )
    63         tr_bitfieldAdd( bf, tr_cryptoWeakRandInt(bitCount) );
     63        tr_bitfieldAdd( &bf, tr_cryptoWeakRandInt(bitCount) );
    6464
    6565    begin = tr_cryptoWeakRandInt( bitCount );
     
    7575    count1 = 0;
    7676    for( i=begin; i<end; ++i )
    77         if( tr_bitfieldHas( bf, i ) )
     77        if( tr_bitfieldHas( &bf, i ) )
    7878            ++count1;
    79     count2 = tr_bitfieldCountRange( bf, begin, end );
     79    count2 = tr_bitfieldCountRange( &bf, begin, end );
    8080    check( count1 == count2 );
    8181
    82     tr_bitfieldFree( bf );
     82    tr_bitfieldDestruct( &bf );
    8383    return 0;
    8484}
     
    8888{
    8989    unsigned int  i;
    90     unsigned int  bitcount = 5000000;
    91     tr_bitfield * field = tr_bitfieldNew( bitcount );
     90    unsigned int  bitcount = 500;
     91    tr_bitfield field;
     92
     93    tr_bitfieldConstruct( &field, bitcount );
    9294
    9395    /* test tr_bitfieldAdd */
    9496    for( i = 0; i < bitcount; ++i )
    9597        if( !( i % 7 ) )
    96             tr_bitfieldAdd( field, i );
     98            tr_bitfieldAdd( &field, i );
    9799    for( i = 0; i < bitcount; ++i )
    98         check( tr_bitfieldHas( field, i ) == ( !( i % 7 ) ) );
     100        check( tr_bitfieldHas( &field, i ) == ( !( i % 7 ) ) );
    99101
    100102    /* test tr_bitfieldAddRange */
    101     tr_bitfieldAddRange( field, 0, bitcount );
     103    tr_bitfieldAddRange( &field, 0, bitcount );
    102104    for( i = 0; i < bitcount; ++i )
    103         check( tr_bitfieldHas( field, i ) );
     105        check( tr_bitfieldHas( &field, i ) );
    104106
    105107    /* test tr_bitfieldRemRange in the middle of a boundary */
    106     tr_bitfieldRemRange( field, 4, 21 );
     108    tr_bitfieldRemRange( &field, 4, 21 );
    107109    for( i = 0; i < 64; ++i )
    108         check( tr_bitfieldHas( field, i ) == ( ( i < 4 ) || ( i >= 21 ) ) );
     110        check( tr_bitfieldHas( &field, i ) == ( ( i < 4 ) || ( i >= 21 ) ) );
    109111
    110112    /* test tr_bitfieldRemRange on the boundaries */
    111     tr_bitfieldAddRange( field, 0, 64 );
    112     tr_bitfieldRemRange( field, 8, 24 );
     113    tr_bitfieldAddRange( &field, 0, 64 );
     114    tr_bitfieldRemRange( &field, 8, 24 );
    113115    for( i = 0; i < 64; ++i )
    114         check( tr_bitfieldHas( field, i ) == ( ( i < 8 ) || ( i >= 24 ) ) );
     116        check( tr_bitfieldHas( &field, i ) == ( ( i < 8 ) || ( i >= 24 ) ) );
    115117
    116118    /* test tr_bitfieldRemRange when begin & end is on the same word */
    117     tr_bitfieldAddRange( field, 0, 64 );
    118     tr_bitfieldRemRange( field, 4, 5 );
     119    tr_bitfieldAddRange( &field, 0, 64 );
     120    tr_bitfieldRemRange( &field, 4, 5 );
    119121    for( i = 0; i < 64; ++i )
    120         check( tr_bitfieldHas( field, i ) == ( ( i < 4 ) || ( i >= 5 ) ) );
     122        check( tr_bitfieldHas( &field, i ) == ( ( i < 4 ) || ( i >= 5 ) ) );
    121123
    122124    /* test tr_bitfieldAddRange */
    123     tr_bitfieldRemRange( field, 0, 64 );
    124     tr_bitfieldAddRange( field, 4, 21 );
     125    tr_bitfieldRemRange( &field, 0, 64 );
     126    tr_bitfieldAddRange( &field, 4, 21 );
    125127    for( i = 0; i < 64; ++i )
    126         check( tr_bitfieldHas( field, i ) == ( ( 4 <= i ) && ( i < 21 ) ) );
     128        check( tr_bitfieldHas( &field, i ) == ( ( 4 <= i ) && ( i < 21 ) ) );
    127129
    128130    /* test tr_bitfieldAddRange on the boundaries */
    129     tr_bitfieldRemRange( field, 0, 64 );
    130     tr_bitfieldAddRange( field, 8, 24 );
     131    tr_bitfieldRemRange( &field, 0, 64 );
     132    tr_bitfieldAddRange( &field, 8, 24 );
    131133    for( i = 0; i < 64; ++i )
    132         check( tr_bitfieldHas( field, i ) == ( ( 8 <= i ) && ( i < 24 ) ) );
     134        check( tr_bitfieldHas( &field, i ) == ( ( 8 <= i ) && ( i < 24 ) ) );
    133135
    134136    /* test tr_bitfieldAddRange when begin & end is on the same word */
    135     tr_bitfieldRemRange( field, 0, 64 );
    136     tr_bitfieldAddRange( field, 4, 5 );
     137    tr_bitfieldRemRange( &field, 0, 64 );
     138    tr_bitfieldAddRange( &field, 4, 5 );
    137139    for( i = 0; i < 64; ++i )
    138         check( tr_bitfieldHas( field, i ) == ( ( 4 <= i ) && ( i < 5 ) ) );
    139 
    140     tr_bitfieldFree( field );
     140        check( tr_bitfieldHas( &field, i ) == ( ( 4 <= i ) && ( i < 5 ) ) );
     141
     142    tr_bitfieldDestruct( &field );
    141143    return 0;
    142144}
     
    514516
    515517    /* bitfield count range */
    516     for( l=0; l<1000000; ++l )
     518    for( l=0; l<10000; ++l )
    517519        if(( i = test_bitfield_count_range( )))
    518520            return i;
  • trunk/libtransmission/webseed.c

    r12204 r12248  
    338338    peer->clientIsInterested = !tr_torrentIsSeed( tor );
    339339    peer->client = tr_strdup( "webseed" );
    340     tr_bitsetSetHaveAll( &peer->have );
     340    tr_bitfieldSetHasAll( &peer->have );
    341341    tr_peerUpdateProgress( tor, peer );
    342342
Note: See TracChangeset for help on using the changeset viewer.