Пример #1
0
void
tr_cpConstruct( tr_completion * cp, tr_torrent * tor )
{
    cp->tor = tor;
    tr_bitfieldConstruct( &cp->blockBitfield, tor->blockCount );
    tr_cpReset( cp );
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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 );
}
Пример #6
0
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;
}
Пример #7
0
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;
}
Пример #8
0
/* 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;
}