Changeset 12248
- Timestamp:
- Mar 28, 2011, 4:31:05 PM (12 years ago)
- Location:
- trunk/libtransmission
- Files:
-
- 2 deleted
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/Makefile.am
r12141 r12248 24 24 bencode.c \ 25 25 bitfield.c \ 26 bitset.c \27 26 blocklist.c \ 28 27 cache.c \ … … 76 75 bencode.h \ 77 76 bitfield.h \ 78 bitset.h \79 77 blocklist.h \ 80 78 cache.h \ -
trunk/libtransmission/bitfield.c
r12096 r12248 16 16 #include "transmission.h" 17 17 #include "bitfield.h" 18 #include "bitset.h"19 18 #include "utils.h" /* tr_new0() */ 20 19 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] = 20 const tr_bitfield TR_BITFIELD_INIT = { NULL, 0, 0, 0, false, false }; 21 22 /**** 23 ***** 24 ****/ 25 26 static const int8_t trueBitCount[256] = 169 27 { 170 28 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, … … 186 44 }; 187 45 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 ) 46 static size_t 47 countRange( const tr_bitfield * b, size_t begin, size_t end ) 205 48 { 206 49 size_t ret = 0; … … 208 51 const int last_byte = ( end - 1 ) >> 3u; 209 52 210 assert( b egin < end);53 assert( b->bits != NULL ); 211 54 212 55 if( first_byte == last_byte ) … … 251 94 return ret; 252 95 } 96 97 size_t 98 tr_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 115 static bool 116 tr_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 125 void* 126 tr_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 153 static void 154 tr_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 162 static void 163 tr_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 176 static void 177 tr_bitfieldRebuildTrueCount( tr_bitfield * b ) 178 { 179 tr_bitfieldSetTrueCount( b, countRange( b, 0, b->bit_count ) ); 180 } 181 182 static void 183 tr_bitfieldIncTrueCount( tr_bitfield * b, int i ) 184 { 185 tr_bitfieldSetTrueCount( b, b->true_count + i ); 186 } 187 188 /**** 189 ***** 190 ****/ 191 192 void 193 tr_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 205 void 206 tr_bitfieldDestruct( tr_bitfield * b ) 207 { 208 tr_bitfieldSetHasNone( b ); 209 } 210 211 static void 212 tr_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 221 void 222 tr_bitfieldSetHasNone( tr_bitfield * b ) 223 { 224 tr_bitfieldClear( b ); 225 b->have_all_hint = false; 226 b->have_none_hint = true; 227 } 228 229 void 230 tr_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 238 bool 239 tr_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 253 bool 254 tr_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 268 void 269 tr_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 */ 282 void 283 tr_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 317 void 318 tr_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 */ 331 void 332 tr_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 18 18 #define TR_BITFIELD_H 1 19 19 20 #include <assert.h> 20 21 #include "transmission.h" 21 22 … … 24 25 { 25 26 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; 28 35 } 29 36 tr_bitfield; 30 37 38 /*** 39 **** life cycle 40 ***/ 41 31 42 extern const tr_bitfield TR_BITFIELD_INIT; 32 43 33 tr_bitfield* tr_bitfieldConstruct( tr_bitfield*, size_t bitCount );44 void tr_bitfieldConstruct( tr_bitfield*, size_t bit_count ); 34 45 35 tr_bitfield*tr_bitfieldDestruct( tr_bitfield* );46 void tr_bitfieldDestruct( tr_bitfield* ); 36 47 37 tr_bitfield* tr_bitfieldNew( size_t bitCount ); 48 /*** 49 **** 50 ***/ 38 51 39 void tr_bitfieldFree( tr_bitfield * b);52 void tr_bitfieldSetHasAll( tr_bitfield* ); 40 53 41 void tr_bitfieldClear( tr_bitfield* );54 void tr_bitfieldSetHasNone( tr_bitfield* ); 42 55 43 inttr_bitfieldAdd( tr_bitfield*, size_t bit );56 void tr_bitfieldAdd( tr_bitfield*, size_t bit ); 44 57 45 inttr_bitfieldRem( tr_bitfield*, size_t bit );58 void tr_bitfieldRem( tr_bitfield*, size_t bit ); 46 59 47 int tr_bitfieldAddRange( tr_bitfield*, size_t begin, size_t end );60 void tr_bitfieldAddRange( tr_bitfield*, size_t begin, size_t end ); 48 61 49 inttr_bitfieldRemRange( tr_bitfield*, size_t begin, size_t end );62 void tr_bitfieldRemRange( tr_bitfield*, size_t begin, size_t end ); 50 63 51 size_t tr_bitfieldCountTrueBits( const tr_bitfield* ); 64 /*** 65 **** 66 ***/ 52 67 53 size_t tr_bitfieldCountRange( const tr_bitfield * b, size_t begin, size_t end);68 bool tr_bitfieldSetFromBitfield( tr_bitfield*, const tr_bitfield* ); 54 69 70 bool tr_bitfieldSetRaw( tr_bitfield*, const void * bits, size_t byte_count ); 55 71 56 tr_bitfield* tr_bitfieldOr( tr_bitfield*, const tr_bitfield* ); 72 void* tr_bitfieldGetRaw( const tr_bitfield * b, size_t * byte_count ); 73 74 /*** 75 **** 76 ***/ 77 78 size_t tr_bitfieldCountRange( const tr_bitfield*, size_t begin, size_t end ); 79 80 static inline size_t 81 tr_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 87 static inline bool 88 tr_bitfieldHasAll( const tr_bitfield * b ) 89 { 90 return b->bit_count ? ( b->true_count == b->bit_count ) : b->have_all_hint; 91 } 92 93 static inline bool 94 tr_bitfieldHasNone( const tr_bitfield * b ) 95 { 96 return b->bit_count ? ( b->true_count == 0 ) : b->have_none_hint; 97 } 57 98 58 99 /** A stripped-down version of bitfieldHas to be used … … 61 102 need to call tr_bitfieldTestFast() first before you 62 103 start looping. */ 63 static inline bool tr_bitfieldHasFast( const tr_bitfield * b, const size_t nth ) 104 static inline bool 105 tr_bitfieldHasFast( const tr_bitfield * b, const size_t n ) 64 106 { 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; 66 110 } 67 111 68 112 /** @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 ) 113 static inline bool 114 tr_bitfieldTestFast( const tr_bitfield * b, const size_t high ) 70 115 { 71 116 return ( b != NULL ) 72 && ( b->bits != NULL ) 73 && ( high < b->bitCount ); 117 && ( high < b->bit_count ); 74 118 } 75 119 76 static inline bool tr_bitfieldHas( const tr_bitfield * b, size_t nth ) 120 static inline bool 121 tr_bitfieldHas( const tr_bitfield * b, size_t n ) 77 122 { 78 return tr_bitfieldTestFast( b, nth ) && tr_bitfieldHasFast( b, nth ); 123 return tr_bitfieldTestFast( b, n ) 124 && tr_bitfieldHasFast( b, n ); 79 125 } 80 126 -
trunk/libtransmission/completion.c
r12204 r12248 11 11 */ 12 12 13 #include <string.h> /* memcpy() */14 15 13 #include "transmission.h" 16 14 #include "completion.h" … … 25 23 tr_cpReset( tr_completion * cp ) 26 24 { 27 tr_bitsetSetHaveNone( &cp->blockBitset );28 tr_free( cp->completeBlocks );29 cp->completeBlocks = NULL;30 25 cp->sizeNow = 0; 31 26 cp->sizeWhenDoneIsDirty = true; 32 cp->blocksWantedIsDirty = true;33 27 cp->haveValidIsDirty = true; 34 } 35 36 tr_completion * 28 tr_bitfieldSetHasNone( &cp->blockBitfield ); 29 } 30 31 void 37 32 tr_cpConstruct( tr_completion * cp, tr_torrent * tor ) 38 33 { 39 34 cp->tor = tor; 40 cp->completeBlocks = NULL; 41 tr_bitsetConstruct( &cp->blockBitset, tor->blockCount ); 35 tr_bitfieldConstruct( &cp->blockBitfield, tor->blockCount ); 42 36 tr_cpReset( cp ); 43 return cp; 44 } 45 46 tr_completion* 37 } 38 39 void 47 40 tr_cpDestruct( tr_completion * cp ) 48 41 { 49 tr_free( cp->completeBlocks ); 50 tr_bitsetDestruct( &cp->blockBitset ); 51 return cp; 42 tr_bitfieldDestruct( &cp->blockBitfield ); 43 } 44 45 bool 46 tr_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; 52 62 } 53 63 … … 59 69 isSeed( const tr_completion * cp ) 60 70 { 61 return cp->blockBitset.haveAll;71 return tr_bitfieldHasAll( &cp->blockBitfield ); 62 72 } 63 73 … … 65 75 tr_cpGetStatus( const tr_completion * cp ) 66 76 { 77 if( isSeed( cp ) ) return TR_SEED; 67 78 if( !tr_torrentHasMetadata( cp->tor ) ) return TR_LEECH; 68 if( cp->sizeNow == cp->tor->info.totalSize ) return TR_SEED;69 79 if( cp->sizeNow == tr_cpSizeWhenDone( cp ) ) return TR_PARTIAL_SEED; 70 80 return TR_LEECH; 71 81 } 72 82 73 /* how many blocks are in this piece? */74 static inline uint16_t75 countBlocksInPiece( const tr_torrent * tor, const tr_piece_index_t piece )76 {77 return piece + 1 == tor->info.pieceCount ? tor->blockCountInLastPiece78 : 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 93 83 void 94 84 tr_cpInvalidateDND( tr_completion * cp ) 95 85 { 96 86 cp->sizeWhenDoneIsDirty = true; 97 cp->blocksWantedIsDirty = true;98 }99 100 tr_block_index_t101 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;131 87 } 132 88 … … 134 90 tr_cpPieceRem( tr_completion * cp, tr_piece_index_t piece ) 135 91 { 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; 139 93 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=f irst; i<=last; ++i )94 95 tr_torGetPieceBlockRange( cp->tor, piece, &f, &l ); 96 97 for( i=f; i<=l; ++i ) 144 98 if( tr_cpBlockIsComplete( cp, i ) ) 145 99 cp->sizeNow -= tr_torBlockCountBytes( tor, i ); 146 100 147 if( !tor->info.pieces[piece].dnd ) 148 cp->blocksWantedCompleteLazy -= complete_blocks[piece]; 149 101 cp->haveValidIsDirty = true; 150 102 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 ); 154 104 } 155 105 … … 157 107 tr_cpPieceAdd( tr_completion * cp, tr_piece_index_t piece ) 158 108 { 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 ) 165 113 tr_cpBlockAdd( cp, i ); 166 114 } … … 173 121 if( !tr_cpBlockIsComplete( cp, block ) ) 174 122 { 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; 186 127 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 } 256 129 } 257 130 … … 265 138 if( ccp->haveValidIsDirty ) 266 139 { 267 tr_piece_index_t 268 uint64_t 269 tr_completion 140 tr_piece_index_t i; 141 uint64_t size = 0; 142 tr_completion * cp = (tr_completion *) ccp; /* mutable */ 270 143 const tr_torrent * tor = ccp->tor; 271 const tr_info 144 const tr_info * info = &tor->info; 272 145 273 146 for( i=0; i<info->pieceCount; ++i ) … … 275 148 size += tr_torPieceCountBytes( tor, i ); 276 149 150 cp->haveValidLazy = size; 277 151 cp->haveValidIsDirty = false; 278 cp->haveValidLazy = size;279 152 } 280 153 … … 287 160 if( ccp->sizeWhenDoneIsDirty ) 288 161 { 289 tr_piece_index_t 290 uint64_t 291 tr_completion 162 tr_piece_index_t i; 163 uint64_t size = 0; 164 tr_completion * cp = (tr_completion *) ccp; /* mutable */ 292 165 const tr_torrent * tor = ccp->tor; 293 const tr_info 166 const tr_info * info = &tor->info; 294 167 295 168 for( i=0; i<info->pieceCount; ++i ) … … 297 170 size += tr_torPieceCountBytes( tor, i ); 298 171 172 cp->sizeWhenDoneLazy = size; 299 173 cp->sizeWhenDoneIsDirty = false; 300 cp->sizeWhenDoneLazy = size;301 174 } 302 175 … … 304 177 } 305 178 179 uint64_t 180 tr_cpLeftUntilDone( const tr_completion * cp ) 181 { 182 return tr_cpSizeWhenDone( cp ) - cp->sizeNow; 183 } 184 185 uint64_t 186 tr_cpLeftUntilComplete( const tr_completion * cp ) 187 { 188 return cp->tor->info.totalSize - cp->sizeNow; 189 } 190 306 191 void 307 192 tr_cpGetAmountDone( const tr_completion * cp, float * tab, int tabCount ) 308 193 { 309 194 int i; 195 const bool seed = isSeed( cp ); 310 196 const float interval = cp->tor->info.pieceCount / (float)tabCount; 311 const bool seed = isSeed( cp );312 197 313 198 for( i=0; i<tabCount; ++i ) { … … 315 200 tab[i] = 1.0f; 316 201 else { 202 tr_block_index_t f, l; 317 203 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); 319 207 } 320 208 } 321 209 } 322 210 323 int324 tr_cpMissingBlocksInPiece( const tr_completion * cp, tr_piece_index_t i)211 size_t 212 tr_cpMissingBlocksInPiece( const tr_completion * cp, tr_piece_index_t piece ) 325 213 { 326 214 if( isSeed( cp ) ) 327 215 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 223 size_t 224 tr_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 } 330 238 } 331 239 … … 333 241 tr_cpFileIsComplete( const tr_completion * cp, tr_file_index_t i ) 334 242 { 335 tr_block_index_t f, l;336 337 243 if( cp->tor->info.files[i].length == 0 ) 338 244 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 252 void * 253 tr_cpCreatePieceBitfield( const tr_completion * cp, size_t * byte_count ) 254 { 255 void * ret; 256 tr_bitfield pieces; 348 257 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 274 double 275 tr_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 287 double 288 tr_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 18 18 #define TR_COMPLETION_H 19 19 20 #include <assert.h>21 22 20 #include "transmission.h" 23 #include "bit set.h"21 #include "bitfield.h" 24 22 #include "utils.h" /* tr_getRatio() */ 25 23 26 24 typedef struct tr_completion 27 25 { 28 bool sizeWhenDoneIsDirty; 29 bool blocksWantedIsDirty; 30 bool haveValidIsDirty; 31 32 tr_torrent * tor; 26 tr_torrent * tor; 33 27 34 28 /* 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; 49 30 50 31 /* number of bytes we'll have when done downloading. [0..info.totalSize] 51 32 DON'T access this directly; it's a lazy field. 52 33 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; 54 38 55 39 /* number of bytes we'll have when done downloading. [0..info.totalSize] 56 40 DON'T access this directly; it's a lazy field. 57 41 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; 59 46 60 47 /* number of bytes we want or have now. [0..sizeWhenDone] */ 61 uint64_t 48 uint64_t sizeNow; 62 49 } 63 50 tr_completion; … … 67 54 **/ 68 55 69 tr_completion *tr_cpConstruct( tr_completion *, tr_torrent * );56 void tr_cpConstruct( tr_completion *, tr_torrent * ); 70 57 71 tr_completion *tr_cpDestruct( tr_completion * );58 void tr_cpDestruct( tr_completion * ); 72 59 73 60 /** … … 75 62 **/ 76 63 77 tr_completeness tr_cpGetStatus( const tr_completion *);64 double tr_cpPercentComplete( const tr_completion * cp ); 78 65 79 uint64_t tr_cpHaveValid( const tr_completion *);66 double tr_cpPercentDone( const tr_completion * cp ); 80 67 81 tr_ block_index_t tr_cpBlocksMissing( const tr_completion * );68 tr_completeness tr_cpGetStatus( const tr_completion * ); 82 69 83 uint64_t tr_cpSizeWhenDone( const tr_completion * );70 uint64_t tr_cpHaveValid( const tr_completion * ); 84 71 85 void tr_cpInvalidateDND(tr_completion * );72 uint64_t tr_cpSizeWhenDone( const tr_completion * ); 86 73 87 void tr_cpGetAmountDone( const tr_completion * completion, 88 float * tab, 89 int tabCount ); 74 uint64_t tr_cpLeftUntilComplete( const tr_completion * ); 75 76 uint64_t tr_cpLeftUntilDone( const tr_completion * ); 77 78 void tr_cpGetAmountDone( const tr_completion * completion, 79 float * tab, 80 int tabCount ); 81 82 static inline bool tr_cpHasAll( const tr_completion * cp ) 83 { 84 return tr_bitfieldHasAll( &cp->blockBitfield ); 85 } 86 87 static inline bool tr_cpHasNone( const tr_completion * cp ) 88 { 89 return tr_bitfieldHasNone( &cp->blockBitfield ); 90 } 90 91 91 92 static inline uint64_t tr_cpHaveTotal( const tr_completion * cp ) … … 94 95 } 95 96 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 else114 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 124 97 /** 125 *** Pieces98 *** Pieces 126 99 **/ 127 100 128 int tr_cpMissingBlocksInPiece( const tr_completion * cp, tr_piece_index_t i ); 101 void tr_cpPieceAdd( tr_completion * cp, tr_piece_index_t i ); 102 103 void tr_cpPieceRem( tr_completion * cp, tr_piece_index_t i ); 104 105 size_t tr_cpMissingBlocksInPiece( const tr_completion *, tr_piece_index_t ); 106 107 size_t tr_cpMissingBytesInPiece ( const tr_completion *, tr_piece_index_t ); 129 108 130 109 static inline bool … … 134 113 } 135 114 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 142 115 /** 143 *** Blocks116 *** Blocks 144 117 **/ 145 118 … … 147 120 tr_cpBlockIsComplete( const tr_completion * cp, tr_block_index_t i ) 148 121 { 149 return tr_bit setHas( &cp->blockBitset, i );122 return tr_bitfieldHas( &cp->blockBitfield, i ); 150 123 } 151 124 152 void tr_cpBlockAdd( tr_completion * cp, tr_block_index_t i );125 void tr_cpBlockAdd( tr_completion * cp, tr_block_index_t i ); 153 126 154 bool tr_cpBlockBitsetInit( tr_completion * cp, const tr_bitset* blocks );127 bool tr_cpBlockInit( tr_completion * cp, const tr_bitfield * blocks ); 155 128 156 129 /*** 157 **** 130 **** Misc 158 131 ***/ 159 132 160 static inline const tr_bitset * 161 tr_cpBlockBitset( const tr_completion * cp ) 162 { 163 return &cp->blockBitset; 164 } 133 bool tr_cpFileIsComplete( const tr_completion * cp, tr_file_index_t ); 165 134 166 tr_bitfield * tr_cpCreatePieceBitfield( const tr_completion * cp ); 135 void tr_cpInvalidateDND( tr_completion * ); 136 137 void* tr_cpCreatePieceBitfield( const tr_completion * cp, size_t * byte_count ); 138 167 139 168 140 #endif -
trunk/libtransmission/peer-io.c
r12233 r12248 130 130 131 131 dbgmsg( io, "canRead" ); 132 133 fprintf( stderr, "[%p] in canRead; refcount is %d (%s:%d)\n", io, io->refCount, __FILE__, __LINE__ ); 132 134 133 135 tr_peerIoRef( io ); … … 569 571 UTP_SetSockopt( utp_socket, SO_RCVBUF, UTP_READ_BUFFER_SIZE ); 570 572 dbgmsg( io, "%s", "calling UTP_SetCallbacks &utp_function_table" ); 573 fprintf( stderr, "[%p] setting utp callbacks (%s:%d)\n", io, __FILE__, __LINE__ ); 571 574 UTP_SetCallbacks( utp_socket, 572 575 &utp_function_table, … … 607 610 { 608 611 int fd = -1; 609 struct UTPSocket * utp_socket = NULL;612 struct UTPSocket * utp_socket = NULL; 610 613 611 614 assert( session ); … … 722 725 #ifdef WITH_UTP 723 726 if( io->utp_socket ) { 727 fprintf( stderr, "[%p] clearing utp callbacks (%s:%d)\n", io, __FILE__, __LINE__ ); 724 728 UTP_SetCallbacks( io->utp_socket, 725 729 &dummy_utp_function_table, -
trunk/libtransmission/peer-mgr.c
r12229 r12248 375 375 memset( peer, 0, sizeof( tr_peer ) ); 376 376 377 peer->have = TR_BIT SET_INIT;377 peer->have = TR_BITFIELD_INIT; 378 378 379 379 tr_historyConstruct( &peer->blocksSentToClient, CANCEL_HISTORY_SEC, ( RECHOKE_PERIOD_MSEC / 1000 ) ); … … 407 407 { 408 408 peer = peerNew( atom ); 409 tr_bitfieldConstruct( &peer->have, torrent->tor->blockCount ); 410 tr_bitfieldConstruct( &peer->blame, torrent->tor->blockCount ); 409 411 tr_ptrArrayInsertSorted( &torrent->peers, peer, peerCompare ); 410 412 } … … 420 422 assert( peer != NULL ); 421 423 422 peerDeclinedAllRequests( tor->torrentPeers, peer ); 424 if( tor->torrentPeers->isRunning ) 425 peerDeclinedAllRequests( tor->torrentPeers, peer ); 423 426 424 427 if( peer->msgs != NULL ) … … 426 429 427 430 if( peer->io ) { 431 fprintf( stderr, "[%p] peer %p clearing/unreffing its io (%s:%d)\n", peer->io, peer, __FILE__, __LINE__ ); 428 432 tr_peerIoClear( peer->io ); 429 433 tr_peerIoUnref( peer->io ); /* balanced by the ref in handshakeDoneCB() */ … … 435 439 tr_historyDestruct( &peer->cancelsSentToPeer ); 436 440 437 tr_bit setDestruct( &peer->have );438 tr_bitfield Free(peer->blame );441 tr_bitfieldDestruct( &peer->have ); 442 tr_bitfieldDestruct( &peer->blame ); 439 443 tr_free( peer->client ); 440 444 … … 483 487 484 488 for( peer_i=0; peer_i<peer_count; ++peer_i ) 485 if( tr_bit setHas( &peers[peer_i]->have, piece_i ) )489 if( tr_bitfieldHas( &peers[peer_i]->have, piece_i ) ) 486 490 ++r; 487 491 … … 867 871 } 868 872 873 static bool 874 testForEndgame( 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 869 882 static void 870 883 updateEndgame( Torrent * t ) 871 884 { 872 const tr_torrent * tor = t->tor;873 const tr_block_index_t missing = tr_cpBlocksMissing( &tor->completion );874 875 885 assert( t->requestCount >= 0 ); 876 886 877 if( (tr_block_index_t) t->requestCount < missing)887 if( !testForEndgame( t ) ) 878 888 { 879 889 /* not in endgame */ … … 1268 1278 */ 1269 1279 static void 1270 tr_decrReplicationFromBit set( Torrent * t, const tr_bitset * bitset)1280 tr_decrReplicationFromBitfield( Torrent * t, const tr_bitfield * b ) 1271 1281 { 1272 1282 int i; … … 1276 1286 assert( t->pieceReplicationSize == t->tor->info.pieceCount ); 1277 1287 1278 if( bitset->haveAll)1288 if( tr_bitfieldHasAll( b ) ) 1279 1289 { 1280 1290 for( i=0; i<n; ++i ) 1281 1291 --t->pieceReplication[i]; 1282 1292 } 1283 else if ( !bitset->haveNone ) 1284 { 1285 const tr_bitfield * const b = &bitset->bitfield; 1286 1293 else if ( !tr_bitfieldHasNone( b ) ) 1294 { 1287 1295 for( i=0; i<n; ++i ) 1288 1296 if( tr_bitfieldHas( b, i ) ) … … 1317 1325 Torrent * t; 1318 1326 struct weighted_piece * pieces; 1319 const tr_bit set *have = &peer->have;1327 const tr_bitfield * const have = &peer->have; 1320 1328 1321 1329 /* sanity clause */ … … 1346 1354 1347 1355 /* if the peer has this piece that we want... */ 1348 if( tr_bit setHas( have, p->index ) )1356 if( tr_bitfieldHas( have, p->index ) ) 1349 1357 { 1350 1358 tr_block_index_t b; … … 2213 2221 { 2214 2222 tr_peer * peer = peers[i]; 2215 if( tr_bitfieldHas( peer->blame, pieceIndex ) )2223 if( tr_bitfieldHas( &peer->blame, pieceIndex ) ) 2216 2224 { 2217 2225 tordbg( t, "peer %s contributed to corrupt piece (%d); now has %d strikes", … … 2403 2411 stopTorrent( Torrent * t ) 2404 2412 { 2405 int i, n;2413 tr_peer * peer; 2406 2414 2407 2415 t->isRunning = false; … … 2411 2419 2412 2420 /* 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 ); 2416 2423 2417 2424 /* disconnect the handshakes. handshakeAbort calls handshakeDoneCB(), … … 2453 2460 tr_peerUpdateProgress( tr_torrent * tor, tr_peer * peer ) 2454 2461 { 2455 const tr_bit set* have = &peer->have;2456 2457 if( have->haveAll)2462 const tr_bitfield * have = &peer->have; 2463 2464 if( tr_bitfieldHasAll( have ) ) 2458 2465 { 2459 2466 peer->progress = 1.0; 2460 2467 } 2461 else if( have->haveNone)2468 else if( tr_bitfieldHasNone( have ) ) 2462 2469 { 2463 2470 peer->progress = 0.0; … … 2465 2472 else 2466 2473 { 2467 const float true Count = tr_bitfieldCountTrueBits( &have->bitfield);2474 const float true_count = tr_bitfieldCountTrueBits( have ); 2468 2475 2469 2476 if( tr_torrentHasMetadata( tor ) ) 2470 peer->progress = true Count / tor->info.pieceCount;2477 peer->progress = true_count / tor->info.pieceCount; 2471 2478 else /* without pieceCount, this result is only a best guess... */ 2472 peer->progress = true Count / ( have->bitfield.bitCount + 1 );2479 peer->progress = true_count / ( have->bit_count + 1 ); 2473 2480 } 2474 2481 … … 2517 2524 int j; 2518 2525 for( j=0; j<peerCount; ++j ) 2519 if( tr_bit setHas( &peers[j]->have, piece ) )2526 if( tr_bitfieldHas( &peers[j]->have, piece ) ) 2520 2527 ++tab[i]; 2521 2528 } … … 2524 2531 } 2525 2532 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; 2533 static bool 2534 peerIsSeed( 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 */ 2546 uint64_t 2547 tr_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; 2542 2591 } 2543 2592 … … 2545 2594 tr_peerMgrTorrentStats( tr_torrent * tor, 2546 2595 int * setmePeersConnected, 2547 int * setmeSeedsConnected,2548 2596 int * setmeWebseedsSendingToUs, 2549 2597 int * setmePeersSendingToUs, … … 2561 2609 2562 2610 *setmePeersConnected = 0; 2563 *setmeSeedsConnected = 0;2564 2611 *setmePeersGettingFromUs = 0; 2565 2612 *setmePeersSendingToUs = 0; … … 2586 2633 if( clientIsUploadingTo( peer ) ) 2587 2634 ++*setmePeersGettingFromUs; 2588 2589 if( atomIsSeed( atom ) )2590 ++*setmeSeedsConnected;2591 2635 } 2592 2636 … … 2624 2668 { 2625 2669 return peer->io ? tr_peerIoGetPieceSpeed_Bps( peer->io, now, direction ) : 0.0; 2626 }2627 2628 static bool2629 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;2638 2670 } 2639 2671 … … 2735 2767 return ( !tor->info.pieces[index].dnd ) /* we want it */ 2736 2768 && ( !tr_cpPieceIsComplete( &tor->completion, index ) ) /* we don't have it */ 2737 && ( tr_bit setHas( &peer->have, index ) ); /* peer has it */2769 && ( tr_bitfieldHas( &peer->have, index ) ); /* peer has it */ 2738 2770 } 2739 2771 … … 3234 3266 3235 3267 if( replicationExists( t ) ) 3236 tr_decrReplicationFromBit set( t, &peer->have );3268 tr_decrReplicationFromBitfield( t, &peer->have ); 3237 3269 3238 3270 assert( removed == peer ); -
trunk/libtransmission/peer-mgr.h
r12229 r12248 25 25 26 26 #include "bitfield.h" 27 #include "bitset.h"28 27 #include "history.h" 29 28 #include "net.h" /* tr_address */ … … 111 110 struct peer_atom * atom; 112 111 113 struct tr_bitfield *blame;114 struct tr_bit sethave;112 struct tr_bitfield blame; 113 struct tr_bitfield have; 115 114 116 115 /** how complete the peer's copy of the torrent is. [0.0...1.0] */ … … 230 229 unsigned int tabCount ); 231 230 232 struct tr_bitfield* tr_peerMgrGetAvailable( const tr_torrent * tor );231 uint64_t tr_peerMgrGetDesiredAvailable( const tr_torrent * tor ); 233 232 234 233 void tr_peerMgrOnTorrentGotMetainfo( tr_torrent * tor ); … … 238 237 void tr_peerMgrTorrentStats( tr_torrent * tor, 239 238 int * setmePeersConnected, 240 int * setmeSeedsConnected,241 239 int * setmeWebseedsSendingToUs, 242 240 int * setmePeersSendingToUs, -
trunk/libtransmission/peer-msgs.c
r12233 r12248 14 14 #include <errno.h> 15 15 #include <stdarg.h> 16 #include <stdio.h>17 16 #include <stdlib.h> 18 17 #include <string.h> … … 217 216 *** 218 217 **/ 219 220 #if 0221 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 #endif229 218 230 219 static inline tr_session* … … 1418 1407 1419 1408 /* a peer can send the same HAVE message twice... */ 1420 if( !tr_bit setHas( &msgs->peer->have, ui32 ) ) {1421 tr_bit setAdd( &msgs->peer->have, ui32 );1409 if( !tr_bitfieldHas( &msgs->peer->have, ui32 ) ) { 1410 tr_bitfieldAdd( &msgs->peer->have, ui32 ); 1422 1411 fireClientGotHave( msgs, ui32 ); 1423 1412 } … … 1426 1415 1427 1416 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 ); 1433 1418 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 ); 1438 1422 updatePeerProgress( msgs ); 1423 tr_free( tmp ); 1439 1424 break; 1440 1425 } … … 1511 1496 dbgmsg( msgs, "Got a BT_FEXT_HAVE_ALL" ); 1512 1497 if( fext ) { 1513 tr_bitsetSetHaveAll( &msgs->peer->have ); 1498 tr_bitfieldSetHasAll( &msgs->peer->have ); 1499 assert( tr_bitfieldHasAll( &msgs->peer->have ) ); 1514 1500 fireClientGotHaveAll( msgs ); 1515 1501 updatePeerProgress( msgs ); … … 1523 1509 dbgmsg( msgs, "Got a BT_FEXT_HAVE_NONE" ); 1524 1510 if( fext ) { 1525 tr_bit setSetHaveNone( &msgs->peer->have );1511 tr_bitfieldSetHasNone( &msgs->peer->have ); 1526 1512 fireClientGotHaveNone( msgs ); 1527 1513 updatePeerProgress( msgs ); … … 1566 1552 } 1567 1553 1568 static void1569 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 1576 1554 /* returns 0 on success, or an errno on failure */ 1577 1555 static int … … 1611 1589 return err; 1612 1590 1613 addPeerToBlamefield( msgs, req->index );1591 tr_bitfieldAdd( &msgs->peer->blame, req->index ); 1614 1592 fireGotBlock( msgs, req ); 1615 1593 return 0; … … 2016 1994 sendBitfield( tr_peermsgs * msgs ) 2017 1995 { 1996 size_t byte_count = 0; 2018 1997 struct evbuffer * out = msgs->outMessages; 2019 tr_bitfield * bf = tr_cpCreatePieceBitfield( &msgs->torrent->completion);2020 2021 evbuffer_add_uint32( out, sizeof( uint8_t ) + b f->byteCount );1998 void * bytes = tr_cpCreatePieceBitfield( &msgs->torrent->completion, &byte_count ); 1999 2000 evbuffer_add_uint32( out, sizeof( uint8_t ) + byte_count ); 2022 2001 evbuffer_add_uint8 ( out, BT_BITFIELD ); 2023 evbuffer_add ( out, b f->bits, bf->byteCount );2002 evbuffer_add ( out, bytes, byte_count ); 2024 2003 dbgmsg( msgs, "sending bitfield... outMessage size is now %zu", evbuffer_get_length( out ) ); 2025 2004 pokeBatchPeriod( msgs, IMMEDIATE_PRIORITY_INTERVAL_SECS ); 2026 2005 2027 tr_ bitfieldFree( bf);2006 tr_free( bytes ); 2028 2007 } 2029 2008 … … 2033 2012 const bool fext = tr_peerIoSupportsFEXT( msgs->peer->io ); 2034 2013 2035 if( fext && ( tr_cpBlockBitset( &msgs->torrent->completion )->haveAll) )2014 if( fext && tr_cpHasAll( &msgs->torrent->completion ) ) 2036 2015 { 2037 2016 protocolSendHaveAll( msgs ); 2038 2017 } 2039 else if( fext && ( tr_cpBlockBitset( &msgs->torrent->completion )->haveNone) )2018 else if( fext && tr_cpHasNone( &msgs->torrent->completion ) ) 2040 2019 { 2041 2020 protocolSendHaveNone( msgs ); 2042 2021 } 2043 else 2022 else if( !tr_cpHasNone( &msgs->torrent->completion ) ) 2044 2023 { 2045 2024 sendBitfield( msgs ); -
trunk/libtransmission/resume.c
r12204 r12248 17 17 #include "transmission.h" 18 18 #include "bencode.h" 19 #include "bitset.h"20 19 #include "completion.h" 21 20 #include "metainfo.h" /* tr_metainfoGetBasename() */ … … 410 409 411 410 static void 411 bitfieldToBenc( 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 422 static void 412 423 saveProgress( tr_benc * dict, tr_torrent * tor ) 413 424 { … … 470 481 471 482 /* add the blocks bitfield */ 472 tr_bitsetToBenc( tr_cpBlockBitset( &tor->completion ),473 483 bitfieldToBenc( &tor->completion.blockBitfield, 484 tr_bencDictAdd( prog, KEY_PROGRESS_BLOCKS ) ); 474 485 } 475 486 … … 493 504 tr_benc * l; 494 505 tr_benc * b; 495 struct tr_bit set bitset = TR_BITSET_INIT;506 struct tr_bitfield blocks = TR_BITFIELD_INIT; 496 507 497 508 if( tr_bencDictFindList( prog, KEY_PROGRESS_CHECKTIME, &l ) ) … … 568 579 569 580 err = NULL; 581 tr_bitfieldConstruct( &blocks, tor->blockCount ); 570 582 571 583 if(( b = tr_bencDictFind( prog, KEY_PROGRESS_BLOCKS ))) 572 584 { 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 ); 575 596 } 576 597 else if( tr_bencDictFindStr( prog, KEY_PROGRESS_HAVE, &str ) ) 577 598 { 578 599 if( !strcmp( str, "all" ) ) 579 tr_bit setSetHaveAll( &bitset);600 tr_bitfieldSetHasAll( &blocks ); 580 601 else 581 602 err = "Invalid value for HAVE"; … … 583 604 else if( tr_bencDictFindRaw( prog, KEY_PROGRESS_BITFIELD, &raw, &rawlen ) ) 584 605 { 585 bitset.bitfield.bits = (void*) raw; 586 bitset.bitfield.byteCount = rawlen; 587 bitset.bitfield.bitCount = rawlen * 8; 606 tr_bitfieldSetRaw( &blocks, raw, rawlen ); 588 607 } 589 608 else err = "Couldn't find 'pieces' or 'have' or 'bitfield'"; 590 609 591 if( !err && !tr_cpBlock BitsetInit( &tor->completion, &bitset) )610 if( !err && !tr_cpBlockInit( &tor->completion, &blocks ) ) 592 611 err = "Error loading bitfield"; 593 612 if( err != NULL ) 594 613 tr_tordbg( tor, "Torrent needs to be verified - %s", err ); 595 614 615 tr_bitfieldDestruct( &blocks ); 596 616 ret = TR_FR_PROGRESS; 597 617 } -
trunk/libtransmission/rpcimpl.c
r12228 r12248 559 559 tr_bencDictAddInt( d, key, st->peersSendingToUs ); 560 560 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 ); 563 564 tr_bencDictAddStr( d, key, str!=NULL ? str : "" ); 564 565 tr_free( str ); 565 tr_ bitfieldFree( bf);566 tr_free( bytes ); 566 567 } 567 568 else if( tr_streq( key, keylen, "pieceCount" ) ) -
trunk/libtransmission/session.c
r12237 r12248 1263 1263 tr_bitfield * b = &t->minutes; 1264 1264 1265 tr_bitfield Clear( b );1265 tr_bitfieldSetHasNone( b ); 1266 1266 1267 1267 for( day=0; day<7; ++day ) -
trunk/libtransmission/torrent.c
r12233 r12248 1139 1139 { 1140 1140 tr_stat * s; 1141 int usableSeeds;1142 1141 uint64_t now; 1143 1142 uint64_t seedRatioBytesLeft; … … 1164 1163 tr_peerMgrTorrentStats( tor, 1165 1164 &s->peersConnected, 1166 &usableSeeds,1167 1165 &s->webseedsSendingToUs, 1168 1166 &s->peersSendingToUs, … … 1175 1173 s->rawDownloadSpeed_KBps = toSpeedKBps( tr_bandwidthGetRawSpeed_Bps ( tor->bandwidth, now, TR_DOWN ) ); 1176 1174 s->pieceDownloadSpeed_KBps = toSpeedKBps( tr_bandwidthGetPieceSpeed_Bps( tor->bandwidth, now, TR_DOWN ) ); 1177 1178 usableSeeds += tor->info.webseedCount;1179 1175 1180 1176 s->percentComplete = tr_cpPercentComplete ( &tor->completion ); … … 1197 1193 s->idleSecs = -1; 1198 1194 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 ); 1224 1201 1225 1202 s->ratio = tr_getRatio( s->uploadedEver, … … 1328 1305 /* the middle blocks */ 1329 1306 if( first + 1 < last ) { 1330 uint64_t u = tr_bit setCountRange( tr_cpBlockBitset( &tor->completion ), first+1, last );1307 uint64_t u = tr_bitfieldCountRange( &tor->completion.blockBitfield, first+1, last ); 1331 1308 u *= tor->blockSize; 1332 1309 total += u; -
trunk/libtransmission/utils-test.c
r12204 r12248 56 56 int count2; 57 57 const int bitCount = 100 + tr_cryptoWeakRandInt( 1000 ); 58 tr_bitfield *bf;58 tr_bitfield bf; 59 59 60 60 /* generate a random bitfield */ 61 bf = tr_bitfieldNew(bitCount );61 tr_bitfieldConstruct( &bf, bitCount ); 62 62 for( i=0, n=tr_cryptoWeakRandInt(bitCount); i<n; ++i ) 63 tr_bitfieldAdd( bf, tr_cryptoWeakRandInt(bitCount) );63 tr_bitfieldAdd( &bf, tr_cryptoWeakRandInt(bitCount) ); 64 64 65 65 begin = tr_cryptoWeakRandInt( bitCount ); … … 75 75 count1 = 0; 76 76 for( i=begin; i<end; ++i ) 77 if( tr_bitfieldHas( bf, i ) )77 if( tr_bitfieldHas( &bf, i ) ) 78 78 ++count1; 79 count2 = tr_bitfieldCountRange( bf, begin, end );79 count2 = tr_bitfieldCountRange( &bf, begin, end ); 80 80 check( count1 == count2 ); 81 81 82 tr_bitfield Free(bf );82 tr_bitfieldDestruct( &bf ); 83 83 return 0; 84 84 } … … 88 88 { 89 89 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 ); 92 94 93 95 /* test tr_bitfieldAdd */ 94 96 for( i = 0; i < bitcount; ++i ) 95 97 if( !( i % 7 ) ) 96 tr_bitfieldAdd( field, i );98 tr_bitfieldAdd( &field, i ); 97 99 for( i = 0; i < bitcount; ++i ) 98 check( tr_bitfieldHas( field, i ) == ( !( i % 7 ) ) );100 check( tr_bitfieldHas( &field, i ) == ( !( i % 7 ) ) ); 99 101 100 102 /* test tr_bitfieldAddRange */ 101 tr_bitfieldAddRange( field, 0, bitcount );103 tr_bitfieldAddRange( &field, 0, bitcount ); 102 104 for( i = 0; i < bitcount; ++i ) 103 check( tr_bitfieldHas( field, i ) );105 check( tr_bitfieldHas( &field, i ) ); 104 106 105 107 /* test tr_bitfieldRemRange in the middle of a boundary */ 106 tr_bitfieldRemRange( field, 4, 21 );108 tr_bitfieldRemRange( &field, 4, 21 ); 107 109 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 ) ) ); 109 111 110 112 /* 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 ); 113 115 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 ) ) ); 115 117 116 118 /* 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 ); 119 121 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 ) ) ); 121 123 122 124 /* 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 ); 125 127 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 ) ) ); 127 129 128 130 /* 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 ); 131 133 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 ) ) ); 133 135 134 136 /* 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 ); 137 139 for( i = 0; i < 64; ++i ) 138 check( tr_bitfieldHas( field, i ) == ( ( 4 <= i ) && ( i < 5 ) ) );139 140 tr_bitfield Free(field );140 check( tr_bitfieldHas( &field, i ) == ( ( 4 <= i ) && ( i < 5 ) ) ); 141 142 tr_bitfieldDestruct( &field ); 141 143 return 0; 142 144 } … … 514 516 515 517 /* bitfield count range */ 516 for( l=0; l<10000 00; ++l )518 for( l=0; l<10000; ++l ) 517 519 if(( i = test_bitfield_count_range( ))) 518 520 return i; -
trunk/libtransmission/webseed.c
r12204 r12248 338 338 peer->clientIsInterested = !tr_torrentIsSeed( tor ); 339 339 peer->client = tr_strdup( "webseed" ); 340 tr_bit setSetHaveAll( &peer->have );340 tr_bitfieldSetHasAll( &peer->have ); 341 341 tr_peerUpdateProgress( tor, peer ); 342 342
Note: See TracChangeset
for help on using the changeset viewer.