improve TCP/uTP mixed mode algorithm by only taking peers into account that have outstanding requests (and want to send or expect to receive). Also throttle upload and download independently

This commit is contained in:
Arvid Norberg
2011-10-11 05:00:35 +00:00
parent 2741563711
commit 8aed4eaa7f

View File

@@ -2694,34 +2694,40 @@ namespace aux {
break; break;
case session_settings::peer_proportional: case session_settings::peer_proportional:
{ {
int num_tcp_peers = 0; int num_peers[2][2] = {{0, 0}, {0, 0}};
int num_peers = 0;
for (connection_map::iterator i = m_connections.begin() for (connection_map::iterator i = m_connections.begin()
, end(m_connections.end());i != end; ++i) , end(m_connections.end());i != end; ++i)
{ {
peer_connection& p = *(*i); peer_connection& p = *(*i);
if (p.in_handshake()) continue; if (p.in_handshake()) continue;
if (!p.get_socket()->get<utp_stream>()) ++num_tcp_peers; int protocol = 0;
++num_peers; if (p.get_socket()->get<utp_stream>()) protocol = 1;
if (p.download_queue().size() + p.request_queue().size() > 0)
++num_peers[protocol][peer_connection::download_channel];
if (p.upload_queue().size() > 0)
++num_peers[protocol][peer_connection::upload_channel];
} }
if (num_peers == 0) bandwidth_channel* tcp_channel[] = { &m_tcp_upload_channel, &m_tcp_download_channel };
int stat_rate[] = {m_stat.upload_rate(), m_stat.download_rate() };
for (int i = 0; i < 2; ++i)
{ {
m_tcp_upload_channel.throttle(0); // if there are no uploading uTP peers, don't throttle TCP up
m_tcp_download_channel.throttle(0); if (num_peers[1][i] == 0)
} {
else tcp_channel[i]->throttle(0);
{ }
if (num_tcp_peers == 0) num_tcp_peers = 1; else
// these are 64 bits since they are multiplied by the number {
// of peers, which otherwise might overflow an int if (num_peers[0][i] == 0) num_peers[0][i] = 1;
boost::uint64_t upload_rate = (std::max)(m_stat.upload_rate(), 20000); int total_peers = num_peers[0][i] + num_peers[1][i];
boost::uint64_t download_rate = (std::max)(m_stat.download_rate(), 20000); // this are 64 bits since it's multiplied by the number
if (m_upload_channel.throttle()) upload_rate = m_upload_channel.throttle(); // of peers, which otherwise might overflow an int
if (m_download_channel.throttle()) download_rate = m_download_channel.throttle(); boost::uint64_t rate = (std::max)(stat_rate[i], 20000);
tcp_channel[i]->throttle(int(rate * num_peers[0][i] / total_peers));
m_tcp_upload_channel.throttle(int(upload_rate * num_tcp_peers / num_peers)); }
m_tcp_download_channel.throttle(int(download_rate * num_tcp_peers / num_peers));
} }
} }
break; break;