From 20e38bc42bfc3156c5af40e5c773c476d3ea2304 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Wed, 21 Mar 2007 02:09:50 +0000 Subject: [PATCH] peer interest flag is now updated when priority is changed. fixes in piece_picker --- include/libtorrent/peer_connection.hpp | 2 + include/libtorrent/torrent.hpp | 2 + src/peer_connection.cpp | 29 ++++++++++++- src/piece_picker.cpp | 19 ++++++-- src/policy.cpp | 16 +------ src/torrent.cpp | 60 +++++++++++++------------- 6 files changed, 77 insertions(+), 51 deletions(-) diff --git a/include/libtorrent/peer_connection.hpp b/include/libtorrent/peer_connection.hpp index 0763ed56c..585b108e0 100755 --- a/include/libtorrent/peer_connection.hpp +++ b/include/libtorrent/peer_connection.hpp @@ -190,6 +190,8 @@ namespace libtorrent bool is_peer_interested() const { return m_peer_interested; } bool has_peer_choked() const { return m_peer_choked; } + void update_interest(); + // returns the torrent this connection is a part of // may be zero if the connection is an incoming connection // and it hasn't received enough information to determine diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index 963f4adb2..ca5195a8b 100755 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -500,6 +500,8 @@ namespace libtorrent , boost::intrusive_ptr p) const; bool request_bandwidth_from_session(int channel) const; + void update_peer_interest(); + torrent_info m_torrent_file; // is set to true when the torrent has diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index 78e561f65..b7e848f9e 100755 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -205,6 +205,33 @@ namespace libtorrent std::fill(m_peer_id.begin(), m_peer_id.end(), 0); } + void peer_connection::update_interest() + { + INVARIANT_CHECK; + + boost::shared_ptr t = m_torrent.lock(); + assert(t); + + bool interested = false; + const std::vector& we_have = t->pieces(); + for (int j = 0; j != (int)we_have.size(); ++j) + { + if (!we_have[j] + && t->piece_priority(j) > 0 + && m_have_piece[j]) + { + interested = true; + break; + } + } + if (!interested) + send_not_interested(); + else + t->get_policy().peer_is_interesting(*this); + + assert(is_interesting() == interested); + } + #ifndef TORRENT_DISABLE_EXTENSIONS void peer_connection::add_extension(boost::shared_ptr ext) { @@ -237,7 +264,7 @@ namespace libtorrent t->peer_has(i); // if the peer has a piece and we don't, the peer is interesting if (!t->have_piece(i) - && !t->picker().piece_priority(i) == 0) + && t->picker().piece_priority(i) != 0) interesting = true; } } diff --git a/src/piece_picker.cpp b/src/piece_picker.cpp index 9d62a7420..9c7636f91 100755 --- a/src/piece_picker.cpp +++ b/src/piece_picker.cpp @@ -264,12 +264,11 @@ namespace libtorrent } } } - else if (!i->filtered()) + else { if (t != 0) assert(!t->have_piece(index)); - assert(i->priority(m_sequenced_download_threshold) < int(m_piece_info.size())); int prio = i->priority(m_sequenced_download_threshold); if (prio > 0) { @@ -277,6 +276,15 @@ namespace libtorrent assert (i->index < vec.size()); assert(vec[i->index] == index); } + + for (int k = 0; k < int(m_piece_info.size()); ++k) + { + for (int j = 0; j < int(m_piece_info[k].size()); ++j) + { + assert(int(m_piece_info[k][j]) != index + || (prio > 0 && prio == k && int(i->index) == j)); + } + } } std::vector::const_iterator down @@ -386,6 +394,8 @@ namespace libtorrent int index = m_piece_info[priority][elem_index]; // update the piece_map piece_pos& p = m_piece_map[index]; + assert(int(p.index) == index || p.have()); + int new_priority = p.priority(m_sequenced_download_threshold); if (new_priority == priority) return; @@ -665,10 +675,12 @@ namespace libtorrent assert(index < (int)m_piece_map.size()); piece_pos& p = m_piece_map[index]; - + // if the priority isn't changed, don't do anything if (new_piece_priority == int(p.piece_priority)) return; + int prev_priority = p.priority(m_sequenced_download_threshold); + if (new_piece_priority == piece_pos::filter_priority && p.piece_priority != piece_pos::filter_priority) { @@ -697,7 +709,6 @@ namespace libtorrent assert(m_num_filtered >= 0); assert(m_num_have_filtered >= 0); - int prev_priority = p.priority(m_sequenced_download_threshold); p.piece_priority = new_piece_priority; int new_priority = p.priority(m_sequenced_download_threshold); diff --git a/src/policy.cpp b/src/policy.cpp index 067cdcb8f..577061bfd 100755 --- a/src/policy.cpp +++ b/src/policy.cpp @@ -1090,21 +1090,7 @@ namespace libtorrent if (!i->connection->is_interesting()) continue; if (!i->connection->has_piece(index)) continue; - bool interested = false; - const std::vector& peer_has = i->connection->get_bitfield(); - const std::vector& we_have = m_torrent->pieces(); - assert(we_have.size() == peer_has.size()); - for (int j = 0; j != (int)we_have.size(); ++j) - { - if (!we_have[j] && peer_has[j]) - { - interested = true; - break; - } - } - if (!interested) - i->connection->send_not_interested(); - assert(i->connection->is_interesting() == interested); + i->connection->update_interest(); } } } diff --git a/src/torrent.cpp b/src/torrent.cpp index f0783c0a0..fa0de9832 100755 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -1036,9 +1036,8 @@ namespace libtorrent assert(index >= 0); assert(index < m_torrent_file.num_pieces()); - // TODO: update peer's interesting-bit - m_picker->set_piece_priority(index, priority); + update_peer_interest(); } int torrent::piece_priority(int index) const @@ -1053,8 +1052,6 @@ namespace libtorrent assert(index >= 0); assert(index < m_torrent_file.num_pieces()); - // TODO: update peer's interesting-bit - return m_picker->piece_priority(index); } @@ -1068,8 +1065,6 @@ namespace libtorrent assert(m_picker.get()); - // TODO: update peer's interesting-bit - int index = 0; for (std::vector::const_iterator i = pieces.begin() , end(pieces.end()); i != end; ++i, ++index) @@ -1078,6 +1073,7 @@ namespace libtorrent assert(*i <= 7); m_picker->set_piece_priority(index, *i); } + update_peer_interest(); } void torrent::piece_priorities(std::vector& pieces) const @@ -1118,35 +1114,37 @@ namespace libtorrent size_type position = 0; - if (m_torrent_file.num_pieces()) + if (m_torrent_file.num_pieces() == 0) return; + + int piece_length = m_torrent_file.piece_length(); + // initialize the piece priorities to 0, then only allow + // setting higher priorities + std::vector pieces(m_torrent_file.num_pieces(), 0); + for (int i = 0; i < int(files.size()); ++i) { - int piece_length = m_torrent_file.piece_length(); - // initialize the piece priorities to 0, then only allow - // setting higher priorities - std::vector pieces(m_torrent_file.num_pieces(), 0); - for (int i = 0; i < int(files.size()); ++i) - { - size_type start = position; - position += m_torrent_file.file_at(i).size; - // mark all pieces of the file with this file's priority - // but only if the priority is higher than the pieces - // already set (to avoid problems with overlapping pieces) - int start_piece = int(start / piece_length); - int last_piece = int(position / piece_length); - // if one piece spans several files, we might - // come here several times with the same start_piece, end_piece - std::for_each(pieces.begin() + start_piece - , pieces.begin() + last_piece + 1 - , bind(&set_if_greater, _1, files[i])); - } - prioritize_pieces(pieces); + size_type start = position; + position += m_torrent_file.file_at(i).size; + // mark all pieces of the file with this file's priority + // but only if the priority is higher than the pieces + // already set (to avoid problems with overlapping pieces) + int start_piece = int(start / piece_length); + int last_piece = int(position / piece_length); + // if one piece spans several files, we might + // come here several times with the same start_piece, end_piece + std::for_each(pieces.begin() + start_piece + , pieces.begin() + last_piece + 1 + , bind(&set_if_greater, _1, files[i])); } + prioritize_pieces(pieces); + update_peer_interest(); } - - - - + // updates the interested flag in peers + void torrent::update_peer_interest() + { + for (peer_iterator i = begin(); i != end(); ++i) + i->second->update_interest(); + }