Ejemplo n.º 1
0
void
tr_cpBlockAdd( tr_completion *  cp,
               tr_block_index_t block )
{
    const tr_torrent * tor = cp->tor;

    if( !tr_cpBlockIsComplete( cp, block ) )
    {
        const tr_piece_index_t piece = tr_torBlockPiece( tor, block );
        const int              blockSize = tr_torBlockCountBytes( tor,
                                                                  block );

        ++cp->completeBlocks[piece];

        if( tr_cpPieceIsComplete( cp, piece ) )
            tr_bitfieldAdd( cp->pieceBitfield, piece );

        tr_bitfieldAdd( cp->blockBitfield, block );

        cp->sizeNow += blockSize;

        cp->haveValidIsDirty = 1;
        cp->sizeWhenDoneIsDirty = 1;
    }
}
Ejemplo n.º 2
0
static int
test_bitfields (void)
{
  unsigned int i;
  unsigned int bitcount = 500;
  tr_bitfield field;

  tr_bitfieldConstruct (&field, bitcount);

  /* test tr_bitfieldAdd */
  for (i=0; i<bitcount; i++)
    if (! (i % 7))
      tr_bitfieldAdd (&field, i);
  for (i=0; i<bitcount; i++)
    check (tr_bitfieldHas (&field, i) == (! (i % 7)));

  /* test tr_bitfieldAddRange */
  tr_bitfieldAddRange (&field, 0, bitcount);
  for (i=0; i<bitcount; i++)
    check (tr_bitfieldHas (&field, i));

  /* test tr_bitfieldRemRange in the middle of a boundary */
  tr_bitfieldRemRange (&field, 4, 21);
  for (i=0; i<64; i++)
    check (tr_bitfieldHas (&field, i) == ((i < 4) || (i >= 21)));

  /* test tr_bitfieldRemRange on the boundaries */
  tr_bitfieldAddRange (&field, 0, 64);
  tr_bitfieldRemRange (&field, 8, 24);
  for (i=0; i<64; i++)
    check (tr_bitfieldHas (&field, i) == ((i < 8) || (i >= 24)));

  /* test tr_bitfieldRemRange when begin & end is on the same word */
  tr_bitfieldAddRange (&field, 0, 64);
  tr_bitfieldRemRange (&field, 4, 5);
  for (i=0; i<64; i++)
    check (tr_bitfieldHas (&field, i) == ((i < 4) || (i >= 5)));

  /* test tr_bitfieldAddRange */
  tr_bitfieldRemRange (&field, 0, 64);
  tr_bitfieldAddRange (&field, 4, 21);
  for (i=0; i<64; i++)
    check (tr_bitfieldHas (&field, i) == ((4 <= i) && (i < 21)));

  /* test tr_bitfieldAddRange on the boundaries */
  tr_bitfieldRemRange (&field, 0, 64);
  tr_bitfieldAddRange (&field, 8, 24);
  for (i=0; i<64; i++)
    check (tr_bitfieldHas (&field, i) == ((8 <= i) && (i < 24)));

  /* test tr_bitfieldAddRange when begin & end is on the same word */
  tr_bitfieldRemRange (&field, 0, 64);
  tr_bitfieldAddRange (&field, 4, 5);
  for (i=0; i<64; i++)
    check (tr_bitfieldHas (&field, i) == ((4 <= i) && (i < 5)));

  tr_bitfieldDestruct (&field);
  return 0;
}
Ejemplo n.º 3
0
void tr_cpBlockAdd( tr_completion_t * cp, int block )
{
    tr_torrent_t * tor = cp->tor;
    if( !tr_cpBlockIsComplete( cp, block ) )
    {
        (cp->blockCount)++;
        if( !cp->blockDownloaders[block] )
        {
            (cp->missingBlocks[tr_blockPiece(block)])--;
        }
    }
    tr_bitfieldAdd( cp->blockBitfield, block );
}
Ejemplo n.º 4
0
void
tr_cpBlockAdd( tr_completion * cp, tr_block_index_t block )
{
    const tr_torrent * tor = cp->tor;

    if( !tr_cpBlockIsComplete( cp, block ) )
    {
        tr_bitfieldAdd( &cp->blockBitfield, block );
        cp->sizeNow += tr_torBlockCountBytes( tor, block );

        cp->haveValidIsDirty = true;
        cp->sizeWhenDoneIsDirty = true;
    }
}
Ejemplo n.º 5
0
void tr_cpPieceAdd( tr_completion_t * cp, int piece )
{
    tr_torrent_t * tor = cp->tor;
    int startBlock, endBlock, i;

    startBlock = tr_pieceStartBlock( piece );
    endBlock   = startBlock + tr_pieceCountBlocks( piece );
    for( i = startBlock; i < endBlock; i++ )
    {
        tr_cpBlockAdd( cp, i );
    }

    tr_bitfieldAdd( cp->pieceBitfield, piece );
}
Ejemplo n.º 6
0
void tr_cpBlockAdd(tr_completion* cp, tr_block_index_t block)
{
    tr_torrent const* tor = cp->tor;

    if (!tr_cpBlockIsComplete(cp, block))
    {
        tr_piece_index_t const piece = tr_torBlockPiece(cp->tor, block);

        tr_bitfieldAdd(&cp->blockBitfield, block);
        cp->sizeNow += tr_torBlockCountBytes(tor, block);

        cp->haveValidIsDirty = true;
        cp->sizeWhenDoneIsDirty |= tor->info.pieces[piece].dnd;
    }
}
Ejemplo n.º 7
0
static int
test_bitfield_count_range (void)
{
  int i;
  int n;
  int begin;
  int end;
  int count1;
  int count2;
  const int bitCount = 100 + tr_cryptoWeakRandInt (1000);
  tr_bitfield bf;

  /* generate a random bitfield */
  tr_bitfieldConstruct (&bf, bitCount);
  for (i=0, n=tr_cryptoWeakRandInt (bitCount); i<n; ++i)
    tr_bitfieldAdd (&bf, tr_cryptoWeakRandInt (bitCount));
  begin = tr_cryptoWeakRandInt (bitCount);
  do
    end = tr_cryptoWeakRandInt (bitCount);
  while (end == begin);

  /* ensure end <= begin */
  if (end < begin)
    {
      const int tmp = begin;
      begin = end;
      end = tmp;
    }

  /* test the bitfield */
  count1 = 0;
  for (i=begin; i<end; ++i)
    if (tr_bitfieldHas (&bf, i))
      ++count1;
  count2 = tr_bitfieldCountRange (&bf, begin, end);
  check (count1 == count2);

  /* cleanup */
  tr_bitfieldDestruct (&bf);
  return 0;
}
Ejemplo n.º 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;
}