forked from premiere/premiere-libtorrent
fixed piece picker bug related to sequential download, added unit test to expose it
This commit is contained in:
parent
6e69480176
commit
a4dfd63ca3
|
@ -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());
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
// ========================================================
|
// ========================================================
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue