fixed piece picker bug related to sequential download, added unit test to expose it

This commit is contained in:
Arvid Norberg 2008-06-11 08:30:06 +00:00
parent 6e69480176
commit a4dfd63ca3
2 changed files with 43 additions and 11 deletions

View File

@ -37,9 +37,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include <algorithm> #include <algorithm>
#include <numeric> #include <numeric>
// non-standard header, is_sorted()
//#include <algo.h>
#include "libtorrent/piece_picker.hpp" #include "libtorrent/piece_picker.hpp"
#include "libtorrent/aux_/session_impl.hpp" #include "libtorrent/aux_/session_impl.hpp"
#include "libtorrent/bitfield.hpp" #include "libtorrent/bitfield.hpp"
@ -255,6 +252,7 @@ namespace libtorrent
TORRENT_ASSERT(m_num_have >= 0); TORRENT_ASSERT(m_num_have >= 0);
TORRENT_ASSERT(m_num_have_filtered >= 0); TORRENT_ASSERT(m_num_have_filtered >= 0);
TORRENT_ASSERT(m_num_filtered >= 0); TORRENT_ASSERT(m_num_filtered >= 0);
TORRENT_ASSERT(m_seeds >= 0);
if (!m_downloads.empty()) if (!m_downloads.empty())
{ {
@ -446,6 +444,7 @@ namespace libtorrent
float piece_picker::distributed_copies() const float piece_picker::distributed_copies() const
{ {
TORRENT_ASSERT(m_seeds >= 0);
const float num_pieces = static_cast<float>(m_piece_map.size()); const float num_pieces = static_cast<float>(m_piece_map.size());
int min_availability = piece_pos::max_peer_count; int min_availability = piece_pos::max_peer_count;
@ -768,8 +767,12 @@ namespace libtorrent
int new_priority = p.priority(this); int new_priority = p.priority(this);
if (new_priority == prev_priority) return; if (new_priority == prev_priority) return;
if (m_sequential_download >= 0) return;
if (m_dirty) return; if (m_dirty) return;
if (m_sequential_download >= 0)
{
m_dirty = true;
return;
}
if (prev_priority == -1) if (prev_priority == -1)
{ {
add(index); add(index);
@ -784,7 +787,6 @@ namespace libtorrent
{ {
TORRENT_PIECE_PICKER_INVARIANT_CHECK; TORRENT_PIECE_PICKER_INVARIANT_CHECK;
++m_seeds; ++m_seeds;
if (m_sequential_download >= 0) return;
if (m_seeds == 1) if (m_seeds == 1)
{ {
// when m_seeds is increased from 0 to 1 // when m_seeds is increased from 0 to 1
@ -798,12 +800,6 @@ namespace libtorrent
{ {
TORRENT_PIECE_PICKER_INVARIANT_CHECK; TORRENT_PIECE_PICKER_INVARIANT_CHECK;
if (m_sequential_download >= 0)
{
--m_seeds;
return;
}
if (m_seeds > 0) if (m_seeds > 0)
{ {
--m_seeds; --m_seeds;
@ -816,6 +812,7 @@ namespace libtorrent
} }
return; return;
} }
TORRENT_ASSERT(m_seeds == 0);
for (std::vector<piece_pos>::iterator i = m_piece_map.begin() for (std::vector<piece_pos>::iterator i = m_piece_map.begin()
, end(m_piece_map.end()); i != end; ++i) , end(m_piece_map.end()); i != end; ++i)
@ -835,6 +832,7 @@ namespace libtorrent
if (m_sequential_download >= 0) if (m_sequential_download >= 0)
{ {
++p.peer_count; ++p.peer_count;
m_dirty = true;
return; return;
} }
@ -856,7 +854,9 @@ namespace libtorrent
piece_pos& p = m_piece_map[index]; piece_pos& p = m_piece_map[index];
if (m_sequential_download >= 0) if (m_sequential_download >= 0)
{ {
TORRENT_ASSERT(p.peer_count > 0);
--p.peer_count; --p.peer_count;
m_dirty = true;
return; return;
} }
int prev_priority = p.priority(this); int prev_priority = p.priority(this);
@ -1756,6 +1756,7 @@ namespace libtorrent
void piece_picker::get_availability(std::vector<int>& avail) const void piece_picker::get_availability(std::vector<int>& avail) const
{ {
TORRENT_ASSERT(m_seeds >= 0);
TORRENT_PIECE_PICKER_INVARIANT_CHECK; TORRENT_PIECE_PICKER_INVARIANT_CHECK;
avail.resize(m_piece_map.size()); avail.resize(m_piece_map.size());

View File

@ -437,6 +437,37 @@ int test_main()
dc = p->distributed_copies(); dc = p->distributed_copies();
std::cout << "distributed copies: " << dc << std::endl; std::cout << "distributed copies: " << dc << std::endl;
TEST_CHECK(fabs(dc - (1.f + 5.f / 7.f)) < 0.01f); TEST_CHECK(fabs(dc - (1.f + 5.f / 7.f)) < 0.01f);
p->inc_refcount(0);
p->dec_refcount_all();
dc = p->distributed_copies();
std::cout << "distributed copies: " << dc << std::endl;
TEST_CHECK(fabs(dc - (0.f + 6.f / 7.f)) < 0.01f);
TEST_CHECK(test_pick(p) == 2);
// ========================================================
// test have_all and have_none with sequential download
print_title("test have_all and have_none with sequential download");
p = setup_picker("0123333", "* ", "", "");
dc = p->distributed_copies();
std::cout << "distributed copies: " << dc << std::endl;
TEST_CHECK(fabs(dc - (1.f + 5.f / 7.f)) < 0.01f);
p->inc_refcount_all();
dc = p->distributed_copies();
std::cout << "distributed copies: " << dc << std::endl;
TEST_CHECK(fabs(dc - (2.f + 5.f / 7.f)) < 0.01f);
p->sequential_download(true);
p->dec_refcount_all();
dc = p->distributed_copies();
std::cout << "distributed copies: " << dc << std::endl;
TEST_CHECK(fabs(dc - (1.f + 5.f / 7.f)) < 0.01f);
p->inc_refcount(0);
p->dec_refcount_all();
dc = p->distributed_copies();
std::cout << "distributed copies: " << dc << std::endl;
TEST_CHECK(fabs(dc - (0.f + 6.f / 7.f)) < 0.01f);
p->inc_refcount(1);
TEST_CHECK(test_pick(p) == 1);
// ======================================================== // ========================================================