Split peer list into IPv4 and IPv6 peers. Saves 12 bytes per IPv4 peer.

This commit is contained in:
Daniel Wallin 2009-05-24 21:49:19 +00:00
parent 1c7cf9a5c8
commit 68629eb6bc
4 changed files with 204 additions and 77 deletions

View File

@ -374,9 +374,17 @@ namespace libtorrent
static int allocations;
static int allocated_bytes;
};
boost::object_pool<policy::peer, logging_allocator> m_peer_pool;
boost::object_pool<
policy::ipv4_peer, logging_allocator> m_ipv4_peer_pool;
# if TORRENT_USE_IPV6
boost::object_pool<
policy::ipv6_peer, logging_allocator> m_ipv6_peer_pool;
# endif
#else
boost::object_pool<policy::peer> m_peer_pool;
boost::object_pool<policy::ipv4_peer> m_ipv4_peer_pool;
# if TORRENT_USE_IPV6
boost::object_pool<policy::ipv6_peer> m_ipv6_peer_pool;
# endif
#endif
// this vector is used to store the block_info

View File

@ -125,25 +125,13 @@ namespace libtorrent
// 44
struct peer
{
peer(tcp::endpoint const& ip, bool connectable, int src);
peer(libtorrent::address const& a) { set_ip(tcp::endpoint(a, 0)); }
peer();
peer(boost::uint16_t port, bool connectable, int src);
size_type total_download() const;
size_type total_upload() const;
void set_ip(tcp::endpoint const& endp);
#if TORRENT_USE_IPV6
libtorrent::address address() const
{
if (is_v6_addr) return address_v6(addr.v6);
else return address_v4(addr.v4);
}
#else
libtorrent::address address() const
{ return addr; }
#endif
libtorrent::address address() const;
tcp::endpoint ip() const { return tcp::endpoint(address(), port); }
@ -187,16 +175,6 @@ namespace libtorrent
// in number of seconds since session was created
boost::uint16_t last_connected;
// the ip address this peer is or was connected on
#if TORRENT_USE_IPV6
union
{
address_v6::bytes_type v6;
address_v4::bytes_type v4;
} addr;
#else
address_v4 addr;
#endif
// the port this peer is or was connected on
boost::uint16_t port;
@ -278,6 +256,24 @@ namespace libtorrent
#endif
};
struct ipv4_peer : peer
{
ipv4_peer(tcp::endpoint const& ip, bool connectable, int src);
ipv4_peer(libtorrent::address const& a);
address_v4 addr;
};
#if TORRENT_USE_IPV6
struct ipv6_peer : peer
{
ipv6_peer(tcp::endpoint const& ip, bool connectable, int src);
ipv6_peer(libtorrent::address const& a);
address_v6::bytes_type addr;
};
#endif
int num_peers() const { return m_peers.size(); }
struct peer_ptr_compare
@ -297,17 +293,37 @@ namespace libtorrent
std::pair<iterator, iterator> find_peers(address const& a)
{
peer tmp(a);
peer_ptr_compare cmp;
#if TORRENT_USE_IPV6
if (a.is_v6())
{
ipv6_peer tmp(a);
return std::equal_range(m_peers.begin(), m_peers.end(), &tmp, cmp);
}
else
#endif
{
ipv4_peer tmp(a);
return std::equal_range(m_peers.begin(), m_peers.end(), &tmp, cmp);
}
}
std::pair<const_iterator, const_iterator> find_peers(address const& a) const
{
peer tmp(a);
peer_ptr_compare cmp;
#if TORRENT_USE_IPV6
if (a.is_v6())
{
ipv6_peer tmp(a);
return std::equal_range(m_peers.begin(), m_peers.end(), &tmp, cmp);
}
else
#endif
{
ipv4_peer tmp(a);
return std::equal_range(m_peers.begin(), m_peers.end(), &tmp, cmp);
}
}
bool connect_one_peer(int session_time);
@ -368,6 +384,46 @@ namespace libtorrent
bool m_finished;
};
inline policy::ipv4_peer::ipv4_peer(
tcp::endpoint const& ip, bool connectable, int src
)
: peer(ip.port(), connectable, src)
, addr(ip.address().to_v4())
{
is_v6_addr = false;
}
inline policy::ipv4_peer::ipv4_peer(libtorrent::address const& a)
: addr(a.to_v4())
{
is_v6_addr = false;
}
inline policy::ipv6_peer::ipv6_peer(
tcp::endpoint const& ip, bool connectable, int src
)
: peer(ip.port(), connectable, src)
, addr(ip.address().to_v6().to_bytes())
{
is_v6_addr = true;
}
inline policy::ipv6_peer::ipv6_peer(libtorrent::address const& a)
: addr(a.to_v6().to_bytes())
{
is_v6_addr = true;
}
inline libtorrent::address policy::peer::address() const
{
#if TORRENT_USE_IPV6
if (is_v6_addr)
return libtorrent::address_v6(
static_cast<policy::ipv6_peer const*>(this)->addr);
#endif
return static_cast<policy::ipv4_peer const*>(this)->addr;
}
}
#endif // TORRENT_POLICY_HPP_INCLUDED

View File

@ -411,7 +411,14 @@ namespace libtorrent
--m_num_connect_candidates;
if (m_round_robin > i - m_peers.begin()) --m_round_robin;
m_torrent->session().m_peer_pool.destroy(*i);
#if TORRENT_USE_IPV6
if ((*i)->is_v6_addr)
m_torrent->session().m_ipv6_peer_pool.destroy(
static_cast<ipv6_peer*>(*i));
else
#endif
m_torrent->session().m_ipv4_peer_pool.destroy(
static_cast<ipv4_peer*>(*i));
m_peers.erase(i);
}
@ -699,10 +706,21 @@ namespace libtorrent
}
else
{
peer tmp(c.remote().address());
peer_ptr_compare cmp;
#if TORRENT_USE_IPV6
if (c.remote().address().is_v6())
{
ipv6_peer tmp(c.remote().address());
iter = std::lower_bound(m_peers.begin(), m_peers.end()
, &tmp, cmp);
}
else
#endif
{
ipv4_peer tmp(c.remote().address());
iter = std::lower_bound(m_peers.begin(), m_peers.end()
, &tmp, cmp);
}
if (iter != m_peers.end() && (*iter)->address() == c.remote().address()) found = true;
}
@ -783,10 +801,29 @@ namespace libtorrent
}
if (m_round_robin > iter - m_peers.begin()) ++m_round_robin;
peer* p = m_torrent->session().m_peer_pool.malloc();
#if TORRENT_USE_IPV6
bool is_v6 = c.remote().address().is_v6();
#endif
peer* p =
#if TORRENT_USE_IPV6
is_v6 ? (peer*)m_torrent->session().m_ipv6_peer_pool.malloc() :
#endif
(peer*)m_torrent->session().m_ipv4_peer_pool.malloc();
if (p == 0) return false;
m_torrent->session().m_peer_pool.set_next_size(500);
new (p) peer(c.remote(), false, 0);
#if TORRENT_USE_IPV6
if (is_v6)
m_torrent->session().m_ipv6_peer_pool.set_next_size(500);
else
#endif
m_torrent->session().m_ipv4_peer_pool.set_next_size(500);
#if TORRENT_USE_IPV6
if (is_v6)
new (p) ipv6_peer(c.remote(), false, 0);
else
#endif
new (p) ipv4_peer(c.remote(), false, 0);
iter = m_peers.insert(iter, p);
i = *iter;
@ -913,10 +950,22 @@ namespace libtorrent
}
else
{
peer tmp(remote.address());
peer_ptr_compare cmp;
#if TORRENT_USE_IPV6
if (remote.address().is_v6())
{
ipv6_peer tmp(remote.address());
iter = std::lower_bound(m_peers.begin(), m_peers.end()
, &tmp, cmp);
}
else
#endif
{
ipv4_peer tmp(remote.address());
iter = std::lower_bound(m_peers.begin(), m_peers.end()
, &tmp, cmp);
}
if (iter != m_peers.end() && (*iter)->address() == remote.address()) found = true;
}
@ -933,20 +982,50 @@ namespace libtorrent
// since some peers were removed, we need to
// update the iterator to make it valid again
peer tmp(remote.address());
peer_ptr_compare cmp;
#if TORRENT_USE_IPV6
if (remote.address().is_v6())
{
ipv6_peer tmp(remote.address());
iter = std::lower_bound(m_peers.begin(), m_peers.end()
, &tmp, cmp);
}
else
#endif
{
ipv4_peer tmp(remote.address());
iter = std::lower_bound(m_peers.begin(), m_peers.end()
, &tmp, cmp);
}
}
if (m_round_robin > iter - m_peers.begin()) ++m_round_robin;
// we don't have any info about this peer.
// add a new entry
peer* p = m_torrent->session().m_peer_pool.malloc();
#if TORRENT_USE_IPV6
bool is_v6 = remote.address().is_v6();
#endif
peer* p =
#if TORRENT_USE_IPV6
is_v6 ? (peer*)m_torrent->session().m_ipv6_peer_pool.malloc() :
#endif
(peer*)m_torrent->session().m_ipv4_peer_pool.malloc();
if (p == 0) return 0;
m_torrent->session().m_peer_pool.set_next_size(500);
new (p) peer(remote, true, src);
#if TORRENT_USE_IPV6
if (is_v6)
m_torrent->session().m_ipv6_peer_pool.set_next_size(500);
else
#endif
m_torrent->session().m_ipv4_peer_pool.set_next_size(500);
#if TORRENT_USE_IPV6
if (is_v6)
new (p) ipv6_peer(remote, true, src);
else
#endif
new (p) ipv4_peer(remote, true, src);
iter = m_peers.insert(iter, p);
i = *iter;
@ -1395,7 +1474,10 @@ namespace libtorrent
}
#endif // TORRENT_DEBUG
policy::peer::peer(const tcp::endpoint& ip_, bool conn, int src)
policy::peer::peer()
{}
policy::peer::peer(boost::uint16_t port, bool conn, int src)
: prev_amount_upload(0)
, prev_amount_download(0)
, connection(0)
@ -1404,10 +1486,7 @@ namespace libtorrent
#endif
, last_optimistically_unchoked(0)
, last_connected(0)
#if !TORRENT_USE_IPV6
, addr(ip_.address().to_v4())
#endif
, port(ip_.port())
, port(port)
, hashfails(0)
, failcount(0)
, connectable(conn)
@ -1428,8 +1507,6 @@ namespace libtorrent
, added_to_dht(false)
#endif
{
set_ip(ip_);
TORRENT_ASSERT((src & 0xff) == src);
}
@ -1446,27 +1523,6 @@ namespace libtorrent
}
}
void policy::peer::set_ip(tcp::endpoint const& endp)
{
#if TORRENT_USE_IPV6
if (endp.address().is_v6())
{
is_v6_addr = true;
addr.v6 = endp.address().to_v6().to_bytes();
}
else
{
is_v6_addr = false;
addr.v4 = endp.address().to_v4().to_bytes();
}
#else
TORRENT_ASSERT(endp.address().is_v4());
addr = endp.address().to_v4();
#endif
port = endp.port();
}
size_type policy::peer::total_upload() const
{
if (connection != 0)

View File

@ -167,7 +167,10 @@ namespace aux {
, fs::path const& logpath
#endif
)
: m_peer_pool(500)
: m_ipv4_peer_pool(500)
#if TORRENT_USE_IPV6
, m_ipv6_peer_pool(500)
#endif
#ifndef TORRENT_DISABLE_POOL_ALLOCATOR
, m_send_buffers(send_buffer_size)
#endif
@ -271,10 +274,14 @@ namespace aux {
PRINT_OFFSETOF(policy::peer, connection)
PRINT_OFFSETOF(policy::peer, last_optimistically_unchoked)
PRINT_OFFSETOF(policy::peer, last_connected)
PRINT_OFFSETOF(policy::peer, addr)
PRINT_OFFSETOF(policy::peer, port)
PRINT_OFFSETOF(policy::peer, hashfails)
PRINT_SIZEOF(policy::ipv4_peer)
#if TORRENT_USE_IPV6
PRINT_SIZEOF(policy::ipv6_peer)
#endif
PRINT_SIZEOF(dht::closest_nodes_observer)
PRINT_SIZEOF(dht::find_data_observer)
PRINT_SIZEOF(dht::announce_observer)