From a20f1a8fa0db8494f5fe873ca193559b0a0e3772 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Tue, 8 Jul 2008 00:03:08 +0000 Subject: [PATCH] keeps track of the number of requests waiting in the send buffer and adjusts bandwidht priority accordingly in the bandwidth limiter --- docs/manual.html | 3 +++ docs/manual.rst | 4 +++ examples/client_test.cpp | 5 ++-- include/libtorrent/bt_peer_connection.hpp | 2 +- include/libtorrent/peer_connection.hpp | 7 ++++- include/libtorrent/peer_info.hpp | 4 +++ src/bt_peer_connection.cpp | 6 ++--- src/peer_connection.cpp | 31 ++++++++++++++++------- src/web_peer_connection.cpp | 2 +- 9 files changed, 47 insertions(+), 17 deletions(-) diff --git a/docs/manual.html b/docs/manual.html index 9631d6fc9..3adb105e8 100644 --- a/docs/manual.html +++ b/docs/manual.html @@ -2551,6 +2551,7 @@ struct peer_info size_type load_balancing; + int requests_in_buffer; int download_queue_length; int upload_queue_length; @@ -2757,6 +2758,8 @@ and free upload that we give. Every peer gets a certain amount of free upload, b this member says how much extra free upload this peer has got. If it is a negative number it means that this was a peer from which we have got this amount of free download.

+

requests_in_buffer is the number of requests messages that are currently in the +send buffer waiting to be sent.

download_queue_length is the number of piece-requests we have sent to this peer that hasn't been answered with a piece yet.

