introduce type for torrent queue_position

This commit is contained in:
arvidn 2017-10-25 02:39:22 +02:00 committed by Arvid Norberg
parent 5480c08184
commit f57b90b500
12 changed files with 129 additions and 109 deletions

View File

@ -299,6 +299,7 @@ void bind_converters()
to_python_converter<std::vector<lt::udp::endpoint>, vector_to_list<std::vector<lt::udp::endpoint>>>();
to_python_converter<std::vector<std::pair<std::string, int>>, vector_to_list<std::vector<std::pair<std::string, int>>>>();
to_python_converter<lt::queue_position_t, from_strong_typedef<lt::queue_position_t>>();
to_python_converter<lt::piece_index_t, from_strong_typedef<lt::piece_index_t>>();
to_python_converter<lt::file_index_t, from_strong_typedef<lt::file_index_t>>();
to_python_converter<lt::port_mapping_t, from_strong_typedef<lt::port_mapping_t>>();
@ -361,6 +362,7 @@ void bind_converters()
list_to_vector<lt::aux::noexcept_movable<std::vector<lt::udp::endpoint>>>();
list_to_vector<lt::aux::noexcept_movable<std::vector<std::pair<std::string, int>>>>();
to_strong_typedef<lt::queue_position_t>();
to_strong_typedef<lt::piece_index_t>();
to_strong_typedef<lt::file_index_t>();
to_strong_typedef<lt::port_mapping_t>();

View File

@ -77,6 +77,8 @@ class test_torrent_handle(unittest.TestCase):
self.h.prioritize_pieces([(0, 1)])
self.assertEqual(self.h.piece_priorities(), [1])
print(self.h.queue_position())
def test_torrent_handle_in_set(self):
self.setup()
torrents = set()

View File

