added disk cache for write operations

This commit is contained in:
Arvid Norberg
2008-02-08 10:22:05 +00:00
parent 196f9c3544
commit 8cf0510144
18 changed files with 645 additions and 166 deletions

View File

@@ -399,19 +399,21 @@ namespace libtorrent
// when they are destructed.
file_pool m_files;
// this is where all active sockets are stored.
// the selector can sleep while there's no activity on
// them
io_service m_io_service;
// handles disk io requests asynchronously
// peers have pointers into the disk buffer
// pool, and must be destructed before this
// object. The disk thread relies on the file
// pool object, and must be destructed before
// m_files.
// m_files. The disk io thread posts completion
// events to the io service, and needs to be
// constructed after it.
disk_io_thread m_disk_thread;
// this is where all active sockets are stored.
// the selector can sleep while there's no activity on
// them
io_service m_io_service;
// this is a list of half-open tcp connections
// (only outgoing connections)
// this has to be one of the last

View File

@@ -44,11 +44,19 @@ POSSIBILITY OF SUCH DAMAGE.
#include <boost/bind.hpp>
#include <boost/pool/pool.hpp>
#include <boost/noncopyable.hpp>
#include <boost/shared_array.hpp>
#include "libtorrent/config.hpp"
namespace libtorrent
{
struct cached_piece_info
{
int piece;
std::vector<bool> blocks;
ptime last_write;
};
struct disk_io_job
{
disk_io_job()
@@ -91,11 +99,22 @@ namespace libtorrent
boost::function<void(int, disk_io_job const&)> callback;
};
struct cache_status
{
// the number of 16kB blocks written
size_type blocks_written;
// the number of write operations used
size_type writes;
// (blocks_written - writes) / blocks_written represents the
// "cache hit" ratio in the write cache
int write_size;
};
// this is a singleton consisting of the thread and a queue
// of disk io jobs
struct disk_io_thread : boost::noncopyable
{
disk_io_thread(int block_size = 16 * 1024);
disk_io_thread(asio::io_service& ios, int block_size = 16 * 1024);
~disk_io_thread();
#ifdef TORRENT_STATS
@@ -122,6 +141,12 @@ namespace libtorrent
size_type queue_buffer_size() const
{ return m_queue_buffer_size; }
void get_cache_info(sha1_hash const& ih
, std::vector<cached_piece_info>& ret) const;
cache_status status() const;
void set_cache_size(int s);
void operator()();
char* allocate_buffer();
@@ -130,13 +155,43 @@ namespace libtorrent
private:
typedef boost::recursive_mutex mutex_t;
struct cached_piece_entry
{
int piece;
// storage this piece belongs to
boost::intrusive_ptr<piece_manager> storage;
// the last time a block was writting to this piece
ptime last_write;
// the number of blocks in the cache for this piece
int num_blocks;
// the pointers to the block data
boost::shared_array<char*> blocks;
};
char* allocate_buffer(mutex_t::scoped_lock& l);
void free_buffer(char* buf, mutex_t::scoped_lock& l);
std::vector<cached_piece_entry>::iterator find_cached_piece(
disk_io_job const& j, mutex_t::scoped_lock& l);
void flush_oldest_piece(mutex_t::scoped_lock& l);
void flush_and_remove(std::vector<cached_piece_entry>::iterator i, mutex_t::scoped_lock& l);
void flush(std::vector<cached_piece_entry>::iterator i, mutex_t::scoped_lock& l);
void cache_block(disk_io_job& j, mutex_t::scoped_lock& l);
mutable mutex_t m_mutex;
boost::condition m_signal;
bool m_abort;
std::deque<disk_io_job> m_jobs;
size_type m_queue_buffer_size;
std::vector<cached_piece_entry> m_pieces;
int m_num_cached_blocks;
// in (16kB) blocks
int m_cache_size;
// memory pool for read and write operations
// and disk cache
boost::pool<> m_pool;
#ifndef NDEBUG
@@ -151,6 +206,11 @@ namespace libtorrent
int m_allocations;
#endif
size_type m_writes;
size_type m_blocks_written;
asio::io_service& m_ios;
// thread for performing blocking disk io operations
boost::thread m_disk_io_thread;
};

View File

@@ -61,6 +61,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/version.hpp"
#include "libtorrent/fingerprint.hpp"
#include "libtorrent/time.hpp"
#include "libtorrent/disk_io_thread.hpp"
#include "libtorrent/storage.hpp"
@@ -176,6 +177,10 @@ namespace libtorrent
session_proxy abort() { return session_proxy(m_impl); }
session_status status() const;
cache_status get_cache_status() const;
void get_cache_info(sha1_hash const& ih
, std::vector<cached_piece_info>& ret) const;
#ifndef TORRENT_DISABLE_DHT
void start_dht(entry const& startup_state = entry());

View File

@@ -120,6 +120,7 @@ namespace libtorrent
, upnp_ignore_nonrouters(true)
, send_buffer_watermark(80 * 1024)
, auto_upload_slots(true)
, cache_size(128)
{}
// this is the user agent that will be sent to the tracker
@@ -317,6 +318,10 @@ namespace libtorrent
// upload slots are never automatically decreased below
// the manual settings, through max_uploads.
bool auto_upload_slots;
// the disk write cache, specified in 16 KiB blocks.
// defaul is 128 (= 2 MB)
int cache_size;
};
#ifndef TORRENT_DISABLE_DHT

View File

@@ -191,6 +191,8 @@ namespace libtorrent
~piece_manager();
torrent_info const* info() const { return m_info.get(); }
bool check_fastresume(aux::piece_checker_data& d
, std::vector<bool>& pieces, int& num_pieces, storage_mode_t storage_mode
, std::string& error_msg);