diff --git a/ChangeLog b/ChangeLog index 6f61678be..990a52c35 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ + * fix suggest_read_cache setting * back-off tracker hostname looksups resulting in NXDOMAIN * lower SOCKS5 UDP keepalive timeout * fix external IP voting for multi-homed DHT nodes diff --git a/include/libtorrent/aux_/suggest_piece.hpp b/include/libtorrent/aux_/suggest_piece.hpp index cfb4c9a00..87949e1ad 100644 --- a/include/libtorrent/aux_/suggest_piece.hpp +++ b/include/libtorrent/aux_/suggest_piece.hpp @@ -56,7 +56,7 @@ struct suggest_piece int ret = 0; // the highest priority pieces are at the end of m_priority_pieces. - // is we add any piece to the result (p), the farther back the better. + // if we add any piece to the result (p), the farther back the better. // the prioritization in p is the same, which means we have to first push // back and then reverse the items we put there. for (int i = int(m_priority_pieces.size()) - 1; i >= 0; --i) diff --git a/include/libtorrent/piece_picker.hpp b/include/libtorrent/piece_picker.hpp index 7a0f13006..dec5c9f21 100644 --- a/include/libtorrent/piece_picker.hpp +++ b/include/libtorrent/piece_picker.hpp @@ -228,6 +228,10 @@ namespace libtorrent { void inc_refcount_all(const torrent_peer* peer); void dec_refcount_all(const torrent_peer* peer); + // we have every piece. This is used when creating a piece picker for a + // seed + void we_have_all(); + // This indicates that we just received this piece // it means that the refcounter will indicate that // we are not interested in this piece anymore @@ -592,7 +596,7 @@ namespace libtorrent { // (availability) std::uint32_t peer_count : 26; - // one of the enums from state_t. This indicates whether this piece + // one of the download_queue_t values. This indicates whether this piece // is currently being downloaded or not, and what state it's in if // it is. Specifically, as an optimization, pieces that have all blocks // requested from them are separated out into separate lists to make diff --git a/src/piece_picker.cpp b/src/piece_picker.cpp index db88b7033..00bfa38b0 100644 --- a/src/piece_picker.cpp +++ b/src/piece_picker.cpp @@ -1702,6 +1702,37 @@ namespace libtorrent { TORRENT_ASSERT(p.priority(this) == -1); } + void piece_picker::we_have_all() + { + INVARIANT_CHECK; +#ifdef TORRENT_PICKER_LOG + std::cerr << "[" << this << "] " << "piece_picker::we_have_all()\n"; +#endif + + m_priority_boundaries.clear(); + m_priority_boundaries.resize(1, prio_index_t(0)); + m_block_info.clear(); + m_free_block_infos.clear(); + m_pieces.clear(); + + m_dirty = false; + m_num_have_filtered += m_num_filtered; + m_num_filtered = 0; + m_have_filtered_pad_blocks += m_filtered_pad_blocks; + m_filtered_pad_blocks = 0; + m_cursor = m_piece_map.end_index(); + m_reverse_cursor = piece_index_t{0}; + m_num_passed = num_pieces(); + m_num_have = num_pieces(); + + for (auto& queue : m_downloads) queue.clear(); + for (auto& p : m_piece_map) + { + p.set_have(); + p.state(piece_pos::piece_open); + } + } + bool piece_picker::set_piece_priority(piece_index_t const index , download_priority_t const new_piece_priority) { diff --git a/src/torrent.cpp b/src/torrent.cpp index b0ef00d79..9ece52b62 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -1297,6 +1297,8 @@ bool is_downloading_state(int const st) , blocks_in_last_piece , m_torrent_file->num_pieces())); + if (m_have_all) pp->we_have_all(); + // initialize the file progress too if (m_file_progress.empty()) m_file_progress.init(*pp, m_torrent_file->files()); diff --git a/test/test_piece_picker.cpp b/test/test_piece_picker.cpp index 5c9a75c37..6b90d54b6 100644 --- a/test/test_piece_picker.cpp +++ b/test/test_piece_picker.cpp @@ -635,6 +635,25 @@ TORRENT_TEST(resize) TEST_EQUAL(p->have().num_pieces, 0); } +TORRENT_TEST(we_have_all) +{ + auto p = setup_picker("0123111", " ** * ", "1234567", " 1234"); + + p->we_have_all(); + + TEST_EQUAL(p->want().num_pieces, 7); + TEST_EQUAL(p->want().pad_blocks, 0); + TEST_EQUAL(p->want().last_piece, true); + + TEST_EQUAL(p->have_want().num_pieces, 7); + TEST_EQUAL(p->have_want().pad_blocks, 0); + TEST_EQUAL(p->have_want().last_piece, true); + + TEST_EQUAL(p->have().num_pieces, 7); + TEST_EQUAL(p->have().pad_blocks, 0); + TEST_EQUAL(p->have().last_piece, true); +} + TORRENT_TEST(dont_pick_requested_blocks) { // make sure requested blocks aren't picked diff --git a/test/test_transfer.cpp b/test/test_transfer.cpp index 5ad4795b4..2c93379c8 100644 --- a/test/test_transfer.cpp +++ b/test/test_transfer.cpp @@ -521,3 +521,12 @@ TORRENT_TEST(allocate) cleanup(); } +TORRENT_TEST(suggest) +{ + using namespace lt; + settings_pack p; + p.set_int(settings_pack::suggest_mode, settings_pack::suggest_read_cache); + test_transfer(0, p); + + cleanup(); +}