@ -37,6 +37,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/torrent_status.hpp"
const int header_size = 2;
using lt::queue_position_t;
std::string torrent_state(lt::torrent_status const& s)
{
@ -72,12 +73,13 @@ std::string torrent_state(lt::torrent_status const& s)
bool compare_torrent(lt::torrent_status const* lhs, lt::torrent_status const* rhs)
{
if (lhs->queue_position != -1 && rhs->queue_position != -1)
if (lhs->queue_position != queue_position_t{-1} && rhs->queue_position != queue_position_t{-1})
{
// both are downloading, sort by queue pos
return lhs->queue_position < rhs->queue_position;
}
else if (lhs->queue_position == -1 && rhs->queue_position == -1)
else if (lhs->queue_position == queue_position_t{-1}
&& rhs->queue_position == queue_position_t{-1})
{
// both are seeding, sort by seed-rank
if (lhs->seed_rank != rhs->seed_rank)
@ -86,7 +88,8 @@ bool compare_torrent(lt::torrent_status const* lhs, lt::torrent_status const* rh
return lhs->info_hash < rhs->info_hash;
}
return (lhs->queue_position == -1) < (rhs->queue_position == -1);
return (lhs->queue_position == queue_position_t{-1})
< (rhs->queue_position == queue_position_t{-1});
}
torrent_view::torrent_view()
@ -341,10 +344,11 @@ void torrent_view::print_torrent(lt::torrent_status const& s, bool selected)
selection = "\x1b[1m\x1b[44m";
char queue_pos[16] = {0};
if (s.queue_position == -1)
if (s.queue_position == queue_position_t{-1})
std::snprintf(queue_pos, sizeof(queue_pos), "-");
else
std::snprintf(queue_pos, sizeof(queue_pos), "%d", s.queue_position);
std::snprintf(queue_pos, sizeof(queue_pos), "%d"
, static_cast<int>(s.queue_position));
std::string name = s.name;
if (name.size() > 50) name.resize(50);

View File

@ -284,7 +284,7 @@ namespace aux {
// this is set while the session is building the
// torrent status update message
bool m_posting_torrent_updates = false;
bool verify_queue_position(torrent const* t, int pos) override;
bool verify_queue_position(torrent const* t, queue_position_t pos) override;
#endif
void on_exception(std::exception const& e) override;
@ -348,7 +348,7 @@ namespace aux {
#endif
std::shared_ptr<torrent> delay_load_torrent(sha1_hash const& info_hash
, peer_connection* pc) override;
void set_queue_position(torrent* t, int p) override;
void set_queue_position(torrent* t, queue_position_t p) override;
peer_id const& get_peer_id() const override { return m_peer_id; }
@ -838,7 +838,7 @@ namespace aux {
// all torrents that are downloading or queued,
// ordered by their queue position
aux::vector<torrent*> m_download_queue;
aux::vector<torrent*, queue_position_t> m_download_queue;
#if !defined(TORRENT_DISABLE_ENCRYPTION) && !defined(TORRENT_DISABLE_EXTENSIONS)
// this maps obfuscated hashes to torrents. It's only

View File

@ -90,6 +90,13 @@ namespace libtorrent {
struct counters;
struct resolver_interface;
// hidden
struct queue_position_tag;
using queue_position_t = aux::strong_typedef<int, queue_position_tag>;
constexpr queue_position_t no_pos{-1};
constexpr queue_position_t last_pos{(std::numeric_limits<int>::max)()};
#ifndef TORRENT_DISABLE_DHT
namespace dht {
@ -192,7 +199,7 @@ namespace libtorrent { namespace aux {
//deprecated in 1.2
virtual void insert_uuid_torrent(std::string uuid, std::shared_ptr<torrent> const& t) = 0;
#endif
virtual void set_queue_position(torrent* t, int p) = 0;
virtual void set_queue_position(torrent* t, queue_position_t p) = 0;
virtual int num_torrents() const = 0;
virtual peer_id const& get_peer_id() const = 0;
@ -316,7 +323,7 @@ namespace libtorrent { namespace aux {
virtual void sent_buffer(int size) = 0;
#if TORRENT_USE_ASSERTS
virtual bool verify_queue_position(torrent const*, int) = 0;
virtual bool verify_queue_position(torrent const*, queue_position_t) = 0;
#endif
virtual ~session_interface() {}

View File

@ -352,7 +352,7 @@ namespace libtorrent {
{
TORRENT_ASSERT(m_added == true);
m_added = false;
set_queue_position(-1);
set_queue_position(no_pos);
// make sure we decrement the gauge counter for this torrent
update_gauge();
}
@ -463,10 +463,10 @@ namespace libtorrent {
void queue_up();
void queue_down();
void set_queue_position(int p);
int queue_position() const { return m_sequence_number; }
void set_queue_position(queue_position_t p);
queue_position_t queue_position() const { return m_sequence_number; }
// used internally
void set_queue_position_impl(int const p)
void set_queue_position_impl(queue_position_t const p)
{
if (m_sequence_number == p) return;
m_sequence_number = p;
@ -1060,7 +1060,7 @@ namespace libtorrent {
, span<char const> data);
#endif
int sequence_number() const { return m_sequence_number; }
queue_position_t sequence_number() const { return m_sequence_number; }
bool seed_mode() const { return m_seed_mode; }
void leave_seed_mode(bool skip_checking);
@ -1417,7 +1417,7 @@ namespace libtorrent {
// the sequence number for this torrent, this is a
// monotonically increasing number for each added torrent
int m_sequence_number;
queue_position_t m_sequence_number;
// used to post a message to defer disconnecting peers
std::vector<peer_connection*> m_peers_to_disconnect;

View File

@ -78,6 +78,7 @@ namespace aux {
struct storage_interface;
class torrent;
// hidden
struct status_flags_tag;
using status_flags_t = flags::bitfield_flag<std::uint32_t, status_flags_tag>;
@ -101,6 +102,10 @@ namespace aux {
struct resume_data_flags_tag;
using resume_data_flags_t = flags::bitfield_flag<std::uint8_t, resume_data_flags_tag>;
// hidden
struct queue_position_tag;
using queue_position_t = aux::strong_typedef<int, queue_position_tag>;
// holds the state of a block in a piece. Who we requested
// it from and how far along we are at downloading it.
struct TORRENT_EXPORT block_info
@ -798,7 +803,7 @@ namespace aux {
// the queue. Up means closer to the front and down means closer to the
// back of the queue. Top and bottom refers to the front and the back of
// the queue respectively.
int queue_position() const;
queue_position_t queue_position() const;
void queue_position_up() const;
void queue_position_down() const;
void queue_position_top() const;
@ -807,7 +812,7 @@ namespace aux {
// updates the position in the queue for this torrent. The relative order
// of all other torrents remain intact but their numerical queue position
// shifts to make space for this torrent's new position
void queue_position_set(int p) const;
void queue_position_set(queue_position_t p) const;
// For SSL torrents, use this to specify a path to a .pem file to use as
// this client's certificate. The certificate must be signed by the

View File

@ -285,7 +285,7 @@ namespace libtorrent {
// the position this torrent has in the download
// queue. If the torrent is a seed or finished, this is -1.
int queue_position = 0;
queue_position_t queue_position{};
// the total rates for all peers for this torrent. These will usually
// have better precision than summing the rates from all peers. The rates

View File

@ -3039,7 +3039,7 @@ namespace {
return false;
}
bool session_impl::verify_queue_position(torrent const* t, int pos)
bool session_impl::verify_queue_position(torrent const* t, queue_position_t const pos)
{
return m_download_queue.end_index() > pos && m_download_queue[pos] == t;
}
@ -4352,15 +4352,15 @@ namespace {
#endif
}
void session_impl::set_queue_position(torrent* me, int p)
void session_impl::set_queue_position(torrent* me, queue_position_t p)
{
int const current_pos = me->queue_position();
queue_position_t const current_pos = me->queue_position();
if (current_pos == p) return;
if (p >= 0 && current_pos == -1)
if (p >= queue_position_t{0} && current_pos == no_pos)
{
// we're inserting the torrent into the download queue
int const last = m_download_queue.end_index();
queue_position_t const last = m_download_queue.end_index();
if (p >= last)
{
m_download_queue.push_back(me);
@ -4368,21 +4368,21 @@ namespace {
return;
}
m_download_queue.insert(m_download_queue.begin() + p, me);
for (int i = p; i < m_download_queue.end_index(); ++i)
m_download_queue.insert(m_download_queue.begin() + static_cast<int>(p), me);
for (queue_position_t i = p; i < m_download_queue.end_index(); ++i)
{
m_download_queue[i]->set_queue_position_impl(i);
}
}
else if (p < 0)
else if (p < queue_position_t{})
{
// we're removing the torrent from the download queue
TORRENT_ASSERT(current_pos >= 0);
TORRENT_ASSERT(p == -1);
TORRENT_ASSERT(current_pos >= queue_position_t{0});
TORRENT_ASSERT(p == no_pos);
TORRENT_ASSERT(m_download_queue[current_pos] == me);
m_download_queue.erase(m_download_queue.begin() + current_pos);
me->set_queue_position_impl(-1);
for (int i = current_pos; i < m_download_queue.end_index(); ++i)
m_download_queue.erase(m_download_queue.begin() + static_cast<int>(current_pos));
me->set_queue_position_impl(no_pos);
for (queue_position_t i = current_pos; i < m_download_queue.end_index(); ++i)
{
m_download_queue[i]->set_queue_position_impl(i);
}
@ -4391,7 +4391,7 @@ namespace {
{
// we're moving the torrent up the queue
torrent* tmp = me;
for (int i = p; i <= current_pos; ++i)
for (queue_position_t i = p; i <= current_pos; ++i)
{
std::swap(m_download_queue[i], tmp);
m_download_queue[i]->set_queue_position_impl(i);
@ -4401,10 +4401,10 @@ namespace {
else if (p > current_pos)
{
// we're moving the torrent down the queue
p = std::min(p, m_download_queue.end_index() - 1);
for (int i = current_pos; i < p; ++i)
p = std::min(p, prev(m_download_queue.end_index()));
for (queue_position_t i = current_pos; i < p; ++i)
{
m_download_queue[i] = m_download_queue[i + 1];
m_download_queue[i] = m_download_queue[next(i)];
m_download_queue[i]->set_queue_position_impl(i);
}
m_download_queue[p] = me;
@ -6853,7 +6853,7 @@ namespace {
TORRENT_ASSERT(i->m_links[l].in_list());
}
int idx = 0;
queue_position_t idx{};
for (auto t : m_download_queue)
{
TORRENT_ASSERT(t->queue_position() == idx);
@ -6866,8 +6866,7 @@ namespace {
torrent_state_gauges.fill(0);
#if defined TORRENT_EXPENSIVE_INVARIANT_CHECKS
std::unordered_set<int> unique;
std::unordered_set<queue_position_t> unique;
#endif
int num_active_downloading = 0;
@ -6886,10 +6885,10 @@ namespace {
++torrent_state_gauges[state];
}
int const pos = t->queue_position();
if (pos < 0)
queue_position_t const pos = t->queue_position();
if (pos < queue_position_t{})
{
TORRENT_ASSERT(pos == -1);
TORRENT_ASSERT(pos == no_pos);
continue;
}
++total_downloaders;

View File

@ -2223,7 +2223,7 @@ namespace libtorrent {
set_state(torrent_status::checking_resume_data);
if (m_auto_managed && !is_finished())
set_queue_position((std::numeric_limits<int>::max)());
set_queue_position(last_pos);
TORRENT_ASSERT(m_outstanding_check_files == false);
m_add_torrent_params.reset();
@ -7251,7 +7251,7 @@ namespace libtorrent {
TORRENT_ASSERT(is_finished());
set_state(torrent_status::finished);
set_queue_position(-1);
set_queue_position(no_pos);
m_became_finished = aux::time_now32();
@ -7333,7 +7333,7 @@ namespace libtorrent {
TORRENT_ASSERT(!is_finished());
set_state(torrent_status::downloading);
set_queue_position((std::numeric_limits<int>::max)());
set_queue_position(last_pos);
m_completed_time = 0;
@ -7709,7 +7709,7 @@ namespace libtorrent {
TORRENT_ASSERT(current_stats_state() == int(m_current_gauge_state + counters::num_checking_torrents)
|| m_current_gauge_state == no_gauge_state);
TORRENT_ASSERT(m_sequence_number == -1
TORRENT_ASSERT(m_sequence_number == no_pos
|| m_ses.verify_queue_position(this, m_sequence_number));
for (auto const& i : m_time_critical_pieces)
@ -7982,30 +7982,30 @@ namespace libtorrent {
// -1
if (m_abort || is_finished()) return;
set_queue_position(queue_position() == 0
? queue_position() : queue_position() - 1);
set_queue_position(queue_position() == queue_position_t{0}
? queue_position() : prev(queue_position()));
}
void torrent::queue_down()
{
set_queue_position(queue_position() + 1);
set_queue_position(next(queue_position()));
}
void torrent::set_queue_position(int p)
void torrent::set_queue_position(queue_position_t const p)
{
TORRENT_ASSERT(is_single_thread());
// finished torrents may not change their queue positions, as it's set to
// -1
if ((m_abort || is_finished()) && p != -1) return;
if ((m_abort || is_finished()) && p != no_pos) return;
TORRENT_ASSERT((p == -1) == is_finished()
|| (!m_auto_managed && p == -1)
|| (m_abort && p == -1)
|| (!m_added && p == -1));
TORRENT_ASSERT((p == no_pos) == is_finished()
|| (!m_auto_managed && p == no_pos)
|| (m_abort && p == no_pos)
|| (!m_added && p == no_pos));
if (p == m_sequence_number) return;
TORRENT_ASSERT(p >= -1);
TORRENT_ASSERT(p >= no_pos);
state_updated();

View File

@ -385,9 +385,10 @@ namespace libtorrent {
}
#endif
int torrent_handle::queue_position() const
queue_position_t torrent_handle::queue_position() const
{
return sync_call_ret<int>(-1, &torrent::queue_position);
return sync_call_ret<queue_position_t>(no_pos
, &torrent::queue_position);
}
void torrent_handle::queue_position_up() const
@ -400,21 +401,21 @@ namespace libtorrent {
async_call(&torrent::queue_down);
}
void torrent_handle::queue_position_set(int p) const
void torrent_handle::queue_position_set(queue_position_t const p) const
{
TORRENT_ASSERT_PRECOND(p >= 0);
if (p < 0) return;
TORRENT_ASSERT_PRECOND(p >= queue_position_t{});
if (p < queue_position_t{}) return;
async_call(&torrent::set_queue_position, p);
}
void torrent_handle::queue_position_top() const
{
async_call(&torrent::set_queue_position, 0);
async_call(&torrent::set_queue_position, queue_position_t{});
}
void torrent_handle::queue_position_bottom() const
{
async_call(&torrent::set_queue_position, INT_MAX);
async_call(&torrent::set_queue_position, last_pos);
}
void torrent_handle::clear_error() const

View File

@ -485,80 +485,80 @@ void test_queue(add_torrent_params p)
torrent_handle finished = torrents[5];
// add_torrent should be ordered
TEST_EQUAL(finished.queue_position(), -1);
TEST_EQUAL(torrents[0].queue_position(), 0);
TEST_EQUAL(torrents[1].queue_position(), 1);
TEST_EQUAL(torrents[2].queue_position(), 2);
TEST_EQUAL(torrents[3].queue_position(), 3);
TEST_EQUAL(torrents[4].queue_position(), 4);
TEST_EQUAL(finished.queue_position(), no_pos);
TEST_EQUAL(torrents[0].queue_position(), queue_position_t{0});
TEST_EQUAL(torrents[1].queue_position(), queue_position_t{1});
TEST_EQUAL(torrents[2].queue_position(), queue_position_t{2});
TEST_EQUAL(torrents[3].queue_position(), queue_position_t{3});
TEST_EQUAL(torrents[4].queue_position(), queue_position_t{4});
// test top and bottom
torrents[2].queue_position_top();
torrents[1].queue_position_bottom();
TEST_EQUAL(finished.queue_position(), -1);
TEST_EQUAL(torrents[2].queue_position(), 0);
TEST_EQUAL(torrents[0].queue_position(), 1);
TEST_EQUAL(torrents[3].queue_position(), 2);
TEST_EQUAL(torrents[4].queue_position(), 3);
TEST_EQUAL(torrents[1].queue_position(), 4);
TEST_EQUAL(finished.queue_position(), no_pos);
TEST_EQUAL(torrents[2].queue_position(), queue_position_t{0});
TEST_EQUAL(torrents[0].queue_position(), queue_position_t{1});
TEST_EQUAL(torrents[3].queue_position(), queue_position_t{2});
TEST_EQUAL(torrents[4].queue_position(), queue_position_t{3});
TEST_EQUAL(torrents[1].queue_position(), queue_position_t{4});
// test set pos
torrents[0].queue_position_set(0);
torrents[1].queue_position_set(1);
torrents[0].queue_position_set(queue_position_t{0});
torrents[1].queue_position_set(queue_position_t{1});
// torrent 2 should be get moved down by 0 and 1 to pos 2
TEST_EQUAL(finished.queue_position(), -1);
TEST_EQUAL(torrents[0].queue_position(), 0);
TEST_EQUAL(torrents[1].queue_position(), 1);
TEST_EQUAL(torrents[2].queue_position(), 2);
TEST_EQUAL(torrents[3].queue_position(), 3);
TEST_EQUAL(torrents[4].queue_position(), 4);
TEST_EQUAL(finished.queue_position(), no_pos);
TEST_EQUAL(torrents[0].queue_position(), queue_position_t{0});
TEST_EQUAL(torrents[1].queue_position(), queue_position_t{1});
TEST_EQUAL(torrents[2].queue_position(), queue_position_t{2});
TEST_EQUAL(torrents[3].queue_position(), queue_position_t{3});
TEST_EQUAL(torrents[4].queue_position(), queue_position_t{4});
//test strange up and down commands
torrents[0].queue_position_up();
torrents[4].queue_position_down();
TEST_EQUAL(finished.queue_position(), -1);
TEST_EQUAL(torrents[0].queue_position(), 0);
TEST_EQUAL(torrents[1].queue_position(), 1);
TEST_EQUAL(torrents[2].queue_position(), 2);
TEST_EQUAL(torrents[3].queue_position(), 3);
TEST_EQUAL(torrents[4].queue_position(), 4);
TEST_EQUAL(finished.queue_position(), no_pos);
TEST_EQUAL(torrents[0].queue_position(), queue_position_t{0});
TEST_EQUAL(torrents[1].queue_position(), queue_position_t{1});
TEST_EQUAL(torrents[2].queue_position(), queue_position_t{2});
TEST_EQUAL(torrents[3].queue_position(), queue_position_t{3});
TEST_EQUAL(torrents[4].queue_position(), queue_position_t{4});
torrents[1].queue_position_up();
torrents[3].queue_position_down();
finished.queue_position_up();
TEST_EQUAL(finished.queue_position(), -1);
TEST_EQUAL(torrents[1].queue_position(), 0);
TEST_EQUAL(torrents[0].queue_position(), 1);
TEST_EQUAL(torrents[2].queue_position(), 2);
TEST_EQUAL(torrents[4].queue_position(), 3);
TEST_EQUAL(torrents[3].queue_position(), 4);
TEST_EQUAL(finished.queue_position(), no_pos);
TEST_EQUAL(torrents[1].queue_position(), queue_position_t{0});
TEST_EQUAL(torrents[0].queue_position(), queue_position_t{1});
TEST_EQUAL(torrents[2].queue_position(), queue_position_t{2});
TEST_EQUAL(torrents[4].queue_position(), queue_position_t{3});
TEST_EQUAL(torrents[3].queue_position(), queue_position_t{4});
torrents[1].queue_position_down();
torrents[3].queue_position_up();
finished.queue_position_down();
TEST_EQUAL(finished.queue_position(), -1);
TEST_EQUAL(torrents[0].queue_position(), 0);
TEST_EQUAL(torrents[1].queue_position(), 1);
TEST_EQUAL(torrents[2].queue_position(), 2);
TEST_EQUAL(torrents[3].queue_position(), 3);
TEST_EQUAL(torrents[4].queue_position(), 4);
TEST_EQUAL(finished.queue_position(), no_pos);
TEST_EQUAL(torrents[0].queue_position(), queue_position_t{0});
TEST_EQUAL(torrents[1].queue_position(), queue_position_t{1});
TEST_EQUAL(torrents[2].queue_position(), queue_position_t{2});
TEST_EQUAL(torrents[3].queue_position(), queue_position_t{3});
TEST_EQUAL(torrents[4].queue_position(), queue_position_t{4});
// test set pos on not existing pos
torrents[3].queue_position_set(10);
finished.queue_position_set(10);
torrents[3].queue_position_set(queue_position_t{10});
finished.queue_position_set(queue_position_t{10});
TEST_EQUAL(finished.queue_position(), -1);
TEST_EQUAL(torrents[0].queue_position(), 0);
TEST_EQUAL(torrents[1].queue_position(), 1);
TEST_EQUAL(torrents[2].queue_position(), 2);
TEST_EQUAL(torrents[4].queue_position(), 3);
TEST_EQUAL(torrents[3].queue_position(), 4);
TEST_EQUAL(finished.queue_position(), no_pos);
TEST_EQUAL(torrents[0].queue_position(), queue_position_t{0});
TEST_EQUAL(torrents[1].queue_position(), queue_position_t{1});
TEST_EQUAL(torrents[2].queue_position(), queue_position_t{2});
TEST_EQUAL(torrents[4].queue_position(), queue_position_t{3});
TEST_EQUAL(torrents[3].queue_position(), queue_position_t{4});
}
TORRENT_TEST(queue)