void tr_cpConstruct( tr_completion * cp, tr_torrent * tor ) { cp->tor = tor; tr_bitfieldConstruct( &cp->blockBitfield, tor->blockCount ); tr_cpReset( cp ); }
tr_completion * tr_cpConstruct( tr_completion * cp, tr_torrent * tor ) { cp->tor = tor; cp->completeBlocks = tr_new( uint16_t, tor->info.pieceCount ); tr_bitfieldConstruct( &cp->blockBitfield, tor->blockCount ); tr_bitfieldConstruct( &cp->pieceBitfield, tor->info.pieceCount ); tr_cpReset( cp ); return cp; }
tr_completion * tr_cpInit( tr_torrent * tor ) { tr_completion * cp = tr_new( tr_completion, 1 ); cp->tor = tor; cp->blockBitfield = tr_bitfieldNew( tor->blockCount ); cp->pieceBitfield = tr_bitfieldNew( tor->info.pieceCount ); cp->completeBlocks = tr_new( uint16_t, tor->info.pieceCount ); tr_cpReset( cp ); return cp; }
tr_completion_t * tr_cpInit( tr_torrent_t * tor ) { tr_completion_t * cp; cp = malloc( sizeof( tr_completion_t ) ); cp->tor = tor; cp->blockBitfield = malloc( ( tor->blockCount + 7 ) / 8 ); cp->blockDownloaders = malloc( tor->blockCount ); cp->pieceBitfield = malloc( ( tor->info.pieceCount + 7 ) / 8 ); cp->missingBlocks = malloc( tor->info.pieceCount * sizeof( int ) ); tr_cpReset( cp ); return cp; }
void tr_cpBlockInit( tr_completion * cp, const tr_bitfield * b ) { tr_cpReset( cp ); /* set blockBitfield */ tr_bitfieldSetFromBitfield( &cp->blockBitfield, b ); /* set sizeNow */ cp->sizeNow = tr_bitfieldCountTrueBits( &cp->blockBitfield ); assert( cp->sizeNow <= cp->tor->blockCount ); cp->sizeNow *= cp->tor->blockSize; if( tr_bitfieldHas( b, cp->tor->blockCount-1 ) ) cp->sizeNow -= ( cp->tor->blockSize - cp->tor->lastBlockSize ); assert( cp->sizeNow <= cp->tor->info.totalSize ); }
void tr_cpSetHaveAll( tr_completion * cp ) { tr_piece_index_t i; tr_torrent * tor = cp->tor; tr_cpReset( cp ); cp->sizeNow = tor->info.totalSize; tr_bitfieldAddRange( &cp->blockBitfield, 0, tor->blockCount ); tr_bitfieldAddRange( &cp->pieceBitfield, 0, tor->info.pieceCount ); for( i=0; i<tor->info.pieceCount; ++i ) cp->completeBlocks[i] = tr_torPieceCountBlocks( tor, i ); cp->sizeWhenDoneIsDirty = 1; cp->haveValidIsDirty = 1; }
int tr_cpBlockBitfieldSet( tr_completion * cp, tr_bitfield * bitfield ) { int success = FALSE; assert( cp ); assert( bitfield ); assert( cp->blockBitfield ); if( tr_bitfieldTestFast( bitfield, cp->tor->blockCount - 1 ) ) { tr_block_index_t i; tr_cpReset( cp ); for( i = 0; i < cp->tor->blockCount; ++i ) if( tr_bitfieldHasFast( bitfield, i ) ) tr_cpBlockAdd( cp, i ); success = TRUE; } return success; }
/* Initialize a completion object from a bitfield indicating which blocks we have */ tr_bool tr_cpBlockBitfieldSet( tr_completion * cp, tr_bitfield * blockBitfield ) { tr_bool success = FALSE; assert( cp ); assert( blockBitfield ); /* The bitfield of block flags is typically loaded from a resume file. Test the bitfield's length in case the resume file somehow got corrupted */ if(( success = blockBitfield->byteCount == cp->blockBitfield.byteCount )) { tr_block_index_t b = 0; tr_piece_index_t p = 0; uint32_t pieceBlock = 0; uint16_t completeBlocksInPiece = 0; tr_block_index_t completeBlocksInTorrent = 0; uint32_t blocksInCurrentPiece = tr_torPieceCountBlocks( cp->tor, p ); /* start cp with a state where it thinks we have nothing */ tr_cpReset( cp ); /* init our block bitfield from the one passed in */ memcpy( cp->blockBitfield.bits, blockBitfield->bits, blockBitfield->byteCount ); /* invalidate the fields that are lazy-evaluated */ cp->sizeWhenDoneIsDirty = TRUE; cp->haveValidIsDirty = TRUE; /* to set the remaining fields, we walk through every block... */ while( b < cp->tor->blockCount ) { if( tr_bitfieldHasFast( blockBitfield, b ) ) ++completeBlocksInPiece; ++b; ++pieceBlock; /* by the time we reach the end of a piece, we have enough info to update that piece's slot in cp.completeBlocks and cp.pieceBitfield */ if( pieceBlock == blocksInCurrentPiece ) { cp->completeBlocks[p] = completeBlocksInPiece; completeBlocksInTorrent += completeBlocksInPiece; if( completeBlocksInPiece == blocksInCurrentPiece ) tr_bitfieldAdd( &cp->pieceBitfield, p ); /* reset the per-piece counters because we're starting on a new piece now */ ++p; completeBlocksInPiece = 0; pieceBlock = 0; blocksInCurrentPiece = tr_torPieceCountBlocks( cp->tor, p ); } } /* update sizeNow */ cp->sizeNow = completeBlocksInTorrent; cp->sizeNow *= tr_torBlockCountBytes( cp->tor, 0 ); if( tr_bitfieldHasFast( &cp->blockBitfield, cp->tor->blockCount-1 ) ) { /* the last block is usually smaller than the other blocks, so handle that special case or cp->sizeNow might be too large */ cp->sizeNow -= tr_torBlockCountBytes( cp->tor, 0 ); cp->sizeNow += tr_torBlockCountBytes( cp->tor, cp->tor->blockCount-1 ); } } return success; }