turn piece picker option flags into a proper type
This commit is contained in:
parent
a33c81ad33
commit
9ac394f5b0
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue