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);
}
// --------------------------