upload_queue_length is the number of piece-requests we have received from this peer diff --git a/docs/manual.rst b/docs/manual.rst index 672a97566..9b8995e03 100644 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -2528,6 +2528,7 @@ It contains the following fields:: size_type load_balancing; + int requests_in_buffer; int download_queue_length; int upload_queue_length; @@ -2724,6 +2725,9 @@ this member says how much *extra* free upload this peer has got. If it is a nega number it means that this was a peer from which we have got this amount of free download. +``requests_in_buffer`` is the number of requests messages that are currently in the +send buffer waiting to be sent. + ``download_queue_length`` is the number of piece-requests we have sent to this peer that hasn't been answered with a piece yet. diff --git a/examples/client_test.cpp b/examples/client_test.cpp index 3d574ce62..0766b26b0 100644 --- a/examples/client_test.cpp +++ b/examples/client_test.cpp @@ -320,7 +320,7 @@ void print_peer_info(std::ostream& out, std::vector const #endif out << "down (total | peak ) up (total | peak ) sent-req recv flags source "; if (print_fails) out << "fail hshf "; - if (print_send_bufs) out << "sndb quota rcvb "; + if (print_send_bufs) out << "rq sndb quota rcvb "; if (print_timers) out << "inactive wait timeout "; out << "disk rtt "; if (print_block) out << "block-progress "; @@ -399,7 +399,8 @@ void print_peer_info(std::ostream& out, std::vector const } if (print_send_bufs) { - out << to_string(i->used_send_buffer, 6) << " ("<< add_suffix(i->send_buffer_size) << ") " + out << to_string(i->requests_in_buffer, 2) << " " + << to_string(i->used_send_buffer, 6) << " ("<< add_suffix(i->send_buffer_size) << ") " << to_string(i->send_quota, 5) << " " << to_string(i->used_receive_buffer, 6) << " ("<< add_suffix(i->receive_buffer_size) << ") "; } diff --git a/include/libtorrent/bt_peer_connection.hpp b/include/libtorrent/bt_peer_connection.hpp index c45f7cb31..a900bfc7e 100644 --- a/include/libtorrent/bt_peer_connection.hpp +++ b/include/libtorrent/bt_peer_connection.hpp @@ -275,7 +275,7 @@ public: // these functions encrypt the send buffer if m_rc4_encrypted // is true, otherwise it passes the call to the // peer_connection functions of the same names - void send_buffer(char* buf, int size); + void send_buffer(char* buf, int size, int flags = 0); buffer::interval allocate_send_buffer(int size); template void append_send_buffer(char* buffer, int size, Destructor const& destructor) diff --git a/include/libtorrent/peer_connection.hpp b/include/libtorrent/peer_connection.hpp index 8eebb113b..bfc45db5d 100644 --- a/include/libtorrent/peer_connection.hpp +++ b/include/libtorrent/peer_connection.hpp @@ -409,7 +409,8 @@ namespace libtorrent // these functions are virtual to let bt_peer_connection hook into them // and encrypt the content - virtual void send_buffer(char const* begin, int size); + enum message_type_flags { message_type_request = 1 }; + virtual void send_buffer(char const* begin, int size, int flags = 0); virtual buffer::interval allocate_send_buffer(int size); virtual void setup_send(); @@ -681,6 +682,10 @@ namespace libtorrent // downloaded from this peer std::vector m_suggested_pieces; + // a list of byte offsets inside the send buffer + // the piece requests + std::vector m_requests_in_buffer; + // the number of pieces this peer // has. Must be the same as // std::count(m_have_piece.begin(), diff --git a/include/libtorrent/peer_info.hpp b/include/libtorrent/peer_info.hpp index d447b51f8..83aa217cf 100644 --- a/include/libtorrent/peer_info.hpp +++ b/include/libtorrent/peer_info.hpp @@ -143,6 +143,10 @@ namespace libtorrent // for yet int download_queue_length; + // the number of request messages + // waiting to be sent inside the send buffer + int requests_in_buffer; + // the number of requests that is // tried to be maintained (this is // typically a function of download speed) diff --git a/src/bt_peer_connection.cpp b/src/bt_peer_connection.cpp index cf9e3bc34..dbba0e407 100644 --- a/src/bt_peer_connection.cpp +++ b/src/bt_peer_connection.cpp @@ -601,7 +601,7 @@ namespace libtorrent #endif } - void bt_peer_connection::send_buffer(char* buf, int size) + void bt_peer_connection::send_buffer(char* buf, int size, int flags) { TORRENT_ASSERT(buf); TORRENT_ASSERT(size > 0); @@ -609,7 +609,7 @@ namespace libtorrent if (m_encrypted && m_rc4_encrypted) m_RC4_handler->encrypt(buf, size); - peer_connection::send_buffer(buf, size); + peer_connection::send_buffer(buf, size, flags); } buffer::interval bt_peer_connection::allocate_send_buffer(int size) @@ -1405,7 +1405,7 @@ namespace libtorrent detail::write_int32(r.piece, ptr); // index detail::write_int32(r.start, ptr); // begin detail::write_int32(r.length, ptr); // length - send_buffer(msg, sizeof(msg)); + send_buffer(msg, sizeof(msg), message_type_request); } void bt_peer_connection::write_bitfield() diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index 6c2b2eb88..6eb64783d 100644 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -1542,8 +1542,8 @@ namespace libtorrent #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING (*m_logger) << time_now_string() - << " *** SKIPPED_PIECE [ piece: " << i->piece_index << " | " - "b: " << i->block_index << " ] ***\n"; + << " *** SKIPPED_PIECE [ piece: " << i->block.piece_index << " | " + "b: " << i->block.block_index << " ] ***\n"; #endif ++i->skipped; @@ -2401,6 +2401,7 @@ namespace libtorrent p.load_balancing = total_free_upload(); p.download_queue_length = int(download_queue().size() + m_request_queue.size()); + p.requests_in_buffer = int(m_requests_in_buffer.size()); p.target_dl_queue_length = int(desired_queue_size()); p.upload_queue_length = int(upload_queue().size()); @@ -2955,15 +2956,16 @@ namespace libtorrent TORRENT_ASSERT(t); if (m_bandwidth_limit[upload_channel].max_assignable() > 0) { -#ifdef TORRENT_VERBOSE_LOGGING - (*m_logger) << time_now_string() << " *** REQUEST_BANDWIDTH [ upload ]\n"; -#endif - + int priority = is_interesting() * 2 + m_requests_in_buffer.size(); // peers that we are not interested in are non-prioritized m_channel_state[upload_channel] = peer_info::bw_torrent; t->request_bandwidth(upload_channel, self() - , m_send_buffer.size() - , is_interesting() * 2); + , m_send_buffer.size(), priority); +#ifdef TORRENT_VERBOSE_LOGGING + (*m_logger) << time_now_string() << " *** REQUEST_BANDWIDTH [ upload prio: " + << priority << "]\n"; +#endif + } return; } @@ -3146,8 +3148,11 @@ namespace libtorrent m_packet_size = packet_size; } - void peer_connection::send_buffer(char const* buf, int size) + void peer_connection::send_buffer(char const* buf, int size, int flags) { + if (flags == message_type_request) + m_requests_in_buffer.push_back(m_send_buffer.size() + size); + int free_space = m_send_buffer.space_in_last_buffer(); if (free_space > size) free_space = size; if (free_space > 0) @@ -3491,6 +3496,14 @@ namespace libtorrent TORRENT_ASSERT(m_channel_state[upload_channel] == peer_info::bw_network); m_send_buffer.pop_front(bytes_transferred); + + for (std::vector::iterator i = m_requests_in_buffer.begin() + , end(m_requests_in_buffer.end()); i != end; ++i) + *i -= bytes_transferred; + + while (!m_requests_in_buffer.empty() + && m_requests_in_buffer.front() <= 0) + m_requests_in_buffer.erase(m_requests_in_buffer.begin()); m_channel_state[upload_channel] = peer_info::bw_idle; diff --git a/src/web_peer_connection.cpp b/src/web_peer_connection.cpp index d31094f86..ab3b0bf64 100644 --- a/src/web_peer_connection.cpp +++ b/src/web_peer_connection.cpp @@ -303,7 +303,7 @@ namespace libtorrent (*m_logger) << request << "\n"; #endif - send_buffer(request.c_str(), request.size()); + send_buffer(request.c_str(), request.size(), message_type_request); } // --------------------------