optimize peer classes a bit

This commit is contained in:
Arvid Norberg 2014-09-17 07:23:41 +00:00
parent 7e69239991
commit c471bcb49f
3 changed files with 57 additions and 37 deletions

View File

@ -44,38 +44,40 @@ POSSIBILITY OF SUCH DAMAGE.
namespace libtorrent namespace libtorrent
{ {
typedef boost::uint32_t peer_class_t; typedef boost::uint8_t peer_class_t;
struct peer_class_info struct peer_class_info
{ {
// ``ignore_unchoke_slots`` determines whether peers should always unchoke a peer, // ``ignore_unchoke_slots`` determines whether peers should always
// regardless of the choking algorithm, or if it should honor the unchoke slot limits. // unchoke a peer, regardless of the choking algorithm, or if it should
// It's used for local peers by default. If *any* of the peer classes a peer belongs to // honor the unchoke slot limits. It's used for local peers by default.
// has this set to true, that peer will be unchoked at all times. // If *any* of the peer classes a peer belongs to has this set to true,
// that peer will be unchoked at all times.
bool ignore_unchoke_slots; bool ignore_unchoke_slots;
// adjusts the connection limit (global and per torrent) that // adjusts the connection limit (global and per torrent) that applies to
// applies to this peer class. By default, local peers are allowed to exceed the normal // this peer class. By default, local peers are allowed to exceed the
// connection limit for instance. This is specified as a percent factor. 100 makes // normal connection limit for instance. This is specified as a percent
// the peer class apply normally to the limit. 200 means as long as there are fewer // factor. 100 makes the peer class apply normally to the limit. 200
// connections than twice the limit, we accept this peer. This factor applies both to // means as long as there are fewer connections than twice the limit, we
// the global connection limit and the per-torrent limit. Note that if not used carefully // accept this peer. This factor applies both to the global connection
// one peer class can potentially completely starve out all other over time. // limit and the per-torrent limit. Note that if not used carefully one
// peer class can potentially completely starve out all other over time.
int connection_limit_factor; int connection_limit_factor;
// not used by libtorrent. It's intended as a potentially user-facing identifier // not used by libtorrent. It's intended as a potentially user-facing
// of this peer class. // identifier of this peer class.
std::string label; std::string label;
// transfer rates limits for the whole peer class. // transfer rates limits for the whole peer class. They are specified in
// They are specified in bytes per second and apply to the sum of all peers that are // bytes per second and apply to the sum of all peers that are members of
// members of this class. // this class.
int upload_limit; int upload_limit;
int download_limit; int download_limit;
// relative priorities used by the // relative priorities used by the bandwidth allocator in the rate
// bandwidth allocator in the rate limiter. If no rate limits are in use, the priority // limiter. If no rate limits are in use, the priority is not used
// is not used either. Priorities start at 1 (0 is not a valid priority) and may not // either. Priorities start at 1 (0 is not a valid priority) and may not
// exceed 255. // exceed 255.
int upload_priority; int upload_priority;
int download_priority; int download_priority;
@ -137,7 +139,7 @@ namespace libtorrent
std::vector<boost::intrusive_ptr<peer_class> > m_peer_classes; std::vector<boost::intrusive_ptr<peer_class> > m_peer_classes;
// indices in m_peer_classes that are no longer used // indices in m_peer_classes that are no longer used
std::vector<int> m_free_list; std::vector<peer_class_t> m_free_list;
}; };
} }

View File

@ -34,7 +34,7 @@ POSSIBILITY OF SUCH DAMAGE.
#define TORRENT_PEER_CLASS_SET_HPP_INCLUDED #define TORRENT_PEER_CLASS_SET_HPP_INCLUDED
#include "libtorrent/peer_class.hpp" #include "libtorrent/peer_class.hpp"
#include <vector> #include <boost/array.hpp>
namespace libtorrent { namespace libtorrent {
@ -42,24 +42,27 @@ namespace libtorrent {
// to it. Most notably, peer connections and torrents derive from this. // to it. Most notably, peer connections and torrents derive from this.
struct peer_class_set struct peer_class_set
{ {
peer_class_set() : m_size(0) {}
void add_class(peer_class_pool& pool, peer_class_t c); void add_class(peer_class_pool& pool, peer_class_t c);
bool has_class(peer_class_t c) const; bool has_class(peer_class_t c) const;
void remove_class(peer_class_pool& pool, peer_class_t c); void remove_class(peer_class_pool& pool, peer_class_t c);
int num_classes() const { return m_class.size(); } int num_classes() const { return m_size; }
peer_class_t class_at(int i) const peer_class_t class_at(int i) const
{ {
TORRENT_ASSERT(i >= 0 && i < int(m_class.size())); TORRENT_ASSERT(i >= 0 && i < int(m_size));
return m_class[i]; return m_class[i];
} }
private: private:
// if this object belongs to any peer-class, this // the number of elements used in the m_class array
// vector contains all class IDs. Each ID refers boost::uint8_t m_size;
// to a an entry in m_ses.m_peer_classes which
// holds the metadata about the class. Classes // if this object belongs to any peer-class, this vector contains all
// affect bandwidth limits among other things // class IDs. Each ID refers to a an entry in m_ses.m_peer_classes which
std::vector<peer_class_t> m_class; // holds the metadata about the class. Classes affect bandwidth limits
// among other things
boost::array<peer_class_t, 15> m_class;
}; };
} }

View File

@ -33,27 +33,42 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/peer_class_set.hpp" #include "libtorrent/peer_class_set.hpp"
#include "libtorrent/peer_class.hpp" #include "libtorrent/peer_class.hpp"
#include <vector> #include <vector>
#include <algorithm> // for_find #include <algorithm> // for find
namespace libtorrent namespace libtorrent
{ {
void peer_class_set::add_class(peer_class_pool& pool, peer_class_t c) void peer_class_set::add_class(peer_class_pool& pool, peer_class_t c)
{ {
if (std::find(m_class.begin(), m_class.end(), c) != m_class.end()) return; if (std::find(m_class.begin(), m_class.begin() + m_size, c)
m_class.push_back(c); != m_class.begin() + m_size) return;
if (m_size >= m_class.size() - 1)
{
assert(false);
return;
}
m_class[m_size] = c;
pool.incref(c); pool.incref(c);
++m_size;
} }
bool peer_class_set::has_class(peer_class_t c) const bool peer_class_set::has_class(peer_class_t c) const
{ {
return std::find(m_class.begin(), m_class.end(), c) != m_class.end(); return std::find(m_class.begin(), m_class.begin() + m_size, c)
!= m_class.begin() + m_size;
} }
void peer_class_set::remove_class(peer_class_pool& pool, peer_class_t c) void peer_class_set::remove_class(peer_class_pool& pool, peer_class_t c)
{ {
std::vector<peer_class_t>::iterator i = std::find(m_class.begin(), m_class.end(), c); boost::array<peer_class_t, 15>::iterator i = std::find(m_class.begin()
if (i == m_class.end()) return; , m_class.begin() + m_size, c);
m_class.erase(i); int idx = i - m_class.begin();
if (idx == m_size) return; // not found
if (idx < m_size - 1)
{
// place the last element in the slot of the erased one
m_class[idx] = m_class[m_size - 1];
}
--m_size;
pool.decref(c); pool.decref(c);
} }
} }