forked from premiere/premiere-libtorrent
piece picker optimization
This commit is contained in:
parent
708202575f
commit
4956639171
|
@ -92,12 +92,14 @@ namespace libtorrent
|
||||||
|
|
||||||
struct block_info
|
struct block_info
|
||||||
{
|
{
|
||||||
block_info(): num_downloads(0) {}
|
block_info(): num_downloads(0), requested(0), finished(0) {}
|
||||||
// the peer this block was requested or
|
// the peer this block was requested or
|
||||||
// downloaded from
|
// downloaded from
|
||||||
tcp::endpoint peer;
|
tcp::endpoint peer;
|
||||||
// the number of times this block has been downloaded
|
// the number of times this block has been downloaded
|
||||||
int num_downloads;
|
unsigned num_downloads:14;
|
||||||
|
unsigned requested:1;
|
||||||
|
unsigned finished:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
// the peers that are downloading this piece
|
// the peers that are downloading this piece
|
||||||
|
@ -109,17 +111,15 @@ namespace libtorrent
|
||||||
|
|
||||||
struct downloading_piece
|
struct downloading_piece
|
||||||
{
|
{
|
||||||
|
downloading_piece(): finished(0), requested(0) {}
|
||||||
piece_state_t state;
|
piece_state_t state;
|
||||||
|
|
||||||
// the index of the piece
|
// the index of the piece
|
||||||
int index;
|
int index;
|
||||||
// each bit represents a block in the piece
|
|
||||||
// set to one if the block has been requested
|
|
||||||
std::bitset<max_blocks_per_piece> requested_blocks;
|
|
||||||
// the bit is set to one if the block has been acquired
|
|
||||||
std::bitset<max_blocks_per_piece> finished_blocks;
|
|
||||||
// info about each block
|
// info about each block
|
||||||
block_info info[max_blocks_per_piece];
|
block_info info[max_blocks_per_piece];
|
||||||
|
boost::uint16_t finished;
|
||||||
|
boost::uint16_t requested;
|
||||||
};
|
};
|
||||||
|
|
||||||
piece_picker(int blocks_per_piece
|
piece_picker(int blocks_per_piece
|
||||||
|
|
|
@ -51,6 +51,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
#include "libtorrent/torrent_info.hpp"
|
#include "libtorrent/torrent_info.hpp"
|
||||||
|
#include "libtorrent/piece_picker.hpp"
|
||||||
#include "libtorrent/config.hpp"
|
#include "libtorrent/config.hpp"
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
|
@ -153,7 +154,7 @@ namespace libtorrent
|
||||||
unsigned long piece_crc(
|
unsigned long piece_crc(
|
||||||
int slot_index
|
int slot_index
|
||||||
, int block_size
|
, int block_size
|
||||||
, const std::bitset<256>& bitmask);
|
, piece_picker::block_info const* bi);
|
||||||
int slot_for_piece(int piece_index) const;
|
int slot_for_piece(int piece_index) const;
|
||||||
|
|
||||||
size_type read(
|
size_type read(
|
||||||
|
|
|
@ -995,7 +995,7 @@ namespace libtorrent
|
||||||
for (std::vector<piece_picker::downloading_piece>::const_iterator i =
|
for (std::vector<piece_picker::downloading_piece>::const_iterator i =
|
||||||
dl_queue.begin(); i != dl_queue.end(); ++i)
|
dl_queue.begin(); i != dl_queue.end(); ++i)
|
||||||
{
|
{
|
||||||
assert(int(i->finished_blocks.count()) < blocks_per_piece);
|
assert(i->finished < blocks_per_piece);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,7 +117,7 @@ namespace libtorrent
|
||||||
tcp::endpoint peer;
|
tcp::endpoint peer;
|
||||||
for (int j = 0; j < m_blocks_per_piece; ++j)
|
for (int j = 0; j < m_blocks_per_piece; ++j)
|
||||||
{
|
{
|
||||||
if (i->finished_blocks[j])
|
if (i->info[j].finished)
|
||||||
mark_as_finished(piece_block(i->index, j), peer);
|
mark_as_finished(piece_block(i->index, j), peer);
|
||||||
}
|
}
|
||||||
if (is_piece_finished(i->index))
|
if (is_piece_finished(i->index))
|
||||||
|
@ -210,20 +210,27 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
bool blocks_requested = false;
|
bool blocks_requested = false;
|
||||||
int num_blocks = blocks_in_piece(i->index);
|
int num_blocks = blocks_in_piece(i->index);
|
||||||
|
int num_requested = 0;
|
||||||
|
int num_finished = 0;
|
||||||
for (int k = 0; k < num_blocks; ++k)
|
for (int k = 0; k < num_blocks; ++k)
|
||||||
{
|
{
|
||||||
if (i->finished_blocks[k])
|
if (i->info[k].finished)
|
||||||
{
|
{
|
||||||
assert(i->requested_blocks[k]);
|
++num_finished;
|
||||||
|
assert(i->info[k].requested);
|
||||||
|
++num_requested;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (i->requested_blocks[k])
|
if (i->info[k].requested)
|
||||||
{
|
{
|
||||||
|
++num_requested;
|
||||||
blocks_requested = true;
|
blocks_requested = true;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(blocks_requested == (i->state != none));
|
assert(blocks_requested == (i->state != none));
|
||||||
|
assert(num_requested == i->requested);
|
||||||
|
assert(num_finished == i->finished);
|
||||||
|
assert(num_finished <= num_requested);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1010,10 +1017,11 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
for (int j = 0; j < num_blocks_in_piece; ++j)
|
for (int j = 0; j < num_blocks_in_piece; ++j)
|
||||||
{
|
{
|
||||||
if ((p.finished_blocks[j] == 1
|
piece_picker::block_info const& info = p.info[j];
|
||||||
|| p.requested_blocks[j] == 1)
|
if ((info.finished == 1
|
||||||
&& p.info[j].peer != peer
|
|| info.requested == 1)
|
||||||
&& p.info[j].peer != tcp::endpoint())
|
&& info.peer != peer
|
||||||
|
&& info.peer != tcp::endpoint())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1065,9 +1073,10 @@ namespace libtorrent
|
||||||
if (int(backup_blocks.size()) >= num_blocks) continue;
|
if (int(backup_blocks.size()) >= num_blocks) continue;
|
||||||
for (int j = 0; j < num_blocks_in_piece; ++j)
|
for (int j = 0; j < num_blocks_in_piece; ++j)
|
||||||
{
|
{
|
||||||
if (p->finished_blocks[j] == 1) continue;
|
block_info const& info = p->info[j];
|
||||||
if (p->requested_blocks[j] == 1
|
if (info.finished) continue;
|
||||||
&& p->info[j].peer == peer) continue;
|
if (info.requested
|
||||||
|
&& info.peer == peer) continue;
|
||||||
backup_blocks.push_back(piece_block(*i, j));
|
backup_blocks.push_back(piece_block(*i, j));
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
@ -1076,10 +1085,10 @@ namespace libtorrent
|
||||||
for (int j = 0; j < num_blocks_in_piece; ++j)
|
for (int j = 0; j < num_blocks_in_piece; ++j)
|
||||||
{
|
{
|
||||||
// ignore completed blocks
|
// ignore completed blocks
|
||||||
if (p->finished_blocks[j] == 1) continue;
|
block_info const& info = p->info[j];
|
||||||
|
if (info.finished) continue;
|
||||||
// ignore blocks requested from this peer already
|
// ignore blocks requested from this peer already
|
||||||
if (p->requested_blocks[j] == 1
|
if (info.requested && info.peer == peer) continue;
|
||||||
&& p->info[j].peer == peer) continue;
|
|
||||||
// if the piece is fast and the peer is slow, or vice versa,
|
// if the piece is fast and the peer is slow, or vice versa,
|
||||||
// add the block as a backup.
|
// add the block as a backup.
|
||||||
// override this behavior if all the other blocks
|
// override this behavior if all the other blocks
|
||||||
|
@ -1102,7 +1111,7 @@ namespace libtorrent
|
||||||
// blocks that have not been requested from any
|
// blocks that have not been requested from any
|
||||||
// other peer.
|
// other peer.
|
||||||
interesting_blocks.push_back(piece_block(*i, j));
|
interesting_blocks.push_back(piece_block(*i, j));
|
||||||
if (p->requested_blocks[j] == 0)
|
if (p->info[j].requested == 0)
|
||||||
{
|
{
|
||||||
// we have found a block that's free to download
|
// we have found a block that's free to download
|
||||||
num_blocks--;
|
num_blocks--;
|
||||||
|
@ -1146,11 +1155,11 @@ namespace libtorrent
|
||||||
std::vector<downloading_piece>::const_iterator i
|
std::vector<downloading_piece>::const_iterator i
|
||||||
= std::find_if(m_downloads.begin(), m_downloads.end(), has_index(index));
|
= std::find_if(m_downloads.begin(), m_downloads.end(), has_index(index));
|
||||||
assert(i != m_downloads.end());
|
assert(i != m_downloads.end());
|
||||||
assert((int)i->finished_blocks.count() <= m_blocks_per_piece);
|
assert((int)i->finished <= m_blocks_per_piece);
|
||||||
int max_blocks = blocks_in_piece(index);
|
int max_blocks = blocks_in_piece(index);
|
||||||
if ((int)i->finished_blocks.count() < max_blocks) return false;
|
if ((int)i->finished < max_blocks) return false;
|
||||||
|
|
||||||
assert((int)i->requested_blocks.count() == max_blocks);
|
assert((int)i->requested == max_blocks);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1169,7 +1178,7 @@ namespace libtorrent
|
||||||
, has_index(block.piece_index));
|
, has_index(block.piece_index));
|
||||||
|
|
||||||
assert(i != m_downloads.end());
|
assert(i != m_downloads.end());
|
||||||
return i->requested_blocks[block.block_index];
|
return i->info[block.block_index].requested;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool piece_picker::is_finished(piece_block block) const
|
bool piece_picker::is_finished(piece_block block) const
|
||||||
|
@ -1184,7 +1193,7 @@ namespace libtorrent
|
||||||
std::vector<downloading_piece>::const_iterator i
|
std::vector<downloading_piece>::const_iterator i
|
||||||
= std::find_if(m_downloads.begin(), m_downloads.end(), has_index(block.piece_index));
|
= std::find_if(m_downloads.begin(), m_downloads.end(), has_index(block.piece_index));
|
||||||
assert(i != m_downloads.end());
|
assert(i != m_downloads.end());
|
||||||
return i->finished_blocks[block.block_index];
|
return i->info[block.block_index].finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1208,8 +1217,10 @@ namespace libtorrent
|
||||||
downloading_piece dp;
|
downloading_piece dp;
|
||||||
dp.state = state;
|
dp.state = state;
|
||||||
dp.index = block.piece_index;
|
dp.index = block.piece_index;
|
||||||
dp.requested_blocks[block.block_index] = 1;
|
block_info& info = dp.info[block.block_index];
|
||||||
dp.info[block.block_index].peer = peer;
|
info.requested = 1;
|
||||||
|
info.peer = peer;
|
||||||
|
++dp.requested;
|
||||||
m_downloads.push_back(dp);
|
m_downloads.push_back(dp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1217,9 +1228,11 @@ namespace libtorrent
|
||||||
std::vector<downloading_piece>::iterator i
|
std::vector<downloading_piece>::iterator i
|
||||||
= std::find_if(m_downloads.begin(), m_downloads.end(), has_index(block.piece_index));
|
= std::find_if(m_downloads.begin(), m_downloads.end(), has_index(block.piece_index));
|
||||||
assert(i != m_downloads.end());
|
assert(i != m_downloads.end());
|
||||||
assert(i->requested_blocks[block.block_index] == 0);
|
block_info& info = i->info[block.block_index];
|
||||||
i->info[block.block_index].peer = peer;
|
assert(info.requested == 0);
|
||||||
i->requested_blocks[block.block_index] = 1;
|
info.peer = peer;
|
||||||
|
info.requested = 1;
|
||||||
|
++i->requested;
|
||||||
if (i->state == none) i->state = state;
|
if (i->state == none) i->state = state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1245,8 +1258,11 @@ namespace libtorrent
|
||||||
downloading_piece dp;
|
downloading_piece dp;
|
||||||
dp.state = none;
|
dp.state = none;
|
||||||
dp.index = block.piece_index;
|
dp.index = block.piece_index;
|
||||||
dp.requested_blocks[block.block_index] = 1;
|
block_info& info = dp.info[block.block_index];
|
||||||
dp.finished_blocks[block.block_index] = 1;
|
info.requested = 1;
|
||||||
|
info.finished = 1;
|
||||||
|
++dp.requested;
|
||||||
|
++dp.finished;
|
||||||
dp.info[block.block_index].peer = peer;
|
dp.info[block.block_index].peer = peer;
|
||||||
m_downloads.push_back(dp);
|
m_downloads.push_back(dp);
|
||||||
}
|
}
|
||||||
|
@ -1255,25 +1271,14 @@ namespace libtorrent
|
||||||
std::vector<downloading_piece>::iterator i
|
std::vector<downloading_piece>::iterator i
|
||||||
= std::find_if(m_downloads.begin(), m_downloads.end(), has_index(block.piece_index));
|
= std::find_if(m_downloads.begin(), m_downloads.end(), has_index(block.piece_index));
|
||||||
assert(i != m_downloads.end());
|
assert(i != m_downloads.end());
|
||||||
i->info[block.block_index].peer = peer;
|
block_info& info = i->info[block.block_index];
|
||||||
i->requested_blocks[block.block_index] = 1;
|
info.peer = peer;
|
||||||
i->finished_blocks[block.block_index] = 1;
|
if (!info.requested) ++i->requested;
|
||||||
|
info.requested = 1;
|
||||||
|
if (!info.finished) ++i->finished;
|
||||||
|
info.finished = 1;
|
||||||
|
|
||||||
// TODO: maintain requested and finished counters so that
|
if (i->requested == i->finished)
|
||||||
// we don't have to count every time
|
|
||||||
bool blocks_requested = false;
|
|
||||||
int num_blocks = blocks_in_piece(i->index);
|
|
||||||
for (int k = 0; k < num_blocks; ++k)
|
|
||||||
{
|
|
||||||
if (i->finished_blocks[k]) continue;
|
|
||||||
if (i->requested_blocks[k])
|
|
||||||
{
|
|
||||||
blocks_requested = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!blocks_requested)
|
|
||||||
{
|
{
|
||||||
// there are no blocks requested in this piece.
|
// there are no blocks requested in this piece.
|
||||||
// remove the fast/slow state from it
|
// remove the fast/slow state from it
|
||||||
|
@ -1309,8 +1314,8 @@ namespace libtorrent
|
||||||
assert(block.block_index < max_blocks_per_piece);
|
assert(block.block_index < max_blocks_per_piece);
|
||||||
assert(block.block_index >= 0);
|
assert(block.block_index >= 0);
|
||||||
|
|
||||||
if (i->requested_blocks[block.block_index] == false
|
if (i->info[block.block_index].requested == false
|
||||||
|| i->finished_blocks[block.block_index] == true)
|
|| i->info[block.block_index].requested == true)
|
||||||
return boost::optional<tcp::endpoint>();
|
return boost::optional<tcp::endpoint>();
|
||||||
|
|
||||||
return boost::optional<tcp::endpoint>(i->info[block.block_index].peer);
|
return boost::optional<tcp::endpoint>(i->info[block.block_index].peer);
|
||||||
|
@ -1336,26 +1341,27 @@ namespace libtorrent
|
||||||
, m_downloads.end(), has_index(block.piece_index));
|
, m_downloads.end(), has_index(block.piece_index));
|
||||||
assert(i != m_downloads.end());
|
assert(i != m_downloads.end());
|
||||||
|
|
||||||
if (i->finished_blocks[block.block_index])
|
if (i->info[block.block_index].finished)
|
||||||
{
|
{
|
||||||
assert(i->requested_blocks[block.block_index]);
|
assert(i->info[block.block_index].requested);
|
||||||
assert(std::find_if(m_downloads.begin(), m_downloads.end()
|
assert(std::find_if(m_downloads.begin(), m_downloads.end()
|
||||||
, has_index(block.piece_index)) == m_downloads.end());
|
, has_index(block.piece_index)) == m_downloads.end());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(block.block_index < blocks_in_piece(block.piece_index));
|
assert(block.block_index < blocks_in_piece(block.piece_index));
|
||||||
assert(i->requested_blocks[block.block_index]);
|
assert(i->info[block.block_index].requested);
|
||||||
|
|
||||||
// clear this block as being downloaded
|
// clear this block as being downloaded
|
||||||
i->requested_blocks[block.block_index] = false;
|
i->info[block.block_index].requested = false;
|
||||||
|
--i->requested;
|
||||||
|
|
||||||
// clear the downloader of this block
|
// clear the downloader of this block
|
||||||
i->info[block.block_index].peer = tcp::endpoint();
|
i->info[block.block_index].peer = tcp::endpoint();
|
||||||
|
|
||||||
// if there are no other blocks in this piece
|
// if there are no other blocks in this piece
|
||||||
// that's being downloaded, remove it from the list
|
// that's being downloaded, remove it from the list
|
||||||
if (i->requested_blocks.count() == 0)
|
if (i->requested == 0)
|
||||||
{
|
{
|
||||||
m_downloads.erase(i);
|
m_downloads.erase(i);
|
||||||
piece_pos& p = m_piece_map[block.piece_index];
|
piece_pos& p = m_piece_map[block.piece_index];
|
||||||
|
@ -1366,28 +1372,11 @@ namespace libtorrent
|
||||||
assert(std::find_if(m_downloads.begin(), m_downloads.end()
|
assert(std::find_if(m_downloads.begin(), m_downloads.end()
|
||||||
, has_index(block.piece_index)) == m_downloads.end());
|
, has_index(block.piece_index)) == m_downloads.end());
|
||||||
}
|
}
|
||||||
else
|
else if (i->requested == i->finished)
|
||||||
{
|
{
|
||||||
// TODO: maintain requested and finished counters so that
|
// there are no blocks requested in this piece.
|
||||||
// we don't have to count every time
|
// remove the fast/slow state from it
|
||||||
bool blocks_requested = false;
|
i->state = none;
|
||||||
int num_blocks = blocks_in_piece(i->index);
|
|
||||||
for (int k = 0; k < num_blocks; ++k)
|
|
||||||
{
|
|
||||||
if (i->finished_blocks[k]) continue;
|
|
||||||
if (i->requested_blocks[k])
|
|
||||||
{
|
|
||||||
blocks_requested = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!blocks_requested)
|
|
||||||
{
|
|
||||||
// there are no blocks requested in this piece.
|
|
||||||
// remove the fast/slow state from it
|
|
||||||
i->state = none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1397,7 +1386,7 @@ namespace libtorrent
|
||||||
for (std::vector<downloading_piece>::const_iterator i = m_downloads.begin();
|
for (std::vector<downloading_piece>::const_iterator i = m_downloads.begin();
|
||||||
i != m_downloads.end(); ++i)
|
i != m_downloads.end(); ++i)
|
||||||
{
|
{
|
||||||
counter += (int)i->finished_blocks.count();
|
counter += (int)i->finished;
|
||||||
}
|
}
|
||||||
return counter;
|
return counter;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1906,11 +1906,14 @@ namespace libtorrent { namespace detail
|
||||||
{
|
{
|
||||||
const int bit = j * 8 + k;
|
const int bit = j * 8 + k;
|
||||||
if (bits & (1 << k))
|
if (bits & (1 << k))
|
||||||
p.finished_blocks[bit] = true;
|
{
|
||||||
|
p.info[bit].finished = true;
|
||||||
|
++p.finished;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p.finished_blocks.count() == 0) continue;
|
if (p.finished == 0) continue;
|
||||||
|
|
||||||
std::vector<int>::iterator slot_iter
|
std::vector<int>::iterator slot_iter
|
||||||
= std::find(tmp_pieces.begin(), tmp_pieces.end(), p.index);
|
= std::find(tmp_pieces.begin(), tmp_pieces.end(), p.index);
|
||||||
|
@ -1929,7 +1932,7 @@ namespace libtorrent { namespace detail
|
||||||
= torrent_ptr->filesystem().piece_crc(
|
= torrent_ptr->filesystem().piece_crc(
|
||||||
slot_index
|
slot_index
|
||||||
, torrent_ptr->block_size()
|
, torrent_ptr->block_size()
|
||||||
, p.finished_blocks);
|
, p.info);
|
||||||
|
|
||||||
const entry& ad = (*i)["adler32"];
|
const entry& ad = (*i)["adler32"];
|
||||||
|
|
||||||
|
|
|
@ -959,7 +959,7 @@ namespace libtorrent
|
||||||
unsigned long piece_crc(
|
unsigned long piece_crc(
|
||||||
int slot_index
|
int slot_index
|
||||||
, int block_size
|
, int block_size
|
||||||
, const std::bitset<256>& bitmask);
|
, piece_picker::block_info const* bi);
|
||||||
|
|
||||||
int slot_for_piece(int piece_index) const;
|
int slot_for_piece(int piece_index) const;
|
||||||
|
|
||||||
|
@ -1208,15 +1208,15 @@ namespace libtorrent
|
||||||
unsigned long piece_manager::piece_crc(
|
unsigned long piece_manager::piece_crc(
|
||||||
int index
|
int index
|
||||||
, int block_size
|
, int block_size
|
||||||
, const std::bitset<256>& bitmask)
|
, piece_picker::block_info const* bi)
|
||||||
{
|
{
|
||||||
return m_pimpl->piece_crc(index, block_size, bitmask);
|
return m_pimpl->piece_crc(index, block_size, bi);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long piece_manager::impl::piece_crc(
|
unsigned long piece_manager::impl::piece_crc(
|
||||||
int slot_index
|
int slot_index
|
||||||
, int block_size
|
, int block_size
|
||||||
, const std::bitset<256>& bitmask)
|
, piece_picker::block_info const* bi)
|
||||||
{
|
{
|
||||||
assert(slot_index >= 0);
|
assert(slot_index >= 0);
|
||||||
assert(slot_index < m_info.num_pieces());
|
assert(slot_index < m_info.num_pieces());
|
||||||
|
@ -1230,7 +1230,7 @@ namespace libtorrent
|
||||||
|
|
||||||
for (int i = 0; i < num_blocks-1; ++i)
|
for (int i = 0; i < num_blocks-1; ++i)
|
||||||
{
|
{
|
||||||
if (!bitmask[i]) continue;
|
if (!bi[i].finished) continue;
|
||||||
m_storage->read(
|
m_storage->read(
|
||||||
&buf[0]
|
&buf[0]
|
||||||
, slot_index
|
, slot_index
|
||||||
|
@ -1238,7 +1238,7 @@ namespace libtorrent
|
||||||
, block_size);
|
, block_size);
|
||||||
crc.update(&buf[0], block_size);
|
crc.update(&buf[0], block_size);
|
||||||
}
|
}
|
||||||
if (bitmask[num_blocks - 1])
|
if (bi[num_blocks - 1].finished)
|
||||||
{
|
{
|
||||||
m_storage->read(
|
m_storage->read(
|
||||||
&buf[0]
|
&buf[0]
|
||||||
|
@ -1260,7 +1260,8 @@ namespace libtorrent
|
||||||
assert(offset >= 0);
|
assert(offset >= 0);
|
||||||
assert(size > 0);
|
assert(size > 0);
|
||||||
assert(piece_index >= 0 && piece_index < (int)m_piece_to_slot.size());
|
assert(piece_index >= 0 && piece_index < (int)m_piece_to_slot.size());
|
||||||
assert(m_piece_to_slot[piece_index] >= 0 && m_piece_to_slot[piece_index] < (int)m_slot_to_piece.size());
|
assert(m_piece_to_slot[piece_index] >= 0
|
||||||
|
&& m_piece_to_slot[piece_index] < (int)m_slot_to_piece.size());
|
||||||
int slot = m_piece_to_slot[piece_index];
|
int slot = m_piece_to_slot[piece_index];
|
||||||
assert(slot >= 0 && slot < (int)m_slot_to_piece.size());
|
assert(slot >= 0 && slot < (int)m_slot_to_piece.size());
|
||||||
return m_storage->read(buf, slot, offset, size);
|
return m_storage->read(buf, slot, offset, size);
|
||||||
|
|
|
@ -738,8 +738,7 @@ namespace libtorrent
|
||||||
int corr = 0;
|
int corr = 0;
|
||||||
int index = i->index;
|
int index = i->index;
|
||||||
assert(!m_have_pieces[index]);
|
assert(!m_have_pieces[index]);
|
||||||
assert(int(i->finished_blocks.count())
|
assert(i->finished < m_picker->blocks_in_piece(index));
|
||||||
< m_picker->blocks_in_piece(index));
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
for (std::vector<piece_picker::downloading_piece>::const_iterator j = boost::next(i);
|
for (std::vector<piece_picker::downloading_piece>::const_iterator j = boost::next(i);
|
||||||
|
@ -751,17 +750,17 @@ namespace libtorrent
|
||||||
|
|
||||||
for (int j = 0; j < blocks_per_piece; ++j)
|
for (int j = 0; j < blocks_per_piece; ++j)
|
||||||
{
|
{
|
||||||
assert(i->finished_blocks[j] == 0 || i->finished_blocks[j] == 1);
|
assert(i->info[j].finished == 0 || i->info[j].finished == 1);
|
||||||
assert(m_picker->is_finished(piece_block(index, j)) == i->finished_blocks[j]);
|
assert(m_picker->is_finished(piece_block(index, j)) == i->info[j].finished);
|
||||||
corr += i->finished_blocks[j] * m_block_size;
|
corr += i->info[j].finished * m_block_size;
|
||||||
assert(index != last_piece || j < m_picker->blocks_in_last_piece()
|
assert(index != last_piece || j < m_picker->blocks_in_last_piece()
|
||||||
|| i->finished_blocks[j] == 0);
|
|| i->info[j].finished == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// correction if this was the last piece
|
// correction if this was the last piece
|
||||||
// and if we have the last block
|
// and if we have the last block
|
||||||
if (i->index == last_piece
|
if (i->index == last_piece
|
||||||
&& i->finished_blocks[m_picker->blocks_in_last_piece()-1])
|
&& i->info[m_picker->blocks_in_last_piece()-1].finished)
|
||||||
{
|
{
|
||||||
corr -= m_block_size;
|
corr -= m_block_size;
|
||||||
corr += m_torrent_file.piece_size(last_piece) % m_block_size;
|
corr += m_torrent_file.piece_size(last_piece) % m_block_size;
|
||||||
|
@ -836,7 +835,7 @@ namespace libtorrent
|
||||||
std::cerr << " " << i->index << " ";
|
std::cerr << " " << i->index << " ";
|
||||||
for (int j = 0; j < blocks_per_piece; ++j)
|
for (int j = 0; j < blocks_per_piece; ++j)
|
||||||
{
|
{
|
||||||
std::cerr << i->finished_blocks[j];
|
std::cerr << i->info[j].finished;
|
||||||
}
|
}
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -542,7 +542,7 @@ namespace libtorrent
|
||||||
for (std::vector<piece_picker::downloading_piece>::const_iterator i
|
for (std::vector<piece_picker::downloading_piece>::const_iterator i
|
||||||
= q.begin(); i != q.end(); ++i)
|
= q.begin(); i != q.end(); ++i)
|
||||||
{
|
{
|
||||||
if (i->finished_blocks.count() == 0) continue;
|
if (i->finished == 0) continue;
|
||||||
|
|
||||||
entry piece_struct(entry::dictionary_t);
|
entry piece_struct(entry::dictionary_t);
|
||||||
|
|
||||||
|
@ -557,7 +557,7 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
unsigned char v = 0;
|
unsigned char v = 0;
|
||||||
for (int k = 0; k < 8; ++k)
|
for (int k = 0; k < 8; ++k)
|
||||||
v |= i->finished_blocks[j*8+k]?(1 << k):0;
|
v |= i->info[j*8+k].finished?(1 << k):0;
|
||||||
bitmask.insert(bitmask.end(), v);
|
bitmask.insert(bitmask.end(), v);
|
||||||
}
|
}
|
||||||
piece_struct["bitmask"] = bitmask;
|
piece_struct["bitmask"] = bitmask;
|
||||||
|
@ -567,7 +567,7 @@ namespace libtorrent
|
||||||
= t->filesystem().piece_crc(
|
= t->filesystem().piece_crc(
|
||||||
t->filesystem().slot_for_piece(i->index)
|
t->filesystem().slot_for_piece(i->index)
|
||||||
, t->block_size()
|
, t->block_size()
|
||||||
, i->finished_blocks);
|
, i->info);
|
||||||
|
|
||||||
piece_struct["adler32"] = adler;
|
piece_struct["adler32"] = adler;
|
||||||
|
|
||||||
|
@ -769,12 +769,12 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
partial_piece_info pi;
|
partial_piece_info pi;
|
||||||
pi.piece_state = (partial_piece_info::state_t)i->state;
|
pi.piece_state = (partial_piece_info::state_t)i->state;
|
||||||
pi.finished_blocks = i->finished_blocks;
|
|
||||||
pi.requested_blocks = i->requested_blocks;
|
|
||||||
for (int j = 0; j < partial_piece_info::max_blocks_per_piece; ++j)
|
for (int j = 0; j < partial_piece_info::max_blocks_per_piece; ++j)
|
||||||
{
|
{
|
||||||
pi.peer[j] = i->info[j].peer;
|
pi.peer[j] = i->info[j].peer;
|
||||||
pi.num_downloads[j] = i->info[j].num_downloads;
|
pi.num_downloads[j] = i->info[j].num_downloads;
|
||||||
|
pi.finished_blocks[j] = i->info[j].finished;
|
||||||
|
pi.requested_blocks[j] = i->info[j].requested;
|
||||||
}
|
}
|
||||||
pi.piece_index = i->index;
|
pi.piece_index = i->index;
|
||||||
pi.blocks_in_piece = p.blocks_in_piece(i->index);
|
pi.blocks_in_piece = p.blocks_in_piece(i->index);
|
||||||
|
|
Loading…
Reference in New Issue