forked from premiere/premiere-libtorrent
use span<> to return the block_info for a piece (#1777)
use span<> to return the block_info for a piece to improve range checks and loops
This commit is contained in:
parent
9f9376fc26
commit
8cf6e9e37c
|
@ -50,7 +50,7 @@ namespace libtorrent { namespace aux {
|
|||
// pull in constructors from base class
|
||||
using base::base;
|
||||
|
||||
auto operator[](IndexType idx) -> decltype(this->base::operator[](underlying_index()))
|
||||
auto operator[](IndexType idx) const -> decltype(this->base::operator[](underlying_index()))
|
||||
{
|
||||
TORRENT_ASSERT(idx >= IndexType(0));
|
||||
return this->base::operator[](std::size_t(static_cast<underlying_index>(idx)));
|
||||
|
@ -64,13 +64,13 @@ namespace libtorrent { namespace aux {
|
|||
|
||||
template <typename U = underlying_index, typename Cond
|
||||
= typename std::enable_if<std::is_signed<U>::value>::type>
|
||||
typed_span<T> first(underlying_index n)
|
||||
typed_span<T> first(underlying_index n) const
|
||||
{
|
||||
TORRENT_ASSERT(n >= 0);
|
||||
return this->base::first(std::size_t(n));
|
||||
}
|
||||
|
||||
typed_span<T> first(std::size_t n)
|
||||
typed_span<T> first(std::size_t n) const
|
||||
{
|
||||
TORRENT_ASSERT(n <= std::size_t((std::numeric_limits<underlying_index>::max)()));
|
||||
return this->base::first(n);
|
||||
|
@ -78,13 +78,13 @@ namespace libtorrent { namespace aux {
|
|||
|
||||
template <typename U = underlying_index, typename Cond
|
||||
= typename std::enable_if<std::is_signed<U>::value>::type>
|
||||
typed_span<T> last(underlying_index n)
|
||||
typed_span<T> last(underlying_index n) const
|
||||
{
|
||||
TORRENT_ASSERT(n >= 0);
|
||||
return this->base::last(std::size_t(n));
|
||||
}
|
||||
|
||||
typed_span<T> last(std::size_t n)
|
||||
typed_span<T> last(std::size_t n) const
|
||||
{
|
||||
TORRENT_ASSERT(n <= std::size_t((std::numeric_limits<underlying_index>::max)()));
|
||||
return this->base::last(n);
|
||||
|
@ -92,7 +92,7 @@ namespace libtorrent { namespace aux {
|
|||
|
||||
template <typename U = underlying_index, typename Cond
|
||||
= typename std::enable_if<std::is_signed<U>::value>::type>
|
||||
typed_span<T> subspan(underlying_index offset)
|
||||
typed_span<T> subspan(underlying_index offset) const
|
||||
{
|
||||
TORRENT_ASSERT(offset >= 0);
|
||||
return this->base::subspan(std::size_t(offset));
|
||||
|
@ -100,20 +100,20 @@ namespace libtorrent { namespace aux {
|
|||
|
||||
template <typename U = underlying_index, typename Cond
|
||||
= typename std::enable_if<std::is_signed<U>::value>::type>
|
||||
typed_span<T> subspan(underlying_index offset, underlying_index count)
|
||||
typed_span<T> subspan(underlying_index offset, underlying_index count) const
|
||||
{
|
||||
TORRENT_ASSERT(offset >= 0);
|
||||
TORRENT_ASSERT(count >= 0);
|
||||
return this->base::subspan(std::size_t(offset), std::size_t(count));
|
||||
}
|
||||
|
||||
typed_span<T> subspan(std::size_t offset)
|
||||
typed_span<T> subspan(std::size_t offset) const
|
||||
{
|
||||
TORRENT_ASSERT(offset <= std::size_t((std::numeric_limits<underlying_index>::max)()));
|
||||
return this->base::subspan(offset);
|
||||
}
|
||||
|
||||
typed_span<T> subspan(std::size_t offset, std::size_t count)
|
||||
typed_span<T> subspan(std::size_t offset, std::size_t count) const
|
||||
{
|
||||
TORRENT_ASSERT(offset <= std::size_t((std::numeric_limits<underlying_index>::max)()));
|
||||
TORRENT_ASSERT(count <= std::size_t((std::numeric_limits<underlying_index>::max)()));
|
||||
|
|
|
@ -56,6 +56,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/time.hpp"
|
||||
#include "libtorrent/piece_block.hpp"
|
||||
#include "libtorrent/aux_/vector.hpp"
|
||||
#include "libtorrent/aux_/typed_span.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
@ -429,11 +430,12 @@ namespace libtorrent
|
|||
|
||||
// return the array of block_info objects for a given downloading_piece.
|
||||
// this array has m_blocks_per_piece elements in it
|
||||
block_info* blocks_for_piece(downloading_piece const& dp);
|
||||
block_info const* blocks_for_piece(downloading_piece const& dp) const;
|
||||
aux::typed_span<block_info const> blocks_for_piece(downloading_piece const& dp) const;
|
||||
|
||||
private:
|
||||
|
||||
aux::typed_span<block_info> mutable_blocks_for_piece(downloading_piece const& dp);
|
||||
|
||||
std::tuple<bool, bool, int, int> requested_from(
|
||||
piece_picker::downloading_piece const& p
|
||||
, int num_blocks_in_piece, torrent_peer* peer) const;
|
||||
|
|
|
@ -105,7 +105,7 @@ namespace libtorrent
|
|||
return { data() + offset, count };
|
||||
}
|
||||
|
||||
T& operator[](std::size_t const idx)
|
||||
T& operator[](std::size_t const idx) const
|
||||
{
|
||||
TORRENT_ASSERT(idx < m_len);
|
||||
return m_ptr[idx];
|
||||
|
|
|
@ -3053,14 +3053,13 @@ namespace libtorrent
|
|||
#if TORRENT_USE_ASSERTS
|
||||
if (t->has_picker())
|
||||
{
|
||||
const std::vector<piece_picker::downloading_piece>& q
|
||||
std::vector<piece_picker::downloading_piece> const& q
|
||||
= picker.get_download_queue();
|
||||
|
||||
for (std::vector<piece_picker::downloading_piece>::const_iterator
|
||||
i = q.begin(), end(q.end()); i != end; ++i)
|
||||
for (piece_picker::downloading_piece const& dp : q)
|
||||
{
|
||||
if (i->index != block_finished.piece_index) continue;
|
||||
piece_picker::block_info* info = picker.blocks_for_piece(*i);
|
||||
if (dp.index != block_finished.piece_index) continue;
|
||||
auto const info = picker.blocks_for_piece(dp);
|
||||
TORRENT_ASSERT(info[block_finished.block_index].state
|
||||
== piece_picker::block_info::state_finished);
|
||||
}
|
||||
|
|
|
@ -207,15 +207,14 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(int(ret.info_idx) * m_blocks_per_piece
|
||||
+ m_blocks_per_piece <= int(m_block_info.size()));
|
||||
|
||||
block_info* info = blocks_for_piece(ret);
|
||||
for (int i = 0; i < m_blocks_per_piece; ++i)
|
||||
for (auto& info : mutable_blocks_for_piece(ret))
|
||||
{
|
||||
info[i].num_peers = 0;
|
||||
info[i].state = block_info::state_none;
|
||||
info[i].peer = nullptr;
|
||||
info.num_peers = 0;
|
||||
info.state = block_info::state_none;
|
||||
info.peer = nullptr;
|
||||
#if TORRENT_USE_ASSERTS
|
||||
info[i].piece_index = piece;
|
||||
info[i].peers.clear();
|
||||
info.piece_index = piece;
|
||||
info.peers.clear();
|
||||
#endif
|
||||
}
|
||||
downloading_iter = m_downloads[download_state].insert(downloading_iter, ret);
|
||||
|
@ -283,18 +282,18 @@ namespace libtorrent
|
|||
*zero_prio = int(m_downloads[piece_pos::piece_zero_prio].size());
|
||||
}
|
||||
|
||||
piece_picker::block_info* piece_picker::blocks_for_piece(
|
||||
aux::typed_span<piece_picker::block_info> piece_picker::mutable_blocks_for_piece(
|
||||
downloading_piece const& dp)
|
||||
{
|
||||
int idx = int(dp.info_idx) * m_blocks_per_piece;
|
||||
TORRENT_ASSERT(idx + m_blocks_per_piece <= int(m_block_info.size()));
|
||||
return &m_block_info[idx];
|
||||
return { &m_block_info[idx], static_cast<std::size_t>(blocks_in_piece(dp.index)) };
|
||||
}
|
||||
|
||||
piece_picker::block_info const* piece_picker::blocks_for_piece(
|
||||
aux::typed_span<piece_picker::block_info const> piece_picker::blocks_for_piece(
|
||||
downloading_piece const& dp) const
|
||||
{
|
||||
return const_cast<piece_picker*>(this)->blocks_for_piece(dp);
|
||||
return const_cast<piece_picker*>(this)->mutable_blocks_for_piece(dp);
|
||||
}
|
||||
|
||||
#if TORRENT_USE_INVARIANT_CHECKS
|
||||
|
@ -313,12 +312,11 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(dp.index < next.index);
|
||||
TORRENT_ASSERT(int(dp.info_idx) * m_blocks_per_piece
|
||||
+ m_blocks_per_piece <= int(m_block_info.size()));
|
||||
block_info const* info = blocks_for_piece(dp);
|
||||
for (int j = 0; j < m_blocks_per_piece; ++j)
|
||||
for (auto const& bl : blocks_for_piece(dp))
|
||||
{
|
||||
if (info[j].peer)
|
||||
if (bl.peer)
|
||||
{
|
||||
torrent_peer* p = info[j].peer;
|
||||
torrent_peer* p = bl.peer;
|
||||
TORRENT_ASSERT(p->in_use);
|
||||
TORRENT_ASSERT(p->connection == nullptr
|
||||
|| static_cast<peer_connection*>(p->connection)->m_in_use);
|
||||
|
@ -440,11 +438,10 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(int(dp.info_idx) * m_blocks_per_piece
|
||||
+ m_blocks_per_piece <= int(m_block_info.size()));
|
||||
#if TORRENT_USE_ASSERTS
|
||||
block_info const* info = blocks_for_piece(dp);
|
||||
for (int j = 0; j < m_blocks_per_piece; ++j)
|
||||
for (auto const& bl : blocks_for_piece(dp))
|
||||
{
|
||||
if (!info[j].peer) continue;
|
||||
torrent_peer* p = info[j].peer;
|
||||
if (!bl.peer) continue;
|
||||
torrent_peer* p = bl.peer;
|
||||
TORRENT_ASSERT(p->in_use);
|
||||
TORRENT_ASSERT(p->connection == nullptr
|
||||
|| static_cast<peer_connection*>(p->connection)->m_in_use);
|
||||
|
@ -467,32 +464,31 @@ namespace libtorrent
|
|||
int num_finished = 0;
|
||||
int num_writing = 0;
|
||||
int num_open = 0;
|
||||
block_info const* info = blocks_for_piece(dp);
|
||||
for (int k = 0; k < num_blocks; ++k)
|
||||
for (auto const& bl : blocks_for_piece(dp))
|
||||
{
|
||||
TORRENT_ASSERT(info[k].piece_index == dp.index);
|
||||
TORRENT_ASSERT(info[k].peer == nullptr
|
||||
|| info[k].peer->in_use);
|
||||
TORRENT_ASSERT(bl.piece_index == dp.index);
|
||||
TORRENT_ASSERT(bl.peer == nullptr
|
||||
|| bl.peer->in_use);
|
||||
|
||||
if (info[k].state == block_info::state_finished)
|
||||
if (bl.state == block_info::state_finished)
|
||||
{
|
||||
++num_finished;
|
||||
TORRENT_ASSERT(info[k].num_peers == 0);
|
||||
TORRENT_ASSERT(bl.num_peers == 0);
|
||||
}
|
||||
else if (info[k].state == block_info::state_requested)
|
||||
else if (bl.state == block_info::state_requested)
|
||||
{
|
||||
++num_requested;
|
||||
TORRENT_ASSERT(info[k].num_peers > 0);
|
||||
TORRENT_ASSERT(bl.num_peers > 0);
|
||||
}
|
||||
else if (info[k].state == block_info::state_writing)
|
||||
else if (bl.state == block_info::state_writing)
|
||||
{
|
||||
++num_writing;
|
||||
TORRENT_ASSERT(info[k].num_peers == 0);
|
||||
TORRENT_ASSERT(bl.num_peers == 0);
|
||||
}
|
||||
else if (info[k].state == block_info::state_none)
|
||||
else if (bl.state == block_info::state_none)
|
||||
{
|
||||
++num_open;
|
||||
TORRENT_ASSERT(info[k].num_peers == 0);
|
||||
TORRENT_ASSERT(bl.num_peers == 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2317,17 +2313,16 @@ get_out:
|
|||
TORRENT_ASSERT(piece_priority(dp->index) > 0);
|
||||
// fill in with blocks requested from other peers
|
||||
// as backups
|
||||
int const num_blocks_in_piece = blocks_in_piece(dp->index);
|
||||
TORRENT_ASSERT(dp->requested > 0);
|
||||
block_info const* binfo = blocks_for_piece(*dp);
|
||||
for (int j = 0; j < num_blocks_in_piece; ++j)
|
||||
int idx = -1;
|
||||
for (auto const& info : blocks_for_piece(*dp))
|
||||
{
|
||||
block_info const& info = binfo[j];
|
||||
++idx;
|
||||
TORRENT_ASSERT(info.peer == nullptr || info.peer->in_use);
|
||||
TORRENT_ASSERT(info.piece_index == dp->index);
|
||||
if (info.state != block_info::state_requested || info.peer == peer)
|
||||
continue;
|
||||
temp.push_back(piece_block(dp->index, j));
|
||||
temp.push_back(piece_block(dp->index, idx));
|
||||
}
|
||||
// are we done?
|
||||
if (!temp.empty())
|
||||
|
@ -2358,15 +2353,14 @@ get_out:
|
|||
&& piece_priority(i.index) != priority_levels - 1)
|
||||
continue;
|
||||
|
||||
const int num_blocks_in_piece = blocks_in_piece(i.index);
|
||||
block_info const* binfo = blocks_for_piece(i);
|
||||
for (int j = 0; j < num_blocks_in_piece; ++j)
|
||||
int idx = -1;
|
||||
for (auto const& info : blocks_for_piece(i))
|
||||
{
|
||||
block_info const& info = binfo[j];
|
||||
++idx;
|
||||
TORRENT_ASSERT(info.piece_index == i.index);
|
||||
if (info.state != block_info::state_none) continue;
|
||||
auto k = std::find(interesting_blocks.begin(), interesting_blocks.end()
|
||||
, piece_block(i.index, j));
|
||||
, piece_block(i.index, idx));
|
||||
if (k != interesting_blocks.end()) continue;
|
||||
|
||||
std::fprintf(stderr, "interesting blocks:\n");
|
||||
|
@ -2379,7 +2373,7 @@ get_out:
|
|||
|
||||
for (auto const& l : m_downloads[piece_pos::piece_downloading])
|
||||
{
|
||||
block_info const* binfo2 = blocks_for_piece(l);
|
||||
auto const binfo2 = blocks_for_piece(l);
|
||||
std::fprintf(stderr, "%d : ", static_cast<int>(l.index));
|
||||
const int cnt = blocks_in_piece(l.index);
|
||||
for (int m = 0; m < cnt; ++m)
|
||||
|
@ -2485,10 +2479,10 @@ get_out:
|
|||
int contiguous_blocks = 0;
|
||||
int max_contiguous = 0;
|
||||
int first_block = 0;
|
||||
block_info const* binfo = blocks_for_piece(p);
|
||||
for (int j = 0; j < num_blocks_in_piece; ++j)
|
||||
int idx = -1;
|
||||
for (auto const& info : blocks_for_piece(p))
|
||||
{
|
||||
piece_picker::block_info const& info = binfo[j];
|
||||
++idx;
|
||||
TORRENT_ASSERT(info.peer == nullptr || info.peer->in_use);
|
||||
TORRENT_ASSERT(info.piece_index == p.index);
|
||||
if (info.state == piece_picker::block_info::state_none)
|
||||
|
@ -2499,7 +2493,7 @@ get_out:
|
|||
if (contiguous_blocks > max_contiguous)
|
||||
{
|
||||
max_contiguous = contiguous_blocks;
|
||||
first_block = j - contiguous_blocks;
|
||||
first_block = idx - contiguous_blocks;
|
||||
}
|
||||
contiguous_blocks = 0;
|
||||
if (info.peer != peer)
|
||||
|
@ -2631,7 +2625,7 @@ get_out:
|
|||
// pieces that only they have downloaded/requested from
|
||||
if ((options & on_parole) && !exclusive) return num_blocks;
|
||||
|
||||
block_info const* binfo = blocks_for_piece(dp);
|
||||
auto const binfo = blocks_for_piece(dp);
|
||||
|
||||
// we prefer whole blocks, but there are other peers
|
||||
// downloading from this piece and there aren't enough contiguous blocks
|
||||
|
@ -2648,7 +2642,7 @@ get_out:
|
|||
for (int j = 0; j < num_blocks_in_piece; ++j)
|
||||
{
|
||||
// ignore completed blocks and already requested blocks
|
||||
int block_idx = (j + first_block) % num_blocks_in_piece;
|
||||
int const block_idx = (j + first_block) % num_blocks_in_piece;
|
||||
block_info const& info = binfo[block_idx];
|
||||
TORRENT_ASSERT(info.piece_index == dp.index);
|
||||
if (info.state != block_info::state_none) continue;
|
||||
|
@ -2660,7 +2654,7 @@ get_out:
|
|||
for (int j = 0; j < num_blocks_in_piece; ++j)
|
||||
{
|
||||
// ignore completed blocks and already requested blocks
|
||||
int block_idx = (j + first_block) % num_blocks_in_piece;
|
||||
int const block_idx = (j + first_block) % num_blocks_in_piece;
|
||||
block_info const& info = binfo[block_idx];
|
||||
TORRENT_ASSERT(info.piece_index == dp.index);
|
||||
if (info.state != block_info::state_none) continue;
|
||||
|
@ -2749,17 +2743,16 @@ get_out:
|
|||
std::vector<downloading_piece>::const_iterator i = find_dl_piece(state, index);
|
||||
TORRENT_ASSERT(i != m_downloads[state].end());
|
||||
TORRENT_ASSERT(int(i->finished) <= m_blocks_per_piece);
|
||||
int max_blocks = blocks_in_piece(index);
|
||||
int const max_blocks = blocks_in_piece(index);
|
||||
if (int(i->finished) + int(i->writing) < max_blocks) return false;
|
||||
TORRENT_ASSERT(int(i->finished) + int(i->writing) == max_blocks);
|
||||
|
||||
#if TORRENT_USE_INVARIANT_CHECKS
|
||||
block_info const* info = blocks_for_piece(*i);
|
||||
for (int k = 0; k < max_blocks; ++k)
|
||||
for (auto const& info : blocks_for_piece(*i))
|
||||
{
|
||||
TORRENT_ASSERT(info[k].piece_index == index);
|
||||
TORRENT_ASSERT(info[k].state == block_info::state_finished
|
||||
|| info[k].state == block_info::state_writing);
|
||||
TORRENT_ASSERT(info.piece_index == index);
|
||||
TORRENT_ASSERT(info.state == block_info::state_finished
|
||||
|| info.state == block_info::state_writing);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2905,7 +2898,7 @@ get_out:
|
|||
|
||||
TORRENT_ASSERT(i != m_downloads[state].end());
|
||||
|
||||
block_info const* info = blocks_for_piece(*i);
|
||||
auto const info = blocks_for_piece(*i);
|
||||
TORRENT_ASSERT(info[block.block_index].piece_index == block.piece_index);
|
||||
return info[block.block_index].state == block_info::state_requested;
|
||||
}
|
||||
|
@ -2923,7 +2916,7 @@ get_out:
|
|||
, block.piece_index);
|
||||
TORRENT_ASSERT(i != m_downloads[state].end());
|
||||
|
||||
block_info const* info = blocks_for_piece(*i);
|
||||
auto const info = blocks_for_piece(*i);
|
||||
TORRENT_ASSERT(info[block.block_index].piece_index == block.piece_index);
|
||||
return info[block.block_index].state == block_info::state_finished
|
||||
|| info[block.block_index].state == block_info::state_writing;
|
||||
|
@ -2942,7 +2935,7 @@ get_out:
|
|||
, block.piece_index);
|
||||
TORRENT_ASSERT(i != m_downloads[p.download_queue()].end());
|
||||
|
||||
block_info const* info = blocks_for_piece(*i);
|
||||
auto const info = blocks_for_piece(*i);
|
||||
TORRENT_ASSERT(info[block.block_index].piece_index == block.piece_index);
|
||||
return info[block.block_index].state == block_info::state_finished;
|
||||
}
|
||||
|
@ -2981,7 +2974,7 @@ get_out:
|
|||
if (prio >= 0 && !m_dirty) update(prio, p.index);
|
||||
|
||||
auto const dp = add_download_piece(block.piece_index);
|
||||
block_info* binfo = blocks_for_piece(*dp);
|
||||
auto const binfo = mutable_blocks_for_piece(*dp);
|
||||
block_info& info = binfo[block.block_index];
|
||||
TORRENT_ASSERT(info.piece_index == block.piece_index);
|
||||
info.state = block_info::state_requested;
|
||||
|
@ -3005,7 +2998,7 @@ get_out:
|
|||
std::vector<downloading_piece>::iterator i = find_dl_piece(p.download_queue()
|
||||
, block.piece_index);
|
||||
TORRENT_ASSERT(i != m_downloads[p.download_queue()].end());
|
||||
block_info* binfo = blocks_for_piece(*i);
|
||||
auto const binfo = mutable_blocks_for_piece(*i);
|
||||
block_info& info = binfo[block.block_index];
|
||||
TORRENT_ASSERT(info.piece_index == block.piece_index);
|
||||
if (info.state == block_info::state_writing
|
||||
|
@ -3068,7 +3061,7 @@ get_out:
|
|||
, block.piece_index);
|
||||
TORRENT_ASSERT(i != m_downloads[p.download_queue()].end());
|
||||
|
||||
block_info const* binfo = blocks_for_piece(*i);
|
||||
auto const binfo = blocks_for_piece(*i);
|
||||
block_info const& info = binfo[block.block_index];
|
||||
TORRENT_ASSERT(&info >= &m_block_info[0]);
|
||||
TORRENT_ASSERT(&info < &m_block_info[0] + m_block_info.size());
|
||||
|
@ -3126,7 +3119,7 @@ get_out:
|
|||
if (prio >= 0 && !m_dirty) update(prio, p.index);
|
||||
|
||||
auto const dp = add_download_piece(block.piece_index);
|
||||
block_info* binfo = blocks_for_piece(*dp);
|
||||
auto const binfo = mutable_blocks_for_piece(*dp);
|
||||
block_info& info = binfo[block.block_index];
|
||||
TORRENT_ASSERT(&info >= &m_block_info[0]);
|
||||
TORRENT_ASSERT(&info < &m_block_info[0] + m_block_info.size());
|
||||
|
@ -3146,7 +3139,7 @@ get_out:
|
|||
std::vector<downloading_piece>::iterator i = find_dl_piece(p.download_queue()
|
||||
, block.piece_index);
|
||||
TORRENT_ASSERT(i != m_downloads[p.download_queue()].end());
|
||||
block_info* binfo = blocks_for_piece(*i);
|
||||
auto const binfo = mutable_blocks_for_piece(*i);
|
||||
block_info& info = binfo[block.block_index];
|
||||
|
||||
TORRENT_ASSERT(&info >= &m_block_info[0]);
|
||||
|
@ -3233,7 +3226,7 @@ get_out:
|
|||
std::vector<downloading_piece>::iterator i = find_dl_piece(state, block.piece_index);
|
||||
if (i == m_downloads[state].end()) return;
|
||||
|
||||
block_info* binfo = blocks_for_piece(*i);
|
||||
auto const binfo = mutable_blocks_for_piece(*i);
|
||||
block_info& info = binfo[block.block_index];
|
||||
TORRENT_ASSERT(&info >= &m_block_info[0]);
|
||||
TORRENT_ASSERT(&info < &m_block_info[0] + m_block_info.size());
|
||||
|
@ -3300,7 +3293,7 @@ get_out:
|
|||
, block.piece_index);
|
||||
|
||||
TORRENT_ASSERT(i != m_downloads[p.download_queue()].end());
|
||||
block_info* binfo = blocks_for_piece(*i);
|
||||
auto const binfo = mutable_blocks_for_piece(*i);
|
||||
block_info& info = binfo[block.block_index];
|
||||
|
||||
if (info.state == block_info::state_finished) return;
|
||||
|
@ -3370,7 +3363,7 @@ get_out:
|
|||
if (prio >= 0 && !m_dirty) update(prio, p.index);
|
||||
|
||||
auto const dp = add_download_piece(block.piece_index);
|
||||
block_info* binfo = blocks_for_piece(*dp);
|
||||
auto const binfo = mutable_blocks_for_piece(*dp);
|
||||
block_info& info = binfo[block.block_index];
|
||||
TORRENT_ASSERT(&info >= &m_block_info[0]);
|
||||
TORRENT_ASSERT(&info < &m_block_info[0] + m_block_info.size());
|
||||
|
@ -3392,7 +3385,7 @@ get_out:
|
|||
std::vector<downloading_piece>::iterator i = find_dl_piece(p.download_queue()
|
||||
, block.piece_index);
|
||||
TORRENT_ASSERT(i != m_downloads[p.download_queue()].end());
|
||||
block_info* binfo = blocks_for_piece(*i);
|
||||
auto const binfo = mutable_blocks_for_piece(*i);
|
||||
block_info& info = binfo[block.block_index];
|
||||
TORRENT_ASSERT(info.piece_index == block.piece_index);
|
||||
|
||||
|
@ -3451,7 +3444,7 @@ get_out:
|
|||
std::vector<downloading_piece>::const_iterator i
|
||||
= find_dl_piece(state, index);
|
||||
TORRENT_ASSERT(i != m_downloads[state].end());
|
||||
block_info const* binfo = blocks_for_piece(*i);
|
||||
auto const binfo = blocks_for_piece(*i);
|
||||
for (int j = 0; j != num_blocks; ++j)
|
||||
{
|
||||
TORRENT_ASSERT(binfo[j].peer == nullptr
|
||||
|
@ -3469,7 +3462,7 @@ get_out:
|
|||
, block.piece_index);
|
||||
|
||||
TORRENT_ASSERT(block.block_index != piece_block::invalid.block_index);
|
||||
block_info const* binfo = blocks_for_piece(*i);
|
||||
auto const binfo = blocks_for_piece(*i);
|
||||
TORRENT_ASSERT(binfo[block.block_index].piece_index == block.piece_index);
|
||||
if (binfo[block.block_index].state == block_info::state_none)
|
||||
return nullptr;
|
||||
|
@ -3502,7 +3495,7 @@ get_out:
|
|||
, block.piece_index);
|
||||
TORRENT_ASSERT(i != m_downloads[state].end());
|
||||
|
||||
block_info* binfo = blocks_for_piece(*i);
|
||||
auto const binfo = mutable_blocks_for_piece(*i);
|
||||
block_info& info = binfo[block.block_index];
|
||||
TORRENT_ASSERT(info.peer == nullptr || info.peer->in_use);
|
||||
TORRENT_ASSERT(info.piece_index == block.piece_index);
|
||||
|
|
104
src/torrent.cpp
104
src/torrent.cpp
|
@ -1816,7 +1816,7 @@ namespace libtorrent
|
|||
|
||||
for (auto const& p : dq)
|
||||
{
|
||||
int num_blocks = m_picker->blocks_in_piece(p.index);
|
||||
int const num_blocks = m_picker->blocks_in_piece(p.index);
|
||||
if (p.finished < num_blocks) continue;
|
||||
have_pieces.push_back(p.index);
|
||||
}
|
||||
|
@ -1855,30 +1855,25 @@ namespace libtorrent
|
|||
{
|
||||
std::vector<std::shared_ptr<torrent>> ts = m_ses.find_collection(c);
|
||||
|
||||
for (std::vector<std::shared_ptr<torrent>>::iterator k = ts.begin()
|
||||
, end2(ts.end()); k != end2; ++k)
|
||||
for (auto const& t : ts)
|
||||
{
|
||||
// Only attempt to reuse files from torrents that are seeding.
|
||||
// TODO: this could be optimized by looking up which files are
|
||||
// complete and just look at those
|
||||
if (!(*k)->is_seed()) continue;
|
||||
if (!t->is_seed()) continue;
|
||||
|
||||
res.match((*k)->get_torrent_copy(), (*k)->save_path());
|
||||
res.match(t->get_torrent_copy(), t->save_path());
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<resolve_links::link_t> const& l = res.get_links();
|
||||
if (!l.empty())
|
||||
{
|
||||
for (std::vector<resolve_links::link_t>::const_iterator i = l.begin()
|
||||
, end(l.end()); i != end; ++i)
|
||||
for (auto const& i : l)
|
||||
{
|
||||
if (!i->ti) continue;
|
||||
|
||||
torrent_info const& ti = *i->ti;
|
||||
std::string const& save_path = i->save_path;
|
||||
links.push_back(combine_path(save_path
|
||||
, ti.files().file_path(i->file_idx)));
|
||||
if (!i.ti) continue;
|
||||
links.push_back(combine_path(i.save_path
|
||||
, i.ti->files().file_path(i.file_idx)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3549,8 +3544,6 @@ namespace libtorrent
|
|||
std::vector<piece_picker::downloading_piece> dl_queue
|
||||
= m_picker->get_download_queue();
|
||||
|
||||
const int blocks_per_piece = (piece_size + block_size() - 1) / block_size();
|
||||
|
||||
// look at all unfinished pieces and add the completed
|
||||
// blocks to our 'done' counter
|
||||
for (auto i = dl_queue.begin(); i != dl_queue.end(); ++i)
|
||||
|
@ -3566,20 +3559,21 @@ namespace libtorrent
|
|||
, [index](piece_picker::downloading_piece const& p) { return p.index == index; }) == 0);
|
||||
#endif
|
||||
|
||||
piece_picker::block_info* info = m_picker->blocks_for_piece(*i);
|
||||
for (int j = 0; j < blocks_per_piece; ++j)
|
||||
int idx = -1;
|
||||
for (auto const& info : m_picker->blocks_for_piece(*i))
|
||||
{
|
||||
++idx;
|
||||
#ifdef TORRENT_EXPENSIVE_INVARIANT_CHECKS
|
||||
TORRENT_ASSERT(m_picker->is_finished(piece_block(index, j))
|
||||
== (info[j].state == piece_picker::block_info::state_finished));
|
||||
TORRENT_ASSERT(m_picker->is_finished(piece_block(index, idx))
|
||||
== (info.state == piece_picker::block_info::state_finished));
|
||||
#endif
|
||||
if (info[j].state == piece_picker::block_info::state_finished)
|
||||
if (info.state == piece_picker::block_info::state_finished)
|
||||
{
|
||||
corr += block_bytes_wanted(piece_block(index, j));
|
||||
corr += block_bytes_wanted(piece_block(index, idx));
|
||||
}
|
||||
TORRENT_ASSERT(corr >= 0);
|
||||
TORRENT_ASSERT(index != last_piece || j < m_picker->blocks_in_last_piece()
|
||||
|| info[j].state != piece_picker::block_info::state_finished);
|
||||
TORRENT_ASSERT(index != last_piece || idx < m_picker->blocks_in_last_piece()
|
||||
|| info.state != piece_picker::block_info::state_finished);
|
||||
}
|
||||
|
||||
st.total_done += corr;
|
||||
|
@ -3642,10 +3636,9 @@ namespace libtorrent
|
|||
for (auto const& dp : dl_queue)
|
||||
{
|
||||
std::fprintf(stderr, " %d ", static_cast<int>(dp.index));
|
||||
piece_picker::block_info* info = m_picker->blocks_for_piece(dp);
|
||||
for (int j = 0; j < blocks_per_piece; ++j)
|
||||
for (auto const& info : m_picker->blocks_for_piece(dp))
|
||||
{
|
||||
char const* state = info[j].state
|
||||
char const* state = info.state
|
||||
== piece_picker::block_info::state_finished ? "1" : "0";
|
||||
fputs(state, stderr);
|
||||
}
|
||||
|
@ -6029,7 +6022,7 @@ namespace libtorrent
|
|||
int const num_bitmask_bytes
|
||||
= std::max(num_blocks_per_piece / 8, 1);
|
||||
|
||||
piece_picker::block_info const* info = m_picker->blocks_for_piece(dp);
|
||||
auto const info = m_picker->blocks_for_piece(dp);
|
||||
for (int j = 0; j < num_bitmask_bytes; ++j)
|
||||
{
|
||||
char v = 0;
|
||||
|
@ -6355,24 +6348,25 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(counter * blocks_per_piece + pi.blocks_in_piece <= int(blk.size()));
|
||||
pi.blocks = &blk[std::size_t(counter * blocks_per_piece)];
|
||||
int const piece_size = torrent_file().piece_size(i->index);
|
||||
piece_picker::block_info const* info = m_picker->blocks_for_piece(*i);
|
||||
for (int j = 0; j < pi.blocks_in_piece; ++j)
|
||||
int idx = -1;
|
||||
for (auto const& info : m_picker->blocks_for_piece(*i))
|
||||
{
|
||||
block_info& bi = pi.blocks[j];
|
||||
bi.state = info[j].state;
|
||||
bi.block_size = j < pi.blocks_in_piece - 1
|
||||
++idx;
|
||||
block_info& bi = pi.blocks[idx];
|
||||
bi.state = info.state;
|
||||
bi.block_size = idx < pi.blocks_in_piece - 1
|
||||
? aux::numeric_cast<std::uint32_t>(block_size())
|
||||
: aux::numeric_cast<std::uint32_t>(piece_size - (j * block_size()));
|
||||
: aux::numeric_cast<std::uint32_t>(piece_size - (idx * block_size()));
|
||||
bool complete = bi.state == block_info::writing
|
||||
|| bi.state == block_info::finished;
|
||||
if (info[j].peer == nullptr)
|
||||
if (info.peer == nullptr)
|
||||
{
|
||||
bi.set_peer(tcp::endpoint());
|
||||
bi.bytes_progress = complete ? bi.block_size : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
torrent_peer* tp = info[j].peer;
|
||||
torrent_peer* tp = info.peer;
|
||||
TORRENT_ASSERT(tp->in_use);
|
||||
if (tp->connection)
|
||||
{
|
||||
|
@ -6382,7 +6376,7 @@ namespace libtorrent
|
|||
if (bi.state == block_info::requested)
|
||||
{
|
||||
auto pbp = peer->downloading_piece_progress();
|
||||
if (pbp.piece_index == i->index && pbp.block_index == j)
|
||||
if (pbp.piece_index == i->index && pbp.block_index == idx)
|
||||
{
|
||||
bi.bytes_progress = aux::numeric_cast<std::uint32_t>(pbp.bytes_downloaded);
|
||||
TORRENT_ASSERT(bi.bytes_progress <= bi.block_size);
|
||||
|
@ -6404,7 +6398,7 @@ namespace libtorrent
|
|||
}
|
||||
}
|
||||
|
||||
pi.blocks[j].num_peers = info[j].num_peers;
|
||||
pi.blocks[idx].num_peers = info.num_peers;
|
||||
}
|
||||
pi.piece_index = i->index;
|
||||
queue->push_back(pi);
|
||||
|
@ -9405,29 +9399,29 @@ namespace libtorrent
|
|||
TORRENT_ALLOCA(busy_blocks, busy_block_t, blocks_in_piece);
|
||||
int busy_count = 0;
|
||||
|
||||
piece_picker::block_info const* info = picker->blocks_for_piece(pi);
|
||||
|
||||
// pick busy blocks from the piece
|
||||
for (int k = 0; k < blocks_in_piece; ++k)
|
||||
int idx = -1;
|
||||
for (auto const& info : picker->blocks_for_piece(pi))
|
||||
{
|
||||
++idx;
|
||||
// only consider blocks that have been requested
|
||||
// and we're still waiting for them
|
||||
if (info[k].state != piece_picker::block_info::state_requested)
|
||||
if (info.state != piece_picker::block_info::state_requested)
|
||||
continue;
|
||||
|
||||
piece_block b(piece, k);
|
||||
piece_block b(piece, idx);
|
||||
|
||||
// only allow a single additional request per block, in order
|
||||
// to spread it out evenly across all stalled blocks
|
||||
if (int(info[k].num_peers) > timed_out)
|
||||
if (int(info.num_peers) > timed_out)
|
||||
continue;
|
||||
|
||||
busy_blocks[busy_count].peers = info[k].num_peers;
|
||||
busy_blocks[busy_count].index = k;
|
||||
busy_blocks[busy_count].peers = info.num_peers;
|
||||
busy_blocks[busy_count].index = idx;
|
||||
++busy_count;
|
||||
|
||||
#if TORRENT_DEBUG_STREAMING > 1
|
||||
std::printf(" [%d (%d)]", b.block_index, info[k].num_peers);
|
||||
std::printf(" [%d (%d)]", b.block_index, info.num_peers);
|
||||
#endif
|
||||
}
|
||||
#if TORRENT_DEBUG_STREAMING > 1
|
||||
|
@ -10249,14 +10243,14 @@ namespace libtorrent
|
|||
std::int64_t offset = std::int64_t(static_cast<int>(dp.index))
|
||||
* m_torrent_file->piece_length();
|
||||
file_index_t file = fs.file_index_at_offset(offset);
|
||||
int num_blocks = m_picker->blocks_in_piece(dp.index);
|
||||
piece_picker::block_info const* info = m_picker->blocks_for_piece(dp);
|
||||
for (int k = 0; k < num_blocks; ++k)
|
||||
int idx = -1;
|
||||
for (auto const& info : m_picker->blocks_for_piece(dp))
|
||||
{
|
||||
++idx;
|
||||
TORRENT_ASSERT(file < fs.end_file());
|
||||
TORRENT_ASSERT(offset == std::int64_t(static_cast<int>(dp.index))
|
||||
* m_torrent_file->piece_length()
|
||||
+ k * block_size());
|
||||
+ idx * block_size());
|
||||
TORRENT_ASSERT(offset < m_torrent_file->total_size());
|
||||
while (offset >= fs.file_offset(file) + fs.file_size(file))
|
||||
{
|
||||
|
@ -10266,21 +10260,21 @@ namespace libtorrent
|
|||
|
||||
std::int64_t block = block_size();
|
||||
|
||||
if (info[k].state == piece_picker::block_info::state_none)
|
||||
if (info.state == piece_picker::block_info::state_none)
|
||||
{
|
||||
offset += block;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (info[k].state == piece_picker::block_info::state_requested)
|
||||
if (info.state == piece_picker::block_info::state_requested)
|
||||
{
|
||||
block = 0;
|
||||
torrent_peer* p = info[k].peer;
|
||||
torrent_peer* p = info.peer;
|
||||
if (p != nullptr && p->connection)
|
||||
{
|
||||
peer_connection* peer = static_cast<peer_connection*>(p->connection);
|
||||
auto pbp = peer->downloading_piece_progress();
|
||||
if (pbp.piece_index == dp.index && pbp.block_index == k)
|
||||
if (pbp.piece_index == dp.index && pbp.block_index == idx)
|
||||
block = pbp.bytes_downloaded;
|
||||
TORRENT_ASSERT(block <= block_size());
|
||||
}
|
||||
|
@ -10318,7 +10312,7 @@ namespace libtorrent
|
|||
offset += left_over;
|
||||
TORRENT_ASSERT(offset == std::int64_t(static_cast<int>(dp.index))
|
||||
* m_torrent_file->piece_length()
|
||||
+ (k + 1) * block_size());
|
||||
+ (idx + 1) * block_size());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue