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
{
typedef boost::uint32_t peer_class_t;
typedef boost::uint8_t peer_class_t;
struct peer_class_info
{
// ``ignore_unchoke_slots`` determines whether peers should always unchoke a peer,
// regardless of the choking algorithm, or if it should honor the unchoke slot limits.
// It's used for local peers by default. If *any* of the peer classes a peer belongs to
// has this set to true, that peer will be unchoked at all times.
// ``ignore_unchoke_slots`` determines whether peers should always
// unchoke a peer, regardless of the choking algorithm, or if it should
// honor the unchoke slot limits. It's used for local peers by default.
// 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;
// adjusts the connection limit (global and per torrent) that
// applies to this peer class. By default, local peers are allowed to exceed the normal
// connection limit for instance. This is specified as a percent factor. 100 makes
// the peer class apply normally to the limit. 200 means as long as there are fewer
// connections than twice the limit, we accept this peer. This factor applies both to
// the global connection limit and the per-torrent limit. Note that if not used carefully
// one peer class can potentially completely starve out all other over time.
// adjusts the connection limit (global and per torrent) that applies to
// this peer class. By default, local peers are allowed to exceed the
// normal connection limit for instance. This is specified as a percent
// factor. 100 makes the peer class apply normally to the limit. 200
// means as long as there are fewer connections than twice the limit, we
// accept this peer. This factor applies both to the global connection
// 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;
// not used by libtorrent. It's intended as a potentially user-facing identifier
// of this peer class.
// not used by libtorrent. It's intended as a potentially user-facing
// identifier of this peer class.
std::string label;
// transfer rates limits for the whole peer class.
// They are specified in bytes per second and apply to the sum of all peers that are
// members of this class.
// transfer rates limits for the whole peer class. They are specified in
// bytes per second and apply to the sum of all peers that are members of
// this class.
int upload_limit;
int download_limit;
// relative priorities used by the
// bandwidth allocator in the rate limiter. If no rate limits are in use, the priority
// is not used either. Priorities start at 1 (0 is not a valid priority) and may not
// relative priorities used by the bandwidth allocator in the rate
// limiter. If no rate limits are in use, the priority is not used
// either. Priorities start at 1 (0 is not a valid priority) and may not
// exceed 255.
int upload_priority;
int download_priority;
@ -137,7 +139,7 @@ namespace libtorrent
std::vector<boost::intrusive_ptr<peer_class> > m_peer_classes;
// 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
#include "libtorrent/peer_class.hpp"
#include <vector>
#include <boost/array.hpp>
namespace libtorrent {
@ -42,24 +42,27 @@ namespace libtorrent {
// to it. Most notably, peer connections and torrents derive from this.
struct peer_class_set
{
peer_class_set() : m_size(0) {}
void add_class(peer_class_pool& pool, peer_class_t c);
bool has_class(peer_class_t c) const;
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
{
TORRENT_ASSERT(i >= 0 && i < int(m_class.size()));
TORRENT_ASSERT(i >= 0 && i < int(m_size));
return m_class[i];
}
private:
// if this object belongs to any peer-class, this
// vector contains all class IDs. Each ID refers
// to a an entry in m_ses.m_peer_classes which
// holds the metadata about the class. Classes
// affect bandwidth limits among other things
std::vector<peer_class_t> m_class;
// the number of elements used in the m_class array
boost::uint8_t m_size;
// if this object belongs to any peer-class, this vector contains all
// class IDs. Each ID refers to a an entry in m_ses.m_peer_classes which
// 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.hpp"
#include <vector>
#include <algorithm> // for_find
#include <algorithm> // for find
namespace libtorrent
{
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;
m_class.push_back(c);
if (std::find(m_class.begin(), m_class.begin() + m_size, 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);
++m_size;
}
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)
{
std::vector<peer_class_t>::iterator i = std::find(m_class.begin(), m_class.end(), c);
if (i == m_class.end()) return;
m_class.erase(i);
boost::array<peer_class_t, 15>::iterator i = std::find(m_class.begin()
, m_class.begin() + m_size, c);
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);
}
}