receive buffer optimization. added receive_buffer_size and used_receive_buffer to peer_info. changed plugin api to make use of new disk_buffer_holder type

This commit is contained in:
Arvid Norberg
2008-04-10 10:03:23 +00:00
parent 5f35d170b0
commit 093d912e9a
25 changed files with 503 additions and 86 deletions

View File

@@ -10,6 +10,7 @@ libtorrent/buffer.hpp \
libtorrent/connection_queue.hpp \
libtorrent/config.hpp \
libtorrent/debug.hpp \
libtorrent/disk_buffer_holder.hpp \
libtorrent/disk_io_thread.hpp \
libtorrent/entry.hpp \
libtorrent/enum_net.hpp \

View File

@@ -334,6 +334,8 @@ namespace libtorrent
std::pair<char*, int> allocate_buffer(int size);
void free_buffer(char* buf, int size);
char* allocate_disk_buffer();
void free_disk_buffer(char* buf);
void set_external_address(address const& ip);

View File

@@ -210,7 +210,7 @@ namespace libtorrent
void write_cancel(peer_request const& r);
void write_bitfield(std::vector<bool> const& bitfield);
void write_have(int index);
void write_piece(peer_request const& r, char* buffer);
void write_piece(peer_request const& r, disk_buffer_holder& buffer);
void write_handshake();
#ifndef TORRENT_DISABLE_EXTENSIONS
void write_extensions();

View File

@@ -44,6 +44,11 @@ class buffer
public:
struct interval
{
interval()
: begin(0)
, end(0)
{}
interval(char* begin, char* end)
: begin(begin)
, end(end)

View File

@@ -0,0 +1,59 @@
/*
Copyright (c) 2008, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TORRENT_DISK_BUFFER_HOLDER_HPP_INCLUDED
#define TORRENT_DISK_BUFFER_HOLDER_HPP_INCLUDED
#include "libtorrent/config.hpp"
namespace libtorrent
{
namespace aux { class session_impl; }
struct TORRENT_EXPORT disk_buffer_holder
{
disk_buffer_holder(aux::session_impl& ses, char* buf)
: m_ses(ses), m_buf(buf) {}
~disk_buffer_holder();
char* release();
char* buffer() const { return m_buf; }
private:
aux::session_impl& m_ses;
char* m_buf;
};
}
#endif

View File

@@ -174,6 +174,10 @@ namespace libtorrent
void operator()();
#ifndef NDEBUG
bool is_disk_buffer(char* buffer) const;
#endif
char* allocate_buffer();
void free_buffer(char* buf);

View File

@@ -56,6 +56,7 @@ namespace libtorrent
struct peer_request;
class peer_connection;
class entry;
struct disk_buffer_holder;
struct TORRENT_EXPORT torrent_plugin
{
@@ -143,7 +144,7 @@ namespace libtorrent
virtual bool on_request(peer_request const& req)
{ return false; }
virtual bool on_piece(peer_request const& piece, char const* data)
virtual bool on_piece(peer_request const& piece, disk_buffer_holder& data)
{ return false; }
virtual bool on_cancel(peer_request const& req)

View File

@@ -75,6 +75,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/intrusive_ptr_base.hpp"
#include "libtorrent/assert.hpp"
#include "libtorrent/chained_buffer.hpp"
#include "libtorrent/disk_buffer_holder.hpp"
namespace libtorrent
{
@@ -321,6 +322,7 @@ namespace libtorrent
void incoming_have(int piece_index);
void incoming_bitfield(std::vector<bool> const& bitfield);
void incoming_request(peer_request const& r);
void incoming_piece(peer_request const& p, disk_buffer_holder& data);
void incoming_piece(peer_request const& p, char const* data);
void incoming_piece_fragment();
void incoming_cancel(peer_request const& r);
@@ -439,7 +441,7 @@ namespace libtorrent
virtual void write_cancel(peer_request const& r) = 0;
virtual void write_have(int index) = 0;
virtual void write_keepalive() = 0;
virtual void write_piece(peer_request const& r, char* buffer) = 0;
virtual void write_piece(peer_request const& r, disk_buffer_holder& buffer) = 0;
virtual void write_reject_request(peer_request const& r) = 0;
virtual void write_allow_fast(int piece) = 0;
@@ -455,10 +457,14 @@ namespace libtorrent
#ifndef TORRENT_DISABLE_ENCRYPTION
buffer::interval wr_recv_buffer()
{
TORRENT_ASSERT(m_disk_recv_buffer == 0);
TORRENT_ASSERT(m_disk_recv_buffer_size == 0);
if (m_recv_buffer.empty()) return buffer::interval(0,0);
return buffer::interval(&m_recv_buffer[0]
, &m_recv_buffer[0] + m_recv_pos);
}
std::pair<buffer::interval, buffer::interval> wr_recv_buffers(int bytes);
#endif
buffer::const_interval receive_buffer() const
@@ -468,8 +474,10 @@ namespace libtorrent
, &m_recv_buffer[0] + m_recv_pos);
}
bool allocate_disk_receive_buffer(int disk_buffer_size);
char* release_disk_receive_buffer();
bool has_disk_receive_buffer() const { return m_disk_recv_buffer; }
void cut_receive_buffer(int size, int packet_size);
void reset_recv_buffer(int packet_size);
void setup_receive();
@@ -555,6 +563,13 @@ namespace libtorrent
int m_recv_pos;
buffer m_recv_buffer;
// if this peer is receiving a piece, this
// points to a disk buffer that the data is
// read into. This eliminates a memcopy from
// the receive buffer into the disk buffer
int m_disk_recv_buffer_size;
char* m_disk_recv_buffer;
chained_buffer m_send_buffer;
// the number of bytes we are currently reading

View File

@@ -111,6 +111,9 @@ namespace libtorrent
// the number bytes that's actually used of the send buffer
int used_send_buffer;
int receive_buffer_size;
int used_receive_buffer;
// the number of failed hashes for this peer
int num_hashfails;

View File

@@ -71,6 +71,7 @@ namespace libtorrent
class session;
struct file_pool;
struct disk_io_job;
struct disk_buffer_holder;
enum storage_mode_t
{
@@ -216,7 +217,7 @@ namespace libtorrent
void async_write(
peer_request const& r
, char const* buffer
, disk_buffer_holder& buffer
, boost::function<void(int, disk_io_job const&)> const& f);
void async_hash(int piece, boost::function<void(int, disk_io_job const&)> const& f);

View File

@@ -122,7 +122,7 @@ namespace libtorrent
void write_cancel(peer_request const& r)
{ incoming_reject_request(r); }
void write_have(int index) {}
void write_piece(peer_request const& r, char* buffer) { TORRENT_ASSERT(false); }
void write_piece(peer_request const& r, disk_buffer_holder& buffer) { TORRENT_ASSERT(false); }
void write_keepalive() {}
void on_connected();
void write_reject_request(peer_request const&) {}