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:
Arvid Norberg 2007-03-16 23:28:26 +00:00
parent d08ca8c4e6
commit 4ac08f393a
6 changed files with 60 additions and 49 deletions

View File

@ -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

View File

@ -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

View File

@ -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)
{

View File

@ -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);

View File

@ -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.

View File

@ -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;
}
}