Browse Source

introducing a new torrent piece property to be persisted on disk: max_seen

is the maximum availability (peer count) ever seen for this piece.
new rpc getpiecemaxseen.
miguelfreitas
Miguel Freitas 10 years ago
parent
commit
1056d874bf
  1. 15
      libtorrent/include/libtorrent/piece_picker.hpp
  2. 1
      libtorrent/include/libtorrent/torrent.hpp
  3. 1
      libtorrent/include/libtorrent/torrent_handle.hpp
  4. 46
      libtorrent/src/piece_picker.cpp
  5. 29
      libtorrent/src/torrent.cpp
  6. 6
      libtorrent/src/torrent_handle.cpp
  7. 2
      src/bitcoinrpc.cpp
  8. 1
      src/bitcoinrpc.h
  9. 20
      src/twister.cpp

15
libtorrent/include/libtorrent/piece_picker.hpp

@ -180,6 +180,7 @@ namespace libtorrent @@ -180,6 +180,7 @@ namespace libtorrent
piece_picker();
void get_availability(std::vector<int>& avail) const;
void get_max_seen(std::vector<int>& max_seen) const;
// increases the peer count for the given piece
// (is used when a HAVE message is received)
@ -249,6 +250,12 @@ namespace libtorrent @@ -249,6 +250,12 @@ namespace libtorrent
// returns the current piece priorities for all pieces
void piece_priorities(std::vector<int>& pieces) const;
// sets the max_seen of a piece.
void set_piece_max_seen(int index, int new_piece_max_seen);
// returns the max_seen for the piece at 'index'
int piece_max_seen(int index) const;
// ========== start deprecation ==============
// fills the bitmask with 1's for pieces that are filtered
@ -412,6 +419,7 @@ namespace libtorrent @@ -412,6 +419,7 @@ namespace libtorrent
piece_pos() {}
piece_pos(int peer_count_, int index_)
: peer_count(peer_count_)
, max_seen((peer_count_ <= max_seen_count) ? peer_count_ : max_seen_count)
, downloading(0)
, full(0)
, piece_priority(1)
@ -428,6 +436,8 @@ namespace libtorrent @@ -428,6 +436,8 @@ namespace libtorrent
#else
boost::uint32_t peer_count : 16;
#endif
// max_seen is max of peer_count (saturated to 6 bits = max_seen_count)
boost::uint32_t max_seen : 6;
// post flags (1 = rt, 2 = dm, 4 = fav, 12 = pfav)
boost::uint32_t post_flags : 4;
// is 1 if the piece is marked as being downloaded
@ -467,10 +477,11 @@ namespace libtorrent @@ -467,10 +477,11 @@ namespace libtorrent
filter_priority = 0,
// the max number the peer count can hold
#if TORRENT_COMPACT_PICKER
max_peer_count = 0x1ff
max_peer_count = 0x1ff,
#else
max_peer_count = 0xffff
max_peer_count = 0xffff,
#endif
max_seen_count = 0x3f
};
bool have() const { return index == we_have_index; }

1
libtorrent/include/libtorrent/torrent.hpp

@ -302,6 +302,7 @@ namespace libtorrent @@ -302,6 +302,7 @@ namespace libtorrent
// ============ end deprecation =============
void piece_availability(std::vector<int>& avail) const;
void piece_max_seen(std::vector<int>& max_seen) const;
void set_piece_priority(int index, int priority);
int piece_priority(int index) const;

1
libtorrent/include/libtorrent/torrent_handle.hpp

@ -351,6 +351,7 @@ namespace libtorrent @@ -351,6 +351,7 @@ namespace libtorrent
#endif
void piece_availability(std::vector<int>& avail) const;
void piece_max_seen(std::vector<int>& max_seen) const;
// priority must be within the range [0, 7]
void piece_priority(int index, int priority) const;

46
libtorrent/src/piece_picker.cpp

@ -111,6 +111,7 @@ namespace libtorrent @@ -111,6 +111,7 @@ namespace libtorrent
, end(m_piece_map.end()); i != end; ++i)
{
i->peer_count = 0;
i->max_seen = 0;
i->downloading = 0;
i->index = 0;
#ifdef TORRENT_DEBUG_REFCOUNTS
@ -157,6 +158,7 @@ namespace libtorrent @@ -157,6 +158,7 @@ namespace libtorrent
, end(m_piece_map.end()); i != end; ++i)
{
i->peer_count = 0;
i->max_seen = 0;
i->downloading = 0;
i->index = 0;
#ifdef TORRENT_DEBUG_REFCOUNTS
@ -987,6 +989,11 @@ namespace libtorrent @@ -987,6 +989,11 @@ namespace libtorrent
int prev_priority = p.priority(this);
++p.peer_count;
if( p.peer_count > p.max_seen ) {
p.max_seen = (p.peer_count <= piece_pos::max_seen_count)
? p.peer_count : piece_pos::max_seen_count;
}
if (m_dirty) return;
int new_priority = p.priority(this);
if (prev_priority == new_priority) return;
@ -1013,6 +1020,10 @@ namespace libtorrent @@ -1013,6 +1020,10 @@ namespace libtorrent
, end(m_piece_map.end()); i != end; ++i)
{
++i->peer_count;
if( i->peer_count > i->max_seen ) {
i->max_seen = (i->peer_count <= piece_pos::max_seen_count)
? i->peer_count : piece_pos::max_seen_count;
}
}
m_dirty = true;
@ -1068,6 +1079,10 @@ namespace libtorrent @@ -1068,6 +1079,10 @@ namespace libtorrent
#endif
++m_piece_map[index].peer_count;
if( m_piece_map[index].peer_count > m_piece_map[index].max_seen ) {
m_piece_map[index].max_seen = (m_piece_map[index].peer_count <= piece_pos::max_seen_count)
? m_piece_map[index].peer_count : piece_pos::max_seen_count;
}
updated = true;
}
}
@ -1449,6 +1464,26 @@ namespace libtorrent @@ -1449,6 +1464,26 @@ namespace libtorrent
}
}
void piece_picker::set_piece_max_seen(int index, int new_piece_max_seen)
{
#ifdef TORRENT_EXPENSIVE_INVARIANT_CHECKS
TORRENT_PIECE_PICKER_INVARIANT_CHECK;
#endif
TORRENT_ASSERT(new_piece_max_seen >= 0);
TORRENT_ASSERT(index >= 0);
TORRENT_ASSERT(index < (int)m_piece_map.size());
m_piece_map[index].max_seen = new_piece_max_seen < piece_pos::max_seen_count ?
new_piece_max_seen : piece_pos::max_seen_count;
}
int piece_picker::piece_max_seen(int index) const
{
TORRENT_ASSERT(index >= 0);
TORRENT_ASSERT(index < (int)m_piece_map.size());
return m_piece_map[index].max_seen;
}
// ============ start deprecation ==============
void piece_picker::filtered_pieces(std::vector<bool>& mask) const
@ -2339,6 +2374,17 @@ namespace libtorrent @@ -2339,6 +2374,17 @@ namespace libtorrent
*j = i->peer_count + m_seeds;
}
void piece_picker::get_max_seen(std::vector<int>& max_seen) const
{
TORRENT_PIECE_PICKER_INVARIANT_CHECK;
max_seen.resize(m_piece_map.size());
std::vector<int>::iterator j = max_seen.begin();
for (std::vector<piece_pos>::const_iterator i = m_piece_map.begin()
, end(m_piece_map.end()); i != end; ++i, ++j)
*j = i->max_seen;
}
bool piece_picker::mark_as_writing(piece_block block, void* peer)
{
#ifdef TORRENT_EXPENSIVE_INVARIANT_CHECKS

29
libtorrent/src/torrent.cpp

@ -3830,6 +3830,20 @@ namespace libtorrent @@ -3830,6 +3830,20 @@ namespace libtorrent
m_picker->get_availability(avail);
}
void torrent::piece_max_seen(std::vector<int>& max_seen) const
{
INVARIANT_CHECK;
TORRENT_ASSERT(valid_metadata());
if (!has_picker())
{
max_seen.clear();
return;
}
m_picker->get_max_seen(max_seen);
}
void torrent::set_piece_priority(int index, int priority)
{
// INVARIANT_CHECK;
@ -5043,6 +5057,15 @@ namespace libtorrent @@ -5043,6 +5057,15 @@ namespace libtorrent
m_policy.recalculate_connect_candidates();
}
lazy_entry const* piece_max_seen = rd.dict_find_string("piece_max_seen");
if (piece_max_seen && piece_max_seen->string_length()
== m_torrent_file->num_pieces())
{
char const* p = piece_max_seen->string_ptr();
for (int i = 0; i < piece_max_seen->string_length(); ++i)
m_picker->set_piece_max_seen(i, p[i]);
}
if (!m_override_resume_data)
{
int auto_managed_ = rd.dict_find_int_value("auto_managed", -1);
@ -5385,6 +5408,12 @@ namespace libtorrent @@ -5385,6 +5408,12 @@ namespace libtorrent
piece_priority[i] = m_picker->piece_priority(i);
}
// write piece max_seen
entry::string_type& piece_max_seen = ret["piece_max_seen"].string();
piece_max_seen.resize(m_torrent_file->num_pieces());
for (int i = 0, end(piece_max_seen.size()); i < end; ++i)
piece_max_seen[i] = m_picker->piece_max_seen(i);
// write file priorities
entry::list_type& file_priority = ret["file_priority"].list();
file_priority.clear();

6
libtorrent/src/torrent_handle.cpp

@ -555,6 +555,12 @@ namespace libtorrent @@ -555,6 +555,12 @@ namespace libtorrent
TORRENT_SYNC_CALL1(piece_availability, boost::ref(avail));
}
void torrent_handle::piece_max_seen(std::vector<int>& max_seen) const
{
INVARIANT_CHECK;
TORRENT_SYNC_CALL1(piece_max_seen, boost::ref(max_seen));
}
void torrent_handle::piece_priority(int index, int priority) const
{
INVARIANT_CHECK;

2
src/bitcoinrpc.cpp

@ -280,6 +280,7 @@ static const CRPCCommand vRPCCommands[] = @@ -280,6 +280,7 @@ static const CRPCCommand vRPCCommands[] =
{ "newgroupdescription", &newgroupdescription, false, true, false },
{ "leavegroup", &leavegroup, false, true, false },
{ "getpieceavailability", &getpieceavailability, false, true, true },
{ "getpiecemaxseen", &getpiecemaxseen, false, true, true },
};
CRPCTable::CRPCTable()
@ -1346,6 +1347,7 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector<std::stri @@ -1346,6 +1347,7 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector<std::stri
if (strMethod == "newgroupinvite" && n > 3) ConvertTo<Array>(params[3]);
if (strMethod == "newgroupdescription" && n > 1) ConvertTo<boost::int64_t>(params[1]);
if (strMethod == "getpieceavailability" && n > 1) ConvertTo<boost::int64_t>(params[1]);
if (strMethod == "getpiecemaxseen" && n > 1) ConvertTo<boost::int64_t>(params[1]);
return params;
}

1
src/bitcoinrpc.h

@ -233,5 +233,6 @@ extern json_spirit::Value newgroupinvite(const json_spirit::Array& params, bool @@ -233,5 +233,6 @@ extern json_spirit::Value newgroupinvite(const json_spirit::Array& params, bool
extern json_spirit::Value newgroupdescription(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value leavegroup(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getpieceavailability(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getpiecemaxseen(const json_spirit::Array& params, bool fHelp);
#endif

20
src/twister.cpp

@ -3824,3 +3824,23 @@ Value getpieceavailability(const Array& params, bool fHelp) @@ -3824,3 +3824,23 @@ Value getpieceavailability(const Array& params, bool fHelp)
return avail.size() > k ? avail.at(k) : 0;
}
Value getpiecemaxseen(const Array& params, bool fHelp)
{
if (fHelp || params.size() != 2 )
throw runtime_error(
"getpiecemaxseen <username> <k>'\n"
"Get piece max seen availability (max peer count for this piece)");
EnsureWalletIsUnlocked();
string strUsername = params[0].get_str();
int k = params[1].get_int();
torrent_handle h = getTorrentUser(strUsername);
std::vector<int> max_seen;
h.piece_max_seen(max_seen);
return max_seen.size() > k ? max_seen.at(k) : 0;
}

Loading…
Cancel
Save