simplified the piece picker by initializing it properly in its constructor. Removed natpmp reporting port map success when removing mappings. fix where incoming connections before the files were completely checked would cause an assert.
This commit is contained in:
parent
d08ca8c4e6
commit
4ac08f393a
|
@ -112,18 +112,14 @@ namespace libtorrent
|
|||
block_info info[max_blocks_per_piece];
|
||||
};
|
||||
|
||||
piece_picker(int blocks_per_piece
|
||||
, int total_num_blocks);
|
||||
|
||||
void set_sequenced_download_threshold(int sequenced_download_threshold);
|
||||
|
||||
// this is called before any other method is called
|
||||
// after the local files has been checked.
|
||||
// the vector tells which pieces we already have
|
||||
// and which we don't have.
|
||||
void files_checked(
|
||||
const std::vector<bool>& pieces
|
||||
, const std::vector<downloading_piece>& unfinished);
|
||||
piece_picker(int blocks_per_piece
|
||||
, int total_num_blocks
|
||||
, std::vector<bool> const& pieces
|
||||
, std::vector<downloading_piece> const& unfinished);
|
||||
|
||||
void set_sequenced_download_threshold(int sequenced_download_threshold);
|
||||
|
||||
// increases the peer count for the given piece
|
||||
// (is used when a HAVE or BITFIELD message is received)
|
||||
|
@ -304,8 +300,8 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
void add(int index);
|
||||
//TODO: should be renamed update()
|
||||
void move(int vec_index, int elem_index);
|
||||
// void remove(int vec_index, int elem_index);
|
||||
|
||||
int add_interesting_blocks(const std::vector<int>& piece_list
|
||||
, const std::vector<bool>& pieces
|
||||
|
@ -354,9 +350,6 @@ namespace libtorrent
|
|||
// the required popularity of a piece in order to download
|
||||
// it in sequence instead of random order.
|
||||
int m_sequenced_download_threshold;
|
||||
#ifndef NDEBUG
|
||||
bool m_files_checked_called;
|
||||
#endif
|
||||
};
|
||||
|
||||
inline int piece_picker::blocks_in_piece(int index) const
|
||||
|
|
|
@ -416,9 +416,17 @@ namespace libtorrent
|
|||
alert_manager& alerts() const;
|
||||
piece_picker& picker()
|
||||
{
|
||||
assert(m_files_checked_called);
|
||||
assert(!is_seed());
|
||||
assert(m_picker.get());
|
||||
return *m_picker;
|
||||
}
|
||||
bool has_picker() const
|
||||
{
|
||||
assert((m_files_checked_called && !is_seed())
|
||||
== bool(m_picker.get()));
|
||||
return m_picker.get();
|
||||
}
|
||||
policy& get_policy()
|
||||
{
|
||||
assert(m_policy);
|
||||
|
@ -611,6 +619,11 @@ namespace libtorrent
|
|||
// m_have_pieces.end(), 0)
|
||||
int m_num_pieces;
|
||||
|
||||
// in case the piece picker hasn't been constructed
|
||||
// when this settings is set, this variable will keep
|
||||
// its value until the piece picker is created
|
||||
int m_sequenced_download_threshold;
|
||||
|
||||
// is false by default and set to
|
||||
// true when the first tracker reponse
|
||||
// is received
|
||||
|
@ -673,6 +686,10 @@ namespace libtorrent
|
|||
// is started. i.e.
|
||||
// total_done - m_initial_done <= total_payload_download
|
||||
size_type m_initial_done;
|
||||
|
||||
// set to true once files_checked has been called
|
||||
// and the piece picker is constructed
|
||||
bool m_files_checked_called;
|
||||
#endif
|
||||
|
||||
#ifdef TORRENT_LOGGING
|
||||
|
|
|
@ -307,11 +307,15 @@ void natpmp::on_reply(asio::error_code const& e
|
|||
throw std::runtime_error(errmsg.str());
|
||||
}
|
||||
|
||||
int tcp_port = 0;
|
||||
int udp_port = 0;
|
||||
if (m.protocol == 1) udp_port = m.external_port;
|
||||
else tcp_port = public_port;
|
||||
m_callback(tcp_port, udp_port, "");
|
||||
// don't report when we remove mappings
|
||||
if (m.local_port != 0)
|
||||
{
|
||||
int tcp_port = 0;
|
||||
int udp_port = 0;
|
||||
if (m.protocol == 1) udp_port = m.external_port;
|
||||
else tcp_port = public_port;
|
||||
m_callback(tcp_port, udp_port, "");
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
|
|
|
@ -687,7 +687,7 @@ namespace libtorrent
|
|||
// just remember the bitmask
|
||||
// don't update the piecepicker
|
||||
// (since it doesn't exist yet)
|
||||
if (!t->valid_metadata())
|
||||
if (!t->ready_for_connections())
|
||||
{
|
||||
m_have_piece = bitfield;
|
||||
m_num_pieces = std::count(bitfield.begin(), bitfield.end(), true);
|
||||
|
|
|
@ -52,7 +52,9 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
namespace libtorrent
|
||||
{
|
||||
|
||||
piece_picker::piece_picker(int blocks_per_piece, int total_num_blocks)
|
||||
piece_picker::piece_picker(int blocks_per_piece, int total_num_blocks
|
||||
, std::vector<bool> const& pieces
|
||||
, std::vector<downloading_piece> const& unfinished)
|
||||
: m_piece_info(2)
|
||||
, m_piece_map((total_num_blocks + blocks_per_piece-1) / blocks_per_piece)
|
||||
, m_num_filtered(0)
|
||||
|
@ -61,9 +63,6 @@ namespace libtorrent
|
|||
{
|
||||
assert(blocks_per_piece > 0);
|
||||
assert(total_num_blocks >= 0);
|
||||
#ifndef NDEBUG
|
||||
m_files_checked_called = false;
|
||||
#endif
|
||||
|
||||
// the piece index is stored in 20 bits, which limits the allowed
|
||||
// number of pieces somewhat
|
||||
|
@ -82,16 +81,8 @@ namespace libtorrent
|
|||
// and make them invalid (as if though we already had every piece)
|
||||
std::fill(m_piece_map.begin(), m_piece_map.end()
|
||||
, piece_pos(0, piece_pos::we_have_index));
|
||||
}
|
||||
|
||||
// pieces is a bitmask with the pieces we have
|
||||
void piece_picker::files_checked(
|
||||
const std::vector<bool>& pieces
|
||||
, const std::vector<downloading_piece>& unfinished)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
m_files_checked_called = true;
|
||||
#endif
|
||||
|
||||
for (std::vector<bool>::const_iterator i = pieces.begin();
|
||||
i != pieces.end(); ++i)
|
||||
{
|
||||
|
@ -126,6 +117,7 @@ namespace libtorrent
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void piece_picker::set_sequenced_download_threshold(
|
||||
|
@ -376,7 +368,6 @@ namespace libtorrent
|
|||
{
|
||||
assert(priority > 0);
|
||||
assert(elem_index >= 0);
|
||||
assert(m_files_checked_called);
|
||||
|
||||
assert(int(m_piece_info.size()) > priority);
|
||||
assert(int(m_piece_info[priority].size()) > elem_index);
|
||||
|
@ -532,7 +523,6 @@ namespace libtorrent
|
|||
|
||||
assert(index >= 0);
|
||||
assert(index < (int)m_piece_map.size());
|
||||
assert(m_files_checked_called);
|
||||
|
||||
assert(m_piece_map[index].downloading == 1);
|
||||
|
||||
|
@ -554,7 +544,6 @@ namespace libtorrent
|
|||
// TORRENT_PIECE_PICKER_INVARIANT_CHECK;
|
||||
assert(i >= 0);
|
||||
assert(i < (int)m_piece_map.size());
|
||||
assert(m_files_checked_called);
|
||||
|
||||
piece_pos& p = m_piece_map[i];
|
||||
int index = p.index;
|
||||
|
@ -587,7 +576,6 @@ namespace libtorrent
|
|||
{
|
||||
// TORRENT_PIECE_PICKER_INVARIANT_CHECK;
|
||||
|
||||
assert(m_files_checked_called);
|
||||
assert(i >= 0);
|
||||
assert(i < (int)m_piece_map.size());
|
||||
|
||||
|
@ -754,7 +742,6 @@ namespace libtorrent
|
|||
TORRENT_PIECE_PICKER_INVARIANT_CHECK;
|
||||
assert(num_blocks > 0);
|
||||
assert(pieces.size() == m_piece_map.size());
|
||||
assert(m_files_checked_called);
|
||||
|
||||
// free refers to pieces that are free to download, no one else
|
||||
// is downloading them.
|
||||
|
|
|
@ -256,6 +256,7 @@ namespace libtorrent
|
|||
, m_time_scaler(0)
|
||||
, m_priority(.5)
|
||||
, m_num_pieces(0)
|
||||
, m_sequenced_download_threshold(0)
|
||||
, m_got_tracker_response(false)
|
||||
, m_ratio(0.f)
|
||||
, m_total_failed_bytes(0)
|
||||
|
@ -270,6 +271,7 @@ namespace libtorrent
|
|||
{
|
||||
#ifndef NDEBUG
|
||||
m_initial_done = 0;
|
||||
m_files_checked_called = false;
|
||||
#endif
|
||||
#ifdef TORRENT_LOGGING
|
||||
m_log = ses.create_log("torrent_"
|
||||
|
@ -346,6 +348,7 @@ namespace libtorrent
|
|||
, m_time_scaler(0)
|
||||
, m_priority(.5)
|
||||
, m_num_pieces(0)
|
||||
, m_sequenced_download_threshold(0)
|
||||
, m_got_tracker_response(false)
|
||||
, m_ratio(0.f)
|
||||
, m_total_failed_bytes(0)
|
||||
|
@ -360,6 +363,7 @@ namespace libtorrent
|
|||
{
|
||||
#ifndef NDEBUG
|
||||
m_initial_done = 0;
|
||||
m_files_checked_called = false;
|
||||
#endif
|
||||
|
||||
#ifdef TORRENT_LOGGING
|
||||
|
@ -459,9 +463,6 @@ namespace libtorrent
|
|||
m_storage.reset(new piece_manager(m_torrent_file, m_save_path
|
||||
, m_ses.m_files, m_storage_constructor));
|
||||
m_block_size = calculate_block_size(m_torrent_file, m_default_block_size);
|
||||
m_picker.reset(new piece_picker(
|
||||
static_cast<int>(m_torrent_file.piece_length() / m_block_size)
|
||||
, static_cast<int>((m_torrent_file.total_size()+m_block_size-1)/m_block_size)));
|
||||
|
||||
std::vector<std::string> const& url_seeds = m_torrent_file.url_seeds();
|
||||
std::copy(url_seeds.begin(), url_seeds.end(), std::inserter(m_web_seeds
|
||||
|
@ -701,10 +702,9 @@ namespace libtorrent
|
|||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
if (!valid_metadata()) return tuple<size_type, size_type>(0,0);
|
||||
|
||||
if (m_torrent_file.num_pieces() == 0)
|
||||
if (!has_picker() || m_torrent_file.num_pieces() == 0)
|
||||
return tuple<size_type, size_type>(0,0);
|
||||
|
||||
const int last_piece = m_torrent_file.num_pieces() - 1;
|
||||
|
||||
if (is_seed())
|
||||
|
@ -2132,11 +2132,17 @@ namespace libtorrent
|
|||
|
||||
if (!is_seed())
|
||||
{
|
||||
m_picker->files_checked(m_have_pieces, unfinished_pieces);
|
||||
m_picker.reset(new piece_picker(
|
||||
static_cast<int>(m_torrent_file.piece_length() / m_block_size)
|
||||
, static_cast<int>((m_torrent_file.total_size()+m_block_size-1)/m_block_size)
|
||||
, m_have_pieces, unfinished_pieces));
|
||||
m_files_checked_called = true;
|
||||
if (m_sequenced_download_threshold > 0)
|
||||
picker().set_sequenced_download_threshold(m_sequenced_download_threshold);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_picker.reset();
|
||||
assert(!m_picker);
|
||||
}
|
||||
if (!m_connections_initialized)
|
||||
{
|
||||
|
@ -2267,10 +2273,14 @@ namespace libtorrent
|
|||
|
||||
void torrent::set_sequenced_download_threshold(int threshold)
|
||||
{
|
||||
// TODO: if there is not valid metadata, save this setting and
|
||||
// set it once the piece picker is created.
|
||||
if (valid_metadata() && !is_seed())
|
||||
if (has_picker())
|
||||
{
|
||||
picker().set_sequenced_download_threshold(threshold);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_sequenced_download_threshold = threshold;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue