merge seed mode test and fixes from RC_1_0
This commit is contained in:
parent
bfe18dd0c9
commit
105c105867
|
@ -1779,6 +1779,8 @@ namespace libtorrent
|
|||
// shared_from_this()
|
||||
void torrent::init()
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
TORRENT_ASSERT(is_single_thread());
|
||||
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
|
@ -1867,10 +1869,6 @@ namespace libtorrent
|
|||
m_file_priority.resize(m_torrent_file->num_files(), 0);
|
||||
}
|
||||
|
||||
// in case file priorities were passed in via the add_torrent_params
|
||||
// and also in the case of share mode, we need to update the priorities
|
||||
update_piece_priorities();
|
||||
|
||||
// if we've already loaded file priorities, don't load piece priorities,
|
||||
// they will interfere.
|
||||
if (!m_seed_mode && m_resume_data && m_file_priority.empty())
|
||||
|
@ -1885,11 +1883,11 @@ namespace libtorrent
|
|||
for (int i = 0; i < piece_priority.string_length(); ++i)
|
||||
{
|
||||
int prio = p[i];
|
||||
if (!has_picker() && prio == 1) continue;
|
||||
if (!has_picker() && prio == 4) continue;
|
||||
need_picker();
|
||||
m_picker->set_piece_priority(i, p[i]);
|
||||
update_gauge();
|
||||
}
|
||||
update_gauge();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1925,6 +1923,7 @@ namespace libtorrent
|
|||
m_ses.get_io_service().post(boost::bind(&torrent::files_checked, shared_from_this()));
|
||||
m_resume_data.reset();
|
||||
update_gauge();
|
||||
update_state_list();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1991,7 +1990,6 @@ namespace libtorrent
|
|||
picker().piece_passed(*i);
|
||||
TORRENT_ASSERT(picker().have_piece(*i));
|
||||
we_have(*i);
|
||||
update_gauge();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2435,12 +2433,7 @@ namespace libtorrent
|
|||
update_gauge();
|
||||
we_have(i);
|
||||
}
|
||||
else if (m_seed_mode)
|
||||
{
|
||||
// being in seed mode and missing a piece is not compatible.
|
||||
// Leave seed mode if that happens
|
||||
leave_seed_mode(true);
|
||||
}
|
||||
|
||||
if (m_seed_mode && (pieces_str[i] & 2)) m_verified.set_bit(i);
|
||||
}
|
||||
}
|
||||
|
@ -4790,6 +4783,7 @@ namespace libtorrent
|
|||
m_abort = true;
|
||||
update_want_peers();
|
||||
update_want_tick();
|
||||
update_want_scrape();
|
||||
update_gauge();
|
||||
|
||||
// if the torrent is paused, it doesn't need
|
||||
|
@ -4836,6 +4830,7 @@ namespace libtorrent
|
|||
|
||||
m_allow_peers = false;
|
||||
m_auto_managed = false;
|
||||
update_state_list();
|
||||
for (int i = 0; i < aux::session_interface::num_torrent_lists; ++i)
|
||||
{
|
||||
if (!m_links[i].in_list()) continue;
|
||||
|
@ -5341,6 +5336,7 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
state_updated();
|
||||
update_state_list();
|
||||
}
|
||||
|
||||
void torrent::piece_priorities(std::vector<int>* pieces) const
|
||||
|
@ -5389,7 +5385,7 @@ namespace libtorrent
|
|||
limit = m_torrent_file->num_files();
|
||||
|
||||
if (int(m_file_priority.size()) < limit)
|
||||
m_file_priority.resize(limit, 1);
|
||||
m_file_priority.resize(limit, 4);
|
||||
|
||||
std::copy(files.begin(), files.begin() + limit, m_file_priority.begin());
|
||||
|
||||
|
@ -5430,7 +5426,7 @@ namespace libtorrent
|
|||
{
|
||||
// any unallocated slot is assumed to be 1
|
||||
if (prio == 1) return;
|
||||
m_file_priority.resize(index+1, 1);
|
||||
m_file_priority.resize(index+1, 4);
|
||||
|
||||
// initialize pad files to priority 0
|
||||
file_storage const& fs = m_torrent_file->files();
|
||||
|
@ -5458,14 +5454,14 @@ namespace libtorrent
|
|||
int torrent::file_priority(int index) const
|
||||
{
|
||||
// this call is only valid on torrents with metadata
|
||||
if (!valid_metadata()) return 1;
|
||||
if (!valid_metadata()) return 4;
|
||||
|
||||
if (index < 0 || index >= m_torrent_file->num_files()) return 0;
|
||||
|
||||
// any unallocated slot is assumed to be 1
|
||||
// unless it's a pad file
|
||||
if (int(m_file_priority.size()) <= index)
|
||||
return m_torrent_file->files().pad_file_at(index) ? 0 : 1;
|
||||
return m_torrent_file->files().pad_file_at(index) ? 0 : 4;
|
||||
|
||||
return m_file_priority[index];
|
||||
}
|
||||
|
@ -5482,7 +5478,7 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
files->clear();
|
||||
files->resize(m_torrent_file->num_files(), 1);
|
||||
files->resize(m_torrent_file->num_files(), 4);
|
||||
TORRENT_ASSERT(int(m_file_priority.size()) <= m_torrent_file->num_files());
|
||||
std::copy(m_file_priority.begin(), m_file_priority.end(), files->begin());
|
||||
}
|
||||
|
@ -5510,7 +5506,7 @@ namespace libtorrent
|
|||
position += size;
|
||||
int file_prio;
|
||||
if (m_file_priority.size() <= i)
|
||||
file_prio = 1;
|
||||
file_prio = 4;
|
||||
else
|
||||
file_prio = m_file_priority[i];
|
||||
|
||||
|
@ -6667,6 +6663,7 @@ namespace libtorrent
|
|||
{
|
||||
m_auto_managed = auto_managed_;
|
||||
|
||||
update_want_scrape();
|
||||
update_state_list();
|
||||
}
|
||||
|
||||
|
@ -6702,9 +6699,6 @@ namespace libtorrent
|
|||
#endif
|
||||
}
|
||||
|
||||
if (m_seed_mode)
|
||||
m_verified.resize(m_torrent_file->num_pieces(), false);
|
||||
|
||||
int now = m_ses.session_time();
|
||||
int tmp = rd.dict_find_int_value("last_scrape", -1);
|
||||
m_last_scrape = tmp == -1 ? (std::numeric_limits<boost::int16_t>::min)() : now - tmp;
|
||||
|
@ -6761,21 +6755,25 @@ namespace libtorrent
|
|||
|
||||
// load file priorities except if the add_torrent_param file was set to
|
||||
// override resume data
|
||||
if (!m_seed_mode && (!m_override_resume_data || m_file_priority.empty()))
|
||||
if (!m_override_resume_data || m_file_priority.empty())
|
||||
{
|
||||
bdecode_node file_priority = rd.dict_find_list("file_priority");
|
||||
if (file_priority && file_priority.list_size()
|
||||
== m_torrent_file->num_files())
|
||||
<= m_torrent_file->num_files())
|
||||
{
|
||||
int num_files = m_torrent_file->num_files();
|
||||
int num_files = file_priority.list_size();
|
||||
m_file_priority.resize(num_files);
|
||||
for (int i = 0; i < num_files; ++i)
|
||||
{
|
||||
m_file_priority[i] = file_priority.list_int_value_at(i, 1);
|
||||
// this is suspicious, leave seed mode
|
||||
if (m_file_priority[i] == 0) m_seed_mode = false;
|
||||
}
|
||||
// unallocated slots are assumed to be priority 1, so cut off any
|
||||
// trailing ones
|
||||
int end_range = num_files - 1;
|
||||
for (; end_range >= 0; --end_range) if (m_file_priority[end_range] != 1) break;
|
||||
m_file_priority.resize(end_range + 1);
|
||||
m_file_priority.resize(end_range + 1, 4);
|
||||
|
||||
// initialize pad files to priority 0
|
||||
file_storage const& fs = m_torrent_file->files();
|
||||
|
@ -6784,9 +6782,9 @@ namespace libtorrent
|
|||
if (!fs.pad_file_at(i)) continue;
|
||||
m_file_priority[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
update_piece_priorities();
|
||||
update_piece_priorities();
|
||||
}
|
||||
}
|
||||
|
||||
bdecode_node trackers = rd.dict_find_list("trackers");
|
||||
|
@ -6871,6 +6869,40 @@ namespace libtorrent
|
|||
// clear it here since we've just restored the resume data we already
|
||||
// have. Nothing has changed from that state yet.
|
||||
m_need_save_resume_data = false;
|
||||
|
||||
if (m_seed_mode)
|
||||
{
|
||||
// some sanity checking. Maybe we shouldn't be in seed mode anymore
|
||||
bdecode_node pieces = rd.dict_find("pieces");
|
||||
if (pieces && pieces.type() == bdecode_node::string_t
|
||||
&& int(pieces.string_length()) == m_torrent_file->num_pieces())
|
||||
{
|
||||
char const* pieces_str = pieces.string_ptr();
|
||||
for (int i = 0, end(pieces.string_length()); i < end; ++i)
|
||||
{
|
||||
// being in seed mode and missing a piece is not compatible.
|
||||
// Leave seed mode if that happens
|
||||
if ((pieces_str[i] & 1)) continue;
|
||||
m_seed_mode = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bdecode_node piece_priority = rd.dict_find_string("piece_priority");
|
||||
if (piece_priority && piece_priority.string_length()
|
||||
== m_torrent_file->num_pieces())
|
||||
{
|
||||
char const* p = piece_priority.string_ptr();
|
||||
for (int i = 0; i < piece_priority.string_length(); ++i)
|
||||
{
|
||||
if (p[i] > 0) continue;
|
||||
m_seed_mode = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_verified.resize(m_torrent_file->num_pieces(), false);
|
||||
}
|
||||
}
|
||||
|
||||
boost::shared_ptr<const torrent_info> torrent::get_torrent_copy()
|
||||
|
@ -7199,7 +7231,7 @@ namespace libtorrent
|
|||
bool default_prio = true;
|
||||
for (int i = 0, end(m_torrent_file->num_pieces()); i < end; ++i)
|
||||
{
|
||||
if (m_picker->piece_priority(i) == 1) continue;
|
||||
if (m_picker->piece_priority(i) == 4) continue;
|
||||
default_prio = false;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ std::vector<char> generate_resume_data(torrent_info* ti
|
|||
rd["file-version"] = 1;
|
||||
rd["info-hash"] = ti->info_hash().to_string();
|
||||
rd["blocks per piece"] = (std::max)(1, ti->piece_length() / 0x4000);
|
||||
rd["pieces"] = std::string(ti->num_pieces(), '\0');
|
||||
rd["pieces"] = std::string(ti->num_pieces(), '\x01');
|
||||
|
||||
rd["total_uploaded"] = 1337;
|
||||
rd["total_downloaded"] = 1338;
|
||||
|
@ -221,6 +221,7 @@ TORRENT_TEST(piece_priorities)
|
|||
|
||||
// now, make sure the piece priorities are loaded correctly
|
||||
h = ses.add_torrent(p);
|
||||
|
||||
TEST_EQUAL(h.piece_priority(0), 0);
|
||||
TEST_EQUAL(h.piece_priority(1), 4);
|
||||
TEST_EQUAL(h.piece_priority(ti->num_pieces()-1), 0);
|
||||
|
@ -240,9 +241,9 @@ TORRENT_TEST(file_priorities_default)
|
|||
std::vector<int> file_priorities = test_resume_flags(ses, 0, "", "").file_priorities();
|
||||
|
||||
TEST_EQUAL(file_priorities.size(), 3);
|
||||
TEST_EQUAL(file_priorities[0], 1);
|
||||
TEST_EQUAL(file_priorities[1], 1);
|
||||
TEST_EQUAL(file_priorities[2], 1);
|
||||
TEST_EQUAL(file_priorities[0], 4);
|
||||
TEST_EQUAL(file_priorities[1], 4);
|
||||
TEST_EQUAL(file_priorities[2], 4);
|
||||
}
|
||||
|
||||
TORRENT_TEST(file_priorities_resume_seed_mode)
|
||||
|
@ -271,6 +272,82 @@ TORRENT_TEST(file_priorities_seed_mode)
|
|||
TEST_EQUAL(file_priorities[2], 0);
|
||||
}
|
||||
|
||||
void test_seed_mode(bool file_prio, bool pieces_have, bool piece_prio)
|
||||
{
|
||||
fprintf(stderr, "test_seed_mode file_prio: %d pieces_have: %d piece_prio: %d\n"
|
||||
, file_prio, pieces_have, piece_prio);
|
||||
|
||||
session ses;
|
||||
boost::shared_ptr<torrent_info> ti = generate_torrent();
|
||||
add_torrent_params p;
|
||||
p.ti = ti;
|
||||
p.save_path = ".";
|
||||
|
||||
entry rd;
|
||||
|
||||
rd["file-format"] = "libtorrent resume file";
|
||||
rd["file-version"] = 1;
|
||||
rd["info-hash"] = ti->info_hash().to_string();
|
||||
rd["blocks per piece"] = (std::max)(1, ti->piece_length() / 0x4000);
|
||||
|
||||
if (file_prio)
|
||||
{
|
||||
// this should take it out of seed_mode
|
||||
entry::list_type& file_prio = rd["file_priority"].list();
|
||||
file_prio.push_back(entry(0));
|
||||
}
|
||||
|
||||
std::string pieces(ti->num_pieces(), '\x01');
|
||||
if (pieces_have)
|
||||
{
|
||||
pieces[0] = '\0';
|
||||
}
|
||||
rd["pieces"] = pieces;
|
||||
|
||||
std::string pieces_prio(ti->num_pieces(), '\x01');
|
||||
if (piece_prio)
|
||||
{
|
||||
pieces_prio[0] = '\0';
|
||||
}
|
||||
rd["piece_priority"] = pieces_prio;
|
||||
|
||||
rd["seed_mode"] = 1;
|
||||
|
||||
bencode(back_inserter(p.resume_data), rd);
|
||||
|
||||
torrent_handle h = ses.add_torrent(p);
|
||||
|
||||
torrent_status s = h.status();
|
||||
if (file_prio || piece_prio || pieces_have)
|
||||
{
|
||||
TEST_EQUAL(s.seed_mode, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
TEST_EQUAL(s.seed_mode, true);
|
||||
}
|
||||
}
|
||||
|
||||
TORRENT_TEST(seed_mode_file_prio)
|
||||
{
|
||||
test_seed_mode(true, false, false);
|
||||
}
|
||||
|
||||
TORRENT_TEST(seed_mode_piece_prio)
|
||||
{
|
||||
test_seed_mode(false, true, false);
|
||||
}
|
||||
|
||||
TORRENT_TEST(seed_mode_piece_have)
|
||||
{
|
||||
test_seed_mode(false, false, true);
|
||||
}
|
||||
|
||||
TORRENT_TEST(seed_mode_preserve)
|
||||
{
|
||||
test_seed_mode(false, false, false);
|
||||
}
|
||||
|
||||
TORRENT_TEST(resume_save_load)
|
||||
{
|
||||
libtorrent::session ses;
|
||||
|
|
Loading…
Reference in New Issue