piece picker update
This commit is contained in:
parent
5c14ec2eb1
commit
333839c9b4
|
@ -242,6 +242,7 @@ namespace libtorrent
|
|||
, piece_state_t s);
|
||||
void mark_as_writing(piece_block block, void* peer);
|
||||
void mark_as_finished(piece_block block, void* peer);
|
||||
void write_failed(piece_block block);
|
||||
int num_peers(piece_block block) const;
|
||||
|
||||
// returns information about the given piece
|
||||
|
|
|
@ -1476,7 +1476,7 @@ namespace libtorrent
|
|||
|
||||
if (ret == -1 || !t)
|
||||
{
|
||||
if (t->has_picker()) t->picker().abort_download(block_finished);
|
||||
if (t->has_picker()) t->picker().write_failed(block_finished);
|
||||
|
||||
if (!t)
|
||||
{
|
||||
|
|
|
@ -49,6 +49,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#endif
|
||||
|
||||
//#define TORRENT_PIECE_PICKER_INVARIANT_CHECK INVARIANT_CHECK
|
||||
//#define TORRENT_NO_EXPENSIVE_INVARIANT_CHECK
|
||||
#define TORRENT_PIECE_PICKER_INVARIANT_CHECK
|
||||
|
||||
//#define TORRENT_PICKER_LOG
|
||||
|
@ -276,7 +277,7 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(p == prio);
|
||||
}
|
||||
}
|
||||
#ifndef NDEBUG
|
||||
|
||||
void piece_picker::print_pieces() const
|
||||
{
|
||||
for (std::vector<int>::const_iterator i = m_priority_boundries.begin()
|
||||
|
@ -300,32 +301,9 @@ namespace libtorrent
|
|||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
void piece_picker::check_invariant(const torrent* t) const
|
||||
{
|
||||
if (m_sequential_download == -1 && !m_dirty)
|
||||
{
|
||||
TORRENT_ASSERT(!m_priority_boundries.empty());
|
||||
int prio = 0;
|
||||
int start = 0;
|
||||
for (std::vector<int>::const_iterator i = m_priority_boundries.begin()
|
||||
, end(m_priority_boundries.end()); i != end; ++i)
|
||||
{
|
||||
verify_priority(start, *i, prio);
|
||||
++prio;
|
||||
start = *i;
|
||||
}
|
||||
TORRENT_ASSERT(m_priority_boundries.back() == int(m_pieces.size()));
|
||||
}
|
||||
else if (m_sequential_download >= 0)
|
||||
{
|
||||
int index = 0;
|
||||
for (std::vector<piece_pos>::const_iterator i = m_piece_map.begin()
|
||||
, end(m_piece_map.end()); i != end && (i->have() || i->filtered());
|
||||
++i, ++index);
|
||||
TORRENT_ASSERT(m_sequential_download == index);
|
||||
}
|
||||
|
||||
TORRENT_ASSERT(sizeof(piece_pos) == 4);
|
||||
TORRENT_ASSERT(m_num_have >= 0);
|
||||
TORRENT_ASSERT(m_num_have_filtered >= 0);
|
||||
|
@ -358,17 +336,18 @@ namespace libtorrent
|
|||
if (i->info[k].state == block_info::state_finished)
|
||||
{
|
||||
++num_finished;
|
||||
continue;
|
||||
TORRENT_ASSERT(i->info[k].num_peers == 0);
|
||||
}
|
||||
if (i->info[k].state == block_info::state_requested)
|
||||
else if (i->info[k].state == block_info::state_requested)
|
||||
{
|
||||
++num_requested;
|
||||
blocks_requested = true;
|
||||
TORRENT_ASSERT(i->info[k].num_peers > 0);
|
||||
}
|
||||
if (i->info[k].state == block_info::state_writing)
|
||||
else if (i->info[k].state == block_info::state_writing)
|
||||
{
|
||||
++num_writing;
|
||||
TORRENT_ASSERT(i->info[k].num_peers == 0);
|
||||
}
|
||||
}
|
||||
TORRENT_ASSERT(blocks_requested == (i->state != none));
|
||||
|
@ -376,7 +355,32 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(num_writing == i->writing);
|
||||
TORRENT_ASSERT(num_finished == i->finished);
|
||||
}
|
||||
#ifdef TORRENT_NO_EXPENSIVE_INVARIANT_CHECK
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (m_sequential_download == -1 && !m_dirty)
|
||||
{
|
||||
TORRENT_ASSERT(!m_priority_boundries.empty());
|
||||
int prio = 0;
|
||||
int start = 0;
|
||||
for (std::vector<int>::const_iterator i = m_priority_boundries.begin()
|
||||
, end(m_priority_boundries.end()); i != end; ++i)
|
||||
{
|
||||
verify_priority(start, *i, prio);
|
||||
++prio;
|
||||
start = *i;
|
||||
}
|
||||
TORRENT_ASSERT(m_priority_boundries.back() == int(m_pieces.size()));
|
||||
}
|
||||
else if (m_sequential_download >= 0)
|
||||
{
|
||||
int index = 0;
|
||||
for (std::vector<piece_pos>::const_iterator i = m_piece_map.begin()
|
||||
, end(m_piece_map.end()); i != end && (i->have() || i->filtered());
|
||||
++i, ++index);
|
||||
TORRENT_ASSERT(m_sequential_download == index);
|
||||
}
|
||||
|
||||
int num_filtered = 0;
|
||||
int num_have_filtered = 0;
|
||||
|
@ -807,9 +811,9 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(m_piece_map[index].downloading == 1);
|
||||
|
||||
std::vector<downloading_piece>::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));
|
||||
|
||||
TORRENT_ASSERT(i != m_downloads.end());
|
||||
erase_download_piece(i);
|
||||
|
||||
|
@ -1814,7 +1818,8 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(info.state != block_info::state_writing);
|
||||
++i->writing;
|
||||
info.state = block_info::state_writing;
|
||||
if (info.num_peers > 0) --info.num_peers;
|
||||
TORRENT_ASSERT(info.num_peers > 0);
|
||||
info.num_peers = 0;
|
||||
|
||||
if (i->requested == 0)
|
||||
{
|
||||
|
@ -1824,6 +1829,31 @@ namespace libtorrent
|
|||
}
|
||||
sort_piece(i);
|
||||
}
|
||||
|
||||
void piece_picker::write_failed(piece_block block)
|
||||
{
|
||||
TORRENT_PIECE_PICKER_INVARIANT_CHECK;
|
||||
|
||||
std::vector<downloading_piece>::iterator i
|
||||
= std::find_if(m_downloads.begin(), m_downloads.end(), has_index(block.piece_index));
|
||||
TORRENT_ASSERT(i != m_downloads.end());
|
||||
block_info& info = i->info[block.block_index];
|
||||
TORRENT_ASSERT(info.state == block_info::state_writing);
|
||||
|
||||
--i->writing;
|
||||
if (info.num_peers > 0)
|
||||
{
|
||||
// there are other peers on this block
|
||||
// turn it back into requested
|
||||
++i->requested;
|
||||
info.state = block_info::state_requested;
|
||||
}
|
||||
else
|
||||
{
|
||||
info.state = block_info::state_none;
|
||||
}
|
||||
info.peer = 0;
|
||||
}
|
||||
|
||||
void piece_picker::mark_as_finished(piece_block block, void* peer)
|
||||
{
|
||||
|
@ -1851,6 +1881,7 @@ namespace libtorrent
|
|||
block_info& info = dp.info[block.block_index];
|
||||
info.peer = peer;
|
||||
TORRENT_ASSERT(info.state == block_info::state_none);
|
||||
TORRENT_ASSERT(info.num_peers == 0);
|
||||
if (info.state != block_info::state_finished)
|
||||
{
|
||||
++dp.finished;
|
||||
|
@ -1866,6 +1897,7 @@ namespace libtorrent
|
|||
= std::find_if(m_downloads.begin(), m_downloads.end(), has_index(block.piece_index));
|
||||
TORRENT_ASSERT(i != m_downloads.end());
|
||||
block_info& info = i->info[block.block_index];
|
||||
TORRENT_ASSERT(info.num_peers == 0);
|
||||
info.peer = peer;
|
||||
TORRENT_ASSERT(info.state == block_info::state_writing
|
||||
|| peer == 0);
|
||||
|
@ -1936,25 +1968,35 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(i != m_downloads.end());
|
||||
|
||||
block_info& info = i->info[block.block_index];
|
||||
--info.num_peers;
|
||||
if (info.num_peers > 0) return;
|
||||
|
||||
if (i->info[block.block_index].state == block_info::state_finished
|
||||
|| i->info[block.block_index].state == block_info::state_writing)
|
||||
TORRENT_ASSERT(info.state == block_info::state_requested);
|
||||
TORRENT_ASSERT(info.num_peers > 0);
|
||||
|
||||
--info.num_peers;
|
||||
TORRENT_ASSERT(block.block_index < blocks_in_piece(block.piece_index));
|
||||
|
||||
// if there are other peers
|
||||
if (info.num_peers > 0)
|
||||
{
|
||||
if (i->info[block.block_index].state == block_info::state_writing)
|
||||
{
|
||||
++i->requested;
|
||||
--i->writing;
|
||||
i->info[block.block_index].state = block_info::state_requested;
|
||||
// since we just cleared the writing state, we know that
|
||||
// the peer for this block was the one we canceled
|
||||
info.peer = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
TORRENT_ASSERT(block.block_index < blocks_in_piece(block.piece_index));
|
||||
TORRENT_ASSERT(i->info[block.block_index].state == block_info::state_requested);
|
||||
// clear the downloader of this block
|
||||
info.peer = 0;
|
||||
|
||||
// clear this block as being downloaded
|
||||
info.state = block_info::state_none;
|
||||
--i->requested;
|
||||
|
||||
// clear the downloader of this block
|
||||
info.peer = 0;
|
||||
|
||||
// if there are no other blocks in this piece
|
||||
// that's being downloaded, remove it from the list
|
||||
if (i->requested + i->finished + i->writing == 0)
|
||||
|
|
|
@ -1359,8 +1359,11 @@ namespace libtorrent
|
|||
std::map<int, partial_hash>::iterator i = m_piece_hasher.find(piece_index);
|
||||
if (i != m_piece_hasher.end())
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
TORRENT_ASSERT(i->second.offset > 0);
|
||||
TORRENT_ASSERT(offset >= i->second.offset);
|
||||
int hash_offset = i->second.offset;
|
||||
TORRENT_ASSERT(offset >= hash_offset);
|
||||
#endif
|
||||
if (offset == i->second.offset)
|
||||
{
|
||||
i->second.offset += size;
|
||||
|
|
|
@ -3069,6 +3069,16 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(piece_index >= 0);
|
||||
TORRENT_ASSERT(piece_index < m_torrent_file->num_pieces());
|
||||
TORRENT_ASSERT(piece_index < (int)m_have_pieces.size());
|
||||
#ifndef NDEBUG
|
||||
if (m_picker)
|
||||
{
|
||||
int blocks_in_piece = m_picker->blocks_in_piece(piece_index);
|
||||
for (int i = 0; i < blocks_in_piece; ++i)
|
||||
{
|
||||
TORRENT_ASSERT(m_picker->num_peers(piece_block(piece_index, i)) == 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
m_storage->async_hash(piece_index, bind(&torrent::on_piece_verified
|
||||
, shared_from_this(), _1, _2, f));
|
||||
|
|
Loading…
Reference in New Issue