From 569ce0a965efde7b895c6c51b94d0e1f00354b75 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Thu, 3 Apr 2014 02:03:14 +0000 Subject: [PATCH] honor pieces with priority 7 in sequential download mode --- ChangeLog | 1 + include/libtorrent/torrent_handle.hpp | 4 +++- src/piece_picker.cpp | 19 +++++++++++++++++++ test/test_piece_picker.cpp | 19 +++++++++++++++++++ 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ec4a0a901..b9ea29ffb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ + * honor pieces with priority 7 in sequential download mode * simplified building python bindings * make ignore_non_routers more forgiving in the case there are no UPnP devices at a known router. Should improve UPnP compatibility. diff --git a/include/libtorrent/torrent_handle.hpp b/include/libtorrent/torrent_handle.hpp index e594a8cdd..565df3942 100644 --- a/include/libtorrent/torrent_handle.hpp +++ b/include/libtorrent/torrent_handle.hpp @@ -1020,7 +1020,9 @@ namespace libtorrent // ``set_sequential_download()`` enables or disables *sequential // download*. When enabled, the piece picker will pick pieces in sequence - // instead of rarest first. + // instead of rarest first. In this mode, piece priorities are ignored, + // with the exception of priority 7, which are still preferred over the + // sequential piece order. // // Enabling sequential download will affect the piece distribution // negatively in the swarm. It should be used sparingly. diff --git a/src/piece_picker.cpp b/src/piece_picker.cpp index 97fae4e3c..6d0be6ad3 100644 --- a/src/piece_picker.cpp +++ b/src/piece_picker.cpp @@ -1585,11 +1585,28 @@ namespace libtorrent if (options & sequential) { + if (m_dirty) update_pieces(); + TORRENT_ASSERT(!m_dirty); + + for (std::vector::const_iterator i = m_pieces.begin(); + i != m_pieces.end() && piece_priority(*i) == 7; ++i) + { + if (!is_piece_free(*i, pieces)) continue; + num_blocks = add_blocks(*i, pieces + , interesting_blocks, backup_blocks + , backup_blocks2, num_blocks + , prefer_whole_pieces, peer, suggested_pieces + , speed, options); + if (num_blocks <= 0) return; + } + if (options & reverse) { for (int i = m_reverse_cursor - 1; i >= m_cursor; --i) { if (!is_piece_free(i, pieces)) continue; + // we've already added prio 7 pieces + if (piece_priority(i) == 7) continue; num_blocks = add_blocks(i, pieces , interesting_blocks, backup_blocks , backup_blocks2, num_blocks @@ -1603,6 +1620,8 @@ namespace libtorrent for (int i = m_cursor; i < m_reverse_cursor; ++i) { if (!is_piece_free(i, pieces)) continue; + // we've already added prio 7 pieces + if (piece_priority(i) == 7) continue; num_blocks = add_blocks(i, pieces , interesting_blocks, backup_blocks , backup_blocks2, num_blocks diff --git a/test/test_piece_picker.cpp b/test/test_piece_picker.cpp index 944945bcb..3bc7eaa2b 100644 --- a/test/test_piece_picker.cpp +++ b/test/test_piece_picker.cpp @@ -550,6 +550,25 @@ int test_main() for (int i = 0; i < int(picked.size()); ++i) TEST_CHECK(picked[i] == piece_block(6 - (i / blocks_per_piece), i % blocks_per_piece)); +// ======================================================== + + // test priority sequential download + print_title("test priority sequential download"); + p = setup_picker("7654321", " ", "1117071", ""); + picked = pick_pieces(p, "*******", 7 * blocks_per_piece, 0, 0, piece_picker::fast + , piece_picker::sequential, empty_vector); + + // the piece with priority 0 was not picked + TEST_CHECK(int(picked.size()) == 6 * blocks_per_piece); + + // the first two pieces picked should be 3 and 5 since those have priority 7 + for (int i = 0; i < 2 * blocks_per_piece; ++i) + TEST_CHECK(picked[i].piece_index == 3 || picked[i].piece_index == 5); + + int expected[] = {-1, -1, 0, 1, 2, 6}; + for (int i = 2 * blocks_per_piece; i < int(picked.size()); ++i) + TEST_CHECK(picked[i].piece_index == expected[i / blocks_per_piece]); + // ======================================================== // test cursors