예제 #1
0
파일: completion.c 프로젝트: AllardJ/Tomato
size_t
tr_cpMissingBytesInPiece (const tr_completion * cp, tr_piece_index_t piece)
{
  if (tr_cpHasAll (cp))
    {
      return 0;
    }
  else
    {
      size_t haveBytes = 0;
      tr_block_index_t f, l;
      const size_t pieceByteSize = tr_torPieceCountBytes (cp->tor, piece);
      tr_torGetPieceBlockRange (cp->tor, piece, &f, &l);
      if (f != l)
        {
          /* nb: we don't pass the usual l+1 here to tr_bitfieldCountRange ().
             It's faster to handle the last block separately because its size
             needs to be checked separately. */
          haveBytes = tr_bitfieldCountRange (&cp->blockBitfield, f, l);
          haveBytes *= cp->tor->blockSize;
        }

      if (tr_bitfieldHas (&cp->blockBitfield, l)) /* handle the last block */
        haveBytes += tr_torBlockCountBytes (cp->tor, l);

      assert (haveBytes <= pieceByteSize);
      return pieceByteSize - haveBytes;
    }
}
uint64_t
tr_cpSizeWhenDone( const tr_completion * ccp )
{
    if( ccp->sizeWhenDoneIsDirty )
    {
        uint64_t size = 0;
        const tr_torrent * tor = ccp->tor;
        const tr_info * inf = tr_torrentInfo( tor );
        tr_completion * cp = (tr_completion *) ccp; /* mutable */

        if( tr_cpHasAll( ccp ) )
        {
            size = inf->totalSize;
        }
        else
        {
            tr_piece_index_t p;

            for( p=0; p<inf->pieceCount; ++p )
            {
                uint64_t n = 0;
                const uint64_t pieceSize = tr_torPieceCountBytes( tor, p );

                if( !inf->pieces[p].dnd )
                {
                    n = pieceSize;
                }
                else
                {
                    uint64_t o = 0;
                    tr_block_index_t b, f, l;
                    tr_torGetPieceBlockRange( cp->tor, p, &f, &l );
                    for( b=f; b<=l; ++b )
                        if( tr_cpBlockIsComplete( cp, b ) )
                            n += tr_torBlockCountBytes( tor, b );

                    o = tr_bitfieldCountRange( &cp->blockBitfield, f, l+1 );
                    o *= cp->tor->blockSize;
                    if( l == ( cp->tor->blockCount - 1 )  && tr_bitfieldHas( &cp->blockBitfield, l ) )
                        o -= ( cp->tor->blockSize - cp->tor->lastBlockSize );

                    assert( n == o );
                }

                assert( n <= tr_torPieceCountBytes( tor, p ) );
                size += n;
            }
        }

        assert( size <= inf->totalSize );
        assert( size >= cp->sizeNow );

        cp->sizeWhenDoneLazy = size;
        cp->sizeWhenDoneIsDirty = false;
    }

    return ccp->sizeWhenDoneLazy;
}
예제 #3
0
void
tr_cpPieceAdd( tr_completion * cp, tr_piece_index_t piece )
{
    tr_block_index_t i, f, l;
    tr_torGetPieceBlockRange( cp->tor, piece, &f, &l );

    for( i=f; i<=l; ++i )
        tr_cpBlockAdd( cp, i );
}
예제 #4
0
size_t
tr_cpMissingBlocksInPiece( const tr_completion * cp, tr_piece_index_t piece )
{
    if( tr_cpHasAll( cp ) )
        return 0;
    else {
        tr_block_index_t f, l;
        tr_torGetPieceBlockRange( cp->tor, piece, &f, &l );
        return (l+1-f) - tr_bitfieldCountRange( &cp->blockBitfield, f, l+1 );
    }
}
예제 #5
0
uint64_t tr_cpSizeWhenDone(tr_completion const* ccp)
{
    if (ccp->sizeWhenDoneIsDirty)
    {
        uint64_t size = 0;
        tr_torrent const* tor = ccp->tor;
        tr_info const* inf = tr_torrentInfo(tor);
        tr_completion* cp = (tr_completion*)ccp; /* mutable */

        if (tr_cpHasAll(ccp))
        {
            size = inf->totalSize;
        }
        else
        {
            for (tr_piece_index_t p = 0; p < inf->pieceCount; ++p)
            {
                uint64_t n = 0;
                uint64_t const pieceSize = tr_torPieceCountBytes(tor, p);

                if (!inf->pieces[p].dnd)
                {
                    n = pieceSize;
                }
                else
                {
                    tr_block_index_t f;
                    tr_block_index_t l;
                    tr_torGetPieceBlockRange(cp->tor, p, &f, &l);

                    n = tr_bitfieldCountRange(&cp->blockBitfield, f, l + 1);
                    n *= cp->tor->blockSize;

                    if (l == cp->tor->blockCount - 1 && tr_bitfieldHas(&cp->blockBitfield, l))
                    {
                        n -= cp->tor->blockSize - cp->tor->lastBlockSize;
                    }
                }

                TR_ASSERT(n <= tr_torPieceCountBytes(tor, p));
                size += n;
            }
        }

        TR_ASSERT(size <= inf->totalSize);
        TR_ASSERT(size >= cp->sizeNow);

        cp->sizeWhenDoneLazy = size;
        cp->sizeWhenDoneIsDirty = false;
    }

    return ccp->sizeWhenDoneLazy;
}
예제 #6
0
void
tr_cpPieceRem( tr_completion *  cp, tr_piece_index_t piece )
{
    tr_block_index_t i, f, l;
    const tr_torrent * tor = cp->tor;

    tr_torGetPieceBlockRange( cp->tor, piece, &f, &l );

    for( i=f; i<=l; ++i )
        if( tr_cpBlockIsComplete( cp, i ) )
            cp->sizeNow -= tr_torBlockCountBytes( tor, i );

    cp->haveValidIsDirty = true;
    cp->sizeWhenDoneIsDirty = true;
    tr_bitfieldRemRange( &cp->blockBitfield, f, l+1 );
}
예제 #7
0
void
tr_cpGetAmountDone( const tr_completion * cp, float * tab, int tabCount )
{
    int i;
    const bool seed = tr_cpHasAll( cp );
    const float interval = cp->tor->info.pieceCount / (float)tabCount;

    for( i=0; i<tabCount; ++i ) {
        if( seed )
            tab[i] = 1.0f;
        else {
            tr_block_index_t f, l;
            const tr_piece_index_t piece = (tr_piece_index_t)i * interval;
            tr_torGetPieceBlockRange( cp->tor, piece, &f, &l );
            tab[i] = tr_bitfieldCountRange( &cp->blockBitfield, f, l+1 )
                                                            / (float)(l+1-f);
        }
    }
}