Changeset 13674
- Timestamp:
- Dec 15, 2012, 4:28:19 AM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/completion.c
r13673 r13674 25 25 tr_cpReset (tr_completion * cp) 26 26 { 27 28 29 30 27 cp->sizeNow = 0; 28 cp->sizeWhenDoneIsDirty = true; 29 cp->haveValidIsDirty = true; 30 tr_bitfieldSetHasNone (&cp->blockBitfield); 31 31 } 32 32 … … 34 34 tr_cpConstruct (tr_completion * cp, tr_torrent * tor) 35 35 { 36 37 38 36 cp->tor = tor; 37 tr_bitfieldConstruct (&cp->blockBitfield, tor->blockCount); 38 tr_cpReset (cp); 39 39 } 40 40 … … 42 42 tr_cpBlockInit (tr_completion * cp, const tr_bitfield * b) 43 43 { 44 tr_cpReset (cp); 45 46 /* set blockBitfield */ 47 tr_bitfieldSetFromBitfield (&cp->blockBitfield, b); 48 49 /* set sizeNow */ 50 cp->sizeNow = tr_bitfieldCountTrueBits (&cp->blockBitfield); 51 assert (cp->sizeNow <= cp->tor->blockCount); 52 cp->sizeNow *= cp->tor->blockSize; 53 if (tr_bitfieldHas (b, cp->tor->blockCount-1)) 54 cp->sizeNow -= (cp->tor->blockSize - cp->tor->lastBlockSize); 55 assert (cp->sizeNow <= cp->tor->info.totalSize); 44 tr_cpReset (cp); 45 46 /* set blockBitfield */ 47 tr_bitfieldSetFromBitfield (&cp->blockBitfield, b); 48 49 /* set sizeNow */ 50 cp->sizeNow = tr_bitfieldCountTrueBits (&cp->blockBitfield); 51 assert (cp->sizeNow <= cp->tor->blockCount); 52 cp->sizeNow *= cp->tor->blockSize; 53 if (tr_bitfieldHas (b, cp->tor->blockCount-1)) 54 cp->sizeNow -= (cp->tor->blockSize - cp->tor->lastBlockSize); 55 56 assert (cp->sizeNow <= cp->tor->info.totalSize); 56 57 } 57 58 … … 63 64 tr_cpGetStatus (const tr_completion * cp) 64 65 { 65 if (tr_cpHasAll (cp)) return TR_SEED; 66 if (!tr_torrentHasMetadata (cp->tor)) return TR_LEECH; 67 if (cp->sizeNow == tr_cpSizeWhenDone (cp)) return TR_PARTIAL_SEED; 66 if (tr_cpHasAll (cp)) 67 return TR_SEED; 68 69 if (!tr_torrentHasMetadata (cp->tor)) 68 70 return TR_LEECH; 71 72 if (cp->sizeNow == tr_cpSizeWhenDone (cp)) 73 return TR_PARTIAL_SEED; 74 75 return TR_LEECH; 69 76 } 70 77 … … 72 79 tr_cpPieceRem (tr_completion * cp, tr_piece_index_t piece) 73 80 { 74 75 76 77 78 79 80 81 82 83 84 85 81 tr_block_index_t i, f, l; 82 const tr_torrent * tor = cp->tor; 83 84 tr_torGetPieceBlockRange (cp->tor, piece, &f, &l); 85 86 for (i=f; i<=l; ++i) 87 if (tr_cpBlockIsComplete (cp, i)) 88 cp->sizeNow -= tr_torBlockCountBytes (tor, i); 89 90 cp->haveValidIsDirty = true; 91 cp->sizeWhenDoneIsDirty = true; 92 tr_bitfieldRemRange (&cp->blockBitfield, f, l+1); 86 93 } 87 94 … … 89 96 tr_cpPieceAdd (tr_completion * cp, tr_piece_index_t piece) 90 97 { 91 92 93 94 95 98 tr_block_index_t i, f, l; 99 tr_torGetPieceBlockRange (cp->tor, piece, &f, &l); 100 101 for (i=f; i<=l; ++i) 102 tr_cpBlockAdd (cp, i); 96 103 } 97 104 … … 99 106 tr_cpBlockAdd (tr_completion * cp, tr_block_index_t block) 100 107 { 101 102 103 104 { 105 106 107 108 109 110 111 108 const tr_torrent * tor = cp->tor; 109 110 if (!tr_cpBlockIsComplete (cp, block)) 111 { 112 const tr_piece_index_t piece = tr_torBlockPiece (cp->tor, block); 113 114 tr_bitfieldAdd (&cp->blockBitfield, block); 115 cp->sizeNow += tr_torBlockCountBytes (tor, block); 116 117 cp->haveValidIsDirty = true; 118 cp->sizeWhenDoneIsDirty |= tor->info.pieces[piece].dnd; 112 119 } 113 120 } … … 120 127 tr_cpHaveValid (const tr_completion * ccp) 121 128 { 122 123 { 124 125 126 127 128 129 130 131 132 133 134 135 136 } 137 138 129 if (ccp->haveValidIsDirty) 130 { 131 tr_piece_index_t i; 132 uint64_t size = 0; 133 tr_completion * cp = (tr_completion *) ccp; /* mutable */ 134 const tr_torrent * tor = ccp->tor; 135 const tr_info * info = &tor->info; 136 137 for (i=0; i<info->pieceCount; ++i) 138 if (tr_cpPieceIsComplete (ccp, i)) 139 size += tr_torPieceCountBytes (tor, i); 140 141 cp->haveValidLazy = size; 142 cp->haveValidIsDirty = false; 143 } 144 145 return ccp->haveValidLazy; 139 146 } 140 147 … … 142 149 tr_cpSizeWhenDone (const tr_completion * ccp) 143 150 { 144 145 { 146 147 148 149 150 151 152 { 153 154 } 155 156 { 157 158 159 151 if (ccp->sizeWhenDoneIsDirty) 152 { 153 uint64_t size = 0; 154 const tr_torrent * tor = ccp->tor; 155 const tr_info * inf = tr_torrentInfo (tor); 156 tr_completion * cp = (tr_completion *) ccp; /* mutable */ 157 158 if (tr_cpHasAll (ccp)) 159 { 160 size = inf->totalSize; 161 } 162 else 163 { 164 tr_piece_index_t p; 165 166 for (p=0; p<inf->pieceCount; ++p) 160 167 { 161 162 163 164 168 uint64_t n = 0; 169 const uint64_t pieceSize = tr_torPieceCountBytes (tor, p); 170 171 if (!inf->pieces[p].dnd) 165 172 { 166 173 n = pieceSize; 167 174 } 168 175 else 169 176 { 170 171 172 173 174 175 if (l == (cp->tor->blockCount - 1)&& tr_bitfieldHas (&cp->blockBitfield, l))176 177 tr_block_index_t f, l; 178 tr_torGetPieceBlockRange (cp->tor, p, &f, &l); 179 180 n = tr_bitfieldCountRange (&cp->blockBitfield, f, l+1); 181 n *= cp->tor->blockSize; 182 if (l == (cp->tor->blockCount-1) && tr_bitfieldHas (&cp->blockBitfield, l)) 183 n -= (cp->tor->blockSize - cp->tor->lastBlockSize); 177 184 } 178 185 179 180 186 assert (n <= tr_torPieceCountBytes (tor, p)); 187 size += n; 181 188 } 182 189 } 183 190 184 185 186 187 188 189 } 190 191 191 assert (size <= inf->totalSize); 192 assert (size >= cp->sizeNow); 193 194 cp->sizeWhenDoneLazy = size; 195 cp->sizeWhenDoneIsDirty = false; 196 } 197 198 return ccp->sizeWhenDoneLazy; 192 199 } 193 200 … … 195 202 tr_cpLeftUntilDone (const tr_completion * cp) 196 203 { 197 198 199 200 201 204 const uint64_t sizeWhenDone = tr_cpSizeWhenDone (cp); 205 206 assert (sizeWhenDone >= cp->sizeNow); 207 208 return sizeWhenDone - cp->sizeNow; 202 209 } 203 210 … … 205 212 tr_cpGetAmountDone (const tr_completion * cp, float * tab, int tabCount) 206 213 { 207 int i; 208 const bool seed = tr_cpHasAll (cp); 209 const float interval = cp->tor->info.pieceCount / (float)tabCount; 210 211 for (i=0; i<tabCount; ++i) { 212 if (seed) 213 tab[i] = 1.0f; 214 else { 215 tr_block_index_t f, l; 216 const tr_piece_index_t piece = (tr_piece_index_t)i * interval; 217 tr_torGetPieceBlockRange (cp->tor, piece, &f, &l); 218 tab[i] = tr_bitfieldCountRange (&cp->blockBitfield, f, l+1) 219 / (float)(l+1-f); 214 int i; 215 const bool seed = tr_cpHasAll (cp); 216 const float interval = cp->tor->info.pieceCount / (float)tabCount; 217 218 for (i=0; i<tabCount; ++i) 219 { 220 if (seed) 221 { 222 tab[i] = 1.0f; 223 } 224 else 225 { 226 tr_block_index_t f, l; 227 const tr_piece_index_t piece = (tr_piece_index_t)i * interval; 228 tr_torGetPieceBlockRange (cp->tor, piece, &f, &l); 229 tab[i] = tr_bitfieldCountRange (&cp->blockBitfield, f, l+1) / (float)(l+1-f); 220 230 } 221 231 } … … 225 235 tr_cpMissingBlocksInPiece (const tr_completion * cp, tr_piece_index_t piece) 226 236 { 227 if (tr_cpHasAll (cp)) 228 return 0; 229 else { 230 tr_block_index_t f, l; 231 tr_torGetPieceBlockRange (cp->tor, piece, &f, &l); 232 return (l+1-f) - tr_bitfieldCountRange (&cp->blockBitfield, f, l+1); 237 if (tr_cpHasAll (cp)) 238 { 239 return 0; 240 } 241 else 242 { 243 tr_block_index_t f, l; 244 tr_torGetPieceBlockRange (cp->tor, piece, &f, &l); 245 return (l+1-f) - tr_bitfieldCountRange (&cp->blockBitfield, f, l+1); 233 246 } 234 247 } … … 237 250 tr_cpMissingBytesInPiece (const tr_completion * cp, tr_piece_index_t piece) 238 251 { 239 if (tr_cpHasAll (cp)) 240 return 0; 241 else { 242 size_t haveBytes = 0; 243 tr_block_index_t f, l; 244 const size_t pieceByteSize = tr_torPieceCountBytes (cp->tor, piece); 245 tr_torGetPieceBlockRange (cp->tor, piece, &f, &l); 246 if (f != l) { 247 /* nb: we don't pass the usual l+1 here to tr_bitfieldCountRange (). 248 It's faster to handle the last block separately because its size 249 needs to be checked separately. */ 250 haveBytes = tr_bitfieldCountRange (&cp->blockBitfield, f, l); 251 haveBytes *= cp->tor->blockSize; 252 } 253 if (tr_bitfieldHas (&cp->blockBitfield, l)) /* handle the last block */ 254 haveBytes += tr_torBlockCountBytes (cp->tor, l); 255 assert (haveBytes <= pieceByteSize); 256 return pieceByteSize - haveBytes; 252 if (tr_cpHasAll (cp)) 253 { 254 return 0; 255 } 256 else 257 { 258 size_t haveBytes = 0; 259 tr_block_index_t f, l; 260 const size_t pieceByteSize = tr_torPieceCountBytes (cp->tor, piece); 261 tr_torGetPieceBlockRange (cp->tor, piece, &f, &l); 262 if (f != l) 263 { 264 /* nb: we don't pass the usual l+1 here to tr_bitfieldCountRange (). 265 It's faster to handle the last block separately because its size 266 needs to be checked separately. */ 267 haveBytes = tr_bitfieldCountRange (&cp->blockBitfield, f, l); 268 haveBytes *= cp->tor->blockSize; 269 } 270 271 if (tr_bitfieldHas (&cp->blockBitfield, l)) /* handle the last block */ 272 haveBytes += tr_torBlockCountBytes (cp->tor, l); 273 274 assert (haveBytes <= pieceByteSize); 275 return pieceByteSize - haveBytes; 257 276 } 258 277 } … … 261 280 tr_cpFileIsComplete (const tr_completion * cp, tr_file_index_t i) 262 281 { 263 if (cp->tor->info.files[i].length == 0) 264 return true; 265 else { 266 tr_block_index_t f, l; 267 tr_torGetFileBlockRange (cp->tor, i, &f, &l); 268 return tr_bitfieldCountRange (&cp->blockBitfield, f, l+1) == (l+1-f); 282 if (cp->tor->info.files[i].length == 0) 283 { 284 return true; 285 } 286 else 287 { 288 tr_block_index_t f, l; 289 tr_torGetFileBlockRange (cp->tor, i, &f, &l); 290 return tr_bitfieldCountRange (&cp->blockBitfield, f, l+1) == (l+1-f); 269 291 } 270 292 } … … 273 295 tr_cpCreatePieceBitfield (const tr_completion * cp, size_t * byte_count) 274 296 { 275 void * ret; 276 tr_piece_index_t n; 277 tr_bitfield pieces; 278 279 assert (tr_torrentHasMetadata (cp->tor)); 280 281 n = cp->tor->info.pieceCount; 282 tr_bitfieldConstruct (&pieces, n); 283 284 if (tr_cpHasAll (cp)) 285 tr_bitfieldSetHasAll (&pieces); 286 else if (!tr_cpHasNone (cp)) { 287 tr_piece_index_t i; 288 bool * flags = tr_new (bool, n); 289 for (i=0; i<n; ++i) 290 flags[i] = tr_cpPieceIsComplete (cp, i); 291 tr_bitfieldSetFromFlags (&pieces, flags, n); 292 tr_free (flags); 293 } 294 295 ret = tr_bitfieldGetRaw (&pieces, byte_count); 296 tr_bitfieldDestruct (&pieces); 297 return ret; 297 void * ret; 298 tr_piece_index_t n; 299 tr_bitfield pieces; 300 301 assert (tr_torrentHasMetadata (cp->tor)); 302 303 n = cp->tor->info.pieceCount; 304 tr_bitfieldConstruct (&pieces, n); 305 306 if (tr_cpHasAll (cp)) 307 { 308 tr_bitfieldSetHasAll (&pieces); 309 } 310 else if (!tr_cpHasNone (cp)) 311 { 312 tr_piece_index_t i; 313 bool * flags = tr_new (bool, n); 314 for (i=0; i<n; ++i) 315 flags[i] = tr_cpPieceIsComplete (cp, i); 316 tr_bitfieldSetFromFlags (&pieces, flags, n); 317 tr_free (flags); 318 } 319 320 ret = tr_bitfieldGetRaw (&pieces, byte_count); 321 tr_bitfieldDestruct (&pieces); 322 return ret; 298 323 } 299 324 … … 301 326 tr_cpPercentComplete (const tr_completion * cp) 302 327 { 303 304 305 306 307 308 309 310 328 const double ratio = tr_getRatio (cp->sizeNow, cp->tor->info.totalSize); 329 330 if ((int)ratio == TR_RATIO_NA) 331 return 0.0; 332 else if ((int)ratio == TR_RATIO_INF) 333 return 1.0; 334 else 335 return ratio; 311 336 } 312 337 … … 314 339 tr_cpPercentDone (const tr_completion * cp) 315 340 { 316 const double ratio = tr_getRatio (cp->sizeNow, tr_cpSizeWhenDone (cp)); 317 const int iratio = (int)ratio; 318 return ((iratio == TR_RATIO_NA) || (iratio == TR_RATIO_INF)) ? 0.0 : ratio; 319 } 341 const double ratio = tr_getRatio (cp->sizeNow, tr_cpSizeWhenDone (cp)); 342 const int iratio = (int)ratio; 343 return ((iratio == TR_RATIO_NA) || (iratio == TR_RATIO_INF)) ? 0.0 : ratio; 344 } 345
Note: See TracChangeset
for help on using the changeset viewer.