turn piece picker option flags into a proper type

This commit is contained in:
arvidn 2018-01-28 14:39:43 +01:00 committed by Arvid Norberg
parent a33c81ad33
commit 9ac394f5b0
6 changed files with 67 additions and 52 deletions

View File

@ -66,6 +66,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/peer_info.hpp"
#include "libtorrent/aux_/vector.hpp"
#include "libtorrent/disk_interface.hpp"
#include "libtorrent/piece_picker.hpp" // for picker_options_t
#include <ctime>
#include <algorithm>
@ -88,8 +89,8 @@ namespace libtorrent {
namespace aux {
struct session_interface;
}
struct session_interface;
}
struct pending_block
{
@ -322,8 +323,7 @@ namespace aux {
void on_metadata_impl();
void picker_options(int o)
{ m_picker_options = o; }
void picker_options(picker_options_t o) { m_picker_options = o; }
int prefer_contiguous_blocks() const
{
@ -333,7 +333,7 @@ namespace aux {
bool on_parole() const;
int picker_options() const;
picker_options_t picker_options() const;
void prefer_contiguous_blocks(int num)
{ m_prefer_contiguous_blocks = num; }
@ -1023,7 +1023,7 @@ namespace aux {
// be augmented with flags controlled by other settings
// like sequential download etc. These are here to
// let plugins control flags that should always be set
int m_picker_options = 0;
picker_options_t m_picker_options{};
// the number of invalid piece-requests
// we have got from this peer. If the request

View File

@ -59,6 +59,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/aux_/typed_span.hpp"
#include "libtorrent/alert_types.hpp" // for picker_flags_t
#include "libtorrent/download_priority.hpp"
#include "libtorrent/flags.hpp"
namespace libtorrent {
@ -72,6 +73,9 @@ namespace libtorrent {
struct prio_index_tag_t {};
using prio_index_t = aux::strong_typedef<int, prio_index_tag_t>;
struct picker_options_tag;
using picker_options_t = flags::bitfield_flag<std::uint16_t, picker_options_tag>;
class TORRENT_EXTRA_EXPORT piece_picker
{
public:
@ -103,27 +107,30 @@ namespace libtorrent {
#endif
};
enum options_t
{
// pick rarest first
rarest_first = 1,
// pick the most common first, or the last pieces if sequential
reverse = 2,
// only pick pieces exclusively requested from this peer
on_parole = 4,
// always pick partial pieces before any other piece
prioritize_partials = 8,
// pick pieces in sequential order
sequential = 16,
// treat pieces with priority 6 and below as filtered
// to trigger end-game mode until all prio 7 pieces are
// completed
time_critical_mode = 32,
// only expands pieces (when prefer contiguous blocks is set)
// within properly aligned ranges, not the largest possible
// range of pieces.
align_expanded_pieces = 64
};
// pick rarest first
static constexpr picker_options_t rarest_first = 0_bit;
// pick the most common first, or the last pieces if sequential
static constexpr picker_options_t reverse = 1_bit;
// only pick pieces exclusively requested from this peer
static constexpr picker_options_t on_parole = 2_bit;
// always pick partial pieces before any other piece
static constexpr picker_options_t prioritize_partials = 3_bit;
// pick pieces in sequential order
static constexpr picker_options_t sequential = 4_bit;
// treat pieces with priority 6 and below as filtered
// to trigger end-game mode until all prio 7 pieces are
// completed
static constexpr picker_options_t time_critical_mode = 5_bit;
// only expands pieces (when prefer contiguous blocks is set)
// within properly aligned ranges, not the largest possible
// range of pieces.
static constexpr picker_options_t align_expanded_pieces = 6_bit;
struct downloading_piece
{
@ -261,7 +268,7 @@ namespace libtorrent {
picker_flags_t pick_pieces(typed_bitfield<piece_index_t> const& pieces
, std::vector<piece_block>& interesting_blocks, int num_blocks
, int prefer_contiguous_blocks, torrent_peer* peer
, int options, std::vector<piece_index_t> const& suggested_pieces
, picker_options_t options, std::vector<piece_index_t> const& suggested_pieces
, int num_peers
, counters& pc
) const;
@ -278,7 +285,7 @@ namespace libtorrent {
, std::vector<piece_block>& backup_blocks2
, int num_blocks, int prefer_contiguous_blocks
, torrent_peer* peer, std::vector<piece_index_t> const& ignore
, int options) const;
, picker_options_t options) const;
// picks blocks only from downloading pieces
int add_blocks_downloading(downloading_piece const& dp
@ -288,7 +295,7 @@ namespace libtorrent {
, std::vector<piece_block>& backup_blocks2
, int num_blocks, int prefer_contiguous_blocks
, torrent_peer* peer
, int options) const;
, picker_options_t options) const;
// clears the peer pointer in all downloading pieces with this
// peer pointer
@ -311,7 +318,7 @@ namespace libtorrent {
// marks this piece-block as queued for downloading
// options are flags from options_t.
bool mark_as_downloading(piece_block block, torrent_peer* peer
, int options = 0);
, picker_options_t options = {});
// returns true if the block was marked as writing,
// and false if the block is already finished or writing
@ -446,7 +453,7 @@ namespace libtorrent {
std::pair<piece_index_t, piece_index_t>
expand_piece(piece_index_t piece, int whole_pieces
, typed_bitfield<piece_index_t> const& have
, int options) const;
, picker_options_t options) const;
// only defined when TORRENT_PICKER_LOG is defined, used for debugging
// unit tests

View File

@ -859,14 +859,14 @@ namespace libtorrent {
bool peer_connection::on_parole() const
{ return peer_info_struct() && peer_info_struct()->on_parole; }
int peer_connection::picker_options() const
picker_options_t peer_connection::picker_options() const
{
TORRENT_ASSERT(is_single_thread());
int ret = m_picker_options;
picker_options_t ret = m_picker_options;
std::shared_ptr<torrent> t = m_torrent.lock();
TORRENT_ASSERT(t);
if (!t) return 0;
if (!t) return {};
if (t->num_time_critical_pieces() > 0)
{

View File

@ -69,6 +69,14 @@ namespace libtorrent {
constexpr prio_index_t piece_picker::piece_pos::we_have_index;
constexpr picker_options_t piece_picker::rarest_first;
constexpr picker_options_t piece_picker::reverse;
constexpr picker_options_t piece_picker::on_parole;
constexpr picker_options_t piece_picker::prioritize_partials;
constexpr picker_options_t piece_picker::sequential;
constexpr picker_options_t piece_picker::time_critical_mode;
constexpr picker_options_t piece_picker::align_expanded_pieces;
piece_picker::piece_picker(int const blocks_per_piece
, int const blocks_in_last_piece, int const total_num_pieces)
: m_priority_boundaries(1, m_pieces.end_index())
@ -1838,7 +1846,7 @@ namespace {
picker_flags_t piece_picker::pick_pieces(typed_bitfield<piece_index_t> const& pieces
, std::vector<piece_block>& interesting_blocks, int num_blocks
, int prefer_contiguous_blocks, torrent_peer* peer
, int options, std::vector<piece_index_t> const& suggested_pieces
, picker_options_t options, std::vector<piece_index_t> const& suggested_pieces
, int num_peers
, counters& pc
) const
@ -2007,7 +2015,7 @@ namespace {
}
// in time critical mode, only pick high priority pieces
if ((options & time_critical_mode) == 0)
if (!(options & time_critical_mode))
{
if (options & reverse)
{
@ -2056,7 +2064,7 @@ namespace {
// pieces. This is why reverse mode is disabled when we're in
// time-critical mode, because all high priority pieces are at the
// front of the list
if ((options & reverse) && (options & time_critical_mode) == 0)
if ((options & reverse) && !(options & time_critical_mode))
{
for (int i = int(m_priority_boundaries.size()) - 1; i >= 0; --i)
{
@ -2517,7 +2525,7 @@ get_out:
, std::vector<piece_block>& backup_blocks2
, int num_blocks, int prefer_contiguous_blocks
, torrent_peer* peer, std::vector<piece_index_t> const& ignore
, int options) const
, picker_options_t const options) const
{
TORRENT_ASSERT(is_piece_free(piece, pieces));
@ -2588,7 +2596,7 @@ get_out:
, std::vector<piece_block>& backup_blocks
, std::vector<piece_block>& backup_blocks2
, int num_blocks, int prefer_contiguous_blocks
, torrent_peer* peer, int options) const
, torrent_peer* peer, picker_options_t const options) const
{
if (!pieces[dp.index]) return num_blocks;
TORRENT_ASSERT(!m_piece_map[dp.index].filtered());
@ -2628,7 +2636,7 @@ get_out:
// to primarily request from a piece all by ourselves.
if (prefer_contiguous_blocks > contiguous_blocks
&& !exclusive_active
&& (options & on_parole) == 0)
&& !(options & on_parole))
{
if (int(backup_blocks2.size()) >= num_blocks)
return num_blocks;
@ -2680,7 +2688,7 @@ get_out:
std::pair<piece_index_t, piece_index_t>
piece_picker::expand_piece(piece_index_t const piece, int const contiguous_blocks
, typed_bitfield<piece_index_t> const& have, int const options) const
, typed_bitfield<piece_index_t> const& have, picker_options_t const options) const
{
if (contiguous_blocks == 0) return std::make_pair(piece, next(piece));
@ -2935,7 +2943,7 @@ get_out:
// options may be 0 or piece_picker::reverse
// returns false if the block could not be marked as downloading
bool piece_picker::mark_as_downloading(piece_block const block
, torrent_peer* peer, int const options)
, torrent_peer* peer, picker_options_t const options)
{
#ifdef TORRENT_PICKER_LOG
std::cerr << "[" << this << "] " << "mark_as_downloading( {"
@ -3022,7 +3030,7 @@ get_out:
// if we make a non-reverse request from a reversed piece,
// undo the reverse state
if ((options & reverse) == 0 && p.reverse())
if (!(options & reverse) && p.reverse())
{
int prio = p.priority(this);
// make it non-reverse

View File

@ -9599,7 +9599,7 @@ namespace libtorrent {
// the backup lists
picker->add_blocks(i->piece, c.get_bitfield(), interesting_blocks
, backup1, backup2, blocks_in_piece, 0, c.peer_info_struct()
, ignore, 0);
, ignore, {});
interesting_blocks.insert(interesting_blocks.end()
, backup1.begin(), backup1.end());

View File

@ -270,7 +270,7 @@ std::vector<piece_block> pick_pieces(std::shared_ptr<piece_picker> const& p
, int num_blocks
, int prefer_contiguous_blocks
, torrent_peer* peer_struct
, int options = piece_picker::rarest_first
, picker_options_t const options = piece_picker::rarest_first
, std::vector<piece_index_t> const& suggested_pieces = empty_vector)
{
std::vector<piece_block> picked;
@ -284,7 +284,7 @@ std::vector<piece_block> pick_pieces(std::shared_ptr<piece_picker> const& p
}
piece_index_t test_pick(std::shared_ptr<piece_picker> const& p
, int options = piece_picker::rarest_first)
, picker_options_t const options = piece_picker::rarest_first)
{
std::vector<piece_block> picked = pick_pieces(p, "*******", 1, 0, nullptr
, options, empty_vector);
@ -292,7 +292,7 @@ piece_index_t test_pick(std::shared_ptr<piece_picker> const& p
return picked[0].piece_index;
}
const int options = piece_picker::rarest_first;
picker_options_t const options = piece_picker::rarest_first;
counters pc;
} // anonymous namespace
@ -715,7 +715,7 @@ TORRENT_TEST(random_picking_downloading_piece)
// make sure the random piece picker can still pick partial pieces
auto p = setup_picker("1111111", " ", "", "013700f");
auto picked = pick_pieces(p, " *** *", 1, 0, nullptr
, 0, empty_vector);
, {}, empty_vector);
TEST_CHECK(int(picked.size()) > 0);
TEST_CHECK(picked.front() == piece_block(piece_index_t(1), 1)
|| picked.front() == piece_block(piece_index_t(2), 2)
@ -728,7 +728,7 @@ TORRENT_TEST(random_picking_downloading_piece_prefer_contiguous)
// even when prefer_contiguous_blocks is set
auto p = setup_picker("1111111", " ", "", "013700f");
auto picked = pick_pieces(p, " *** *", 1, 4, nullptr
, 0, empty_vector);
, {}, empty_vector);
TEST_CHECK(int(picked.size()) > 0);
TEST_CHECK(picked.front() == piece_block(piece_index_t(1), 1)
|| picked.front() == piece_block(piece_index_t(2), 2)
@ -1070,13 +1070,13 @@ TORRENT_TEST(random_pick)
auto p = setup_picker("1234567", " ", "1111122", "");
std::set<piece_index_t> random_pieces;
for (int i = 0; i < 100; ++i)
random_pieces.insert(test_pick(p, 0));
random_pieces.insert(test_pick(p, {}));
TEST_CHECK(random_pieces.size() == 7);
random_pieces.clear();
for (int i = 0; i < 7; ++i)
{
piece_index_t const piece = test_pick(p, 0);
piece_index_t const piece = test_pick(p, {});
p->we_have(piece);
random_pieces.insert(piece);
}