added read cache. Not fully configurable yet
This commit is contained in:
@@ -45,6 +45,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <boost/pool/pool.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/shared_array.hpp>
|
||||
#include <deque>
|
||||
#include "libtorrent/config.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
@@ -54,7 +55,7 @@ namespace libtorrent
|
||||
{
|
||||
int piece;
|
||||
std::vector<bool> blocks;
|
||||
ptime last_write;
|
||||
ptime last_use;
|
||||
};
|
||||
|
||||
struct disk_io_job
|
||||
@@ -101,13 +102,36 @@ namespace libtorrent
|
||||
|
||||
struct cache_status
|
||||
{
|
||||
cache_status()
|
||||
: blocks_written(0)
|
||||
, writes(0)
|
||||
, blocks_read(0)
|
||||
, blocks_read_hit(0)
|
||||
, reads(0)
|
||||
, cache_size(0)
|
||||
, read_cache_size(0)
|
||||
{}
|
||||
|
||||
// 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;
|
||||
// the number of blocks read
|
||||
|
||||
// the number of blocks passed back to the bittorrent engine
|
||||
size_type blocks_read;
|
||||
// the number of blocks that was just copied from the read cache
|
||||
size_type blocks_read_hit;
|
||||
// the number of read operations used
|
||||
size_type reads;
|
||||
|
||||
// the number of blocks in the cache (both read and write)
|
||||
int cache_size;
|
||||
|
||||
// the number of blocks in the cache used for read cache
|
||||
int read_cache_size;
|
||||
};
|
||||
|
||||
// this is a singleton consisting of the thread and a queue
|
||||
@@ -153,6 +177,10 @@ namespace libtorrent
|
||||
char* allocate_buffer();
|
||||
void free_buffer(char* buf);
|
||||
|
||||
#ifndef NDEBUG
|
||||
void check_invariant() const;
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
typedef boost::recursive_mutex mutex_t;
|
||||
@@ -163,7 +191,7 @@ namespace libtorrent
|
||||
// storage this piece belongs to
|
||||
boost::intrusive_ptr<piece_manager> storage;
|
||||
// the last time a block was writting to this piece
|
||||
ptime last_write;
|
||||
ptime last_use;
|
||||
// the number of blocks in the cache for this piece
|
||||
int num_blocks;
|
||||
// the pointers to the block data
|
||||
@@ -173,33 +201,70 @@ namespace libtorrent
|
||||
char* allocate_buffer(mutex_t::scoped_lock& l);
|
||||
void free_buffer(char* buf, mutex_t::scoped_lock& l);
|
||||
|
||||
// cache operations
|
||||
std::vector<cached_piece_entry>::iterator find_cached_piece(
|
||||
disk_io_job const& j, mutex_t::scoped_lock& l);
|
||||
std::vector<cached_piece_entry>& cache, disk_io_job const& j
|
||||
, mutex_t::scoped_lock& l);
|
||||
|
||||
// write cache operations
|
||||
void flush_oldest_piece(mutex_t::scoped_lock& l);
|
||||
void flush_expired_pieces(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);
|
||||
|
||||
// read cache operations
|
||||
bool clear_oldest_read_piece(mutex_t::scoped_lock& l);
|
||||
int read_into_piece(cached_piece_entry& p, int start_block, mutex_t::scoped_lock& l);
|
||||
int cache_read_block(disk_io_job const& j, mutex_t::scoped_lock& l);
|
||||
void free_piece(cached_piece_entry& p, mutex_t::scoped_lock& l);
|
||||
bool make_room(int num_blocks, mutex_t::scoped_lock& l);
|
||||
int try_read_from_cache(disk_io_job const& 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;
|
||||
|
||||
// write cache
|
||||
std::vector<cached_piece_entry> m_pieces;
|
||||
|
||||
// read cache
|
||||
std::vector<cached_piece_entry> m_read_pieces;
|
||||
|
||||
// total number of blocks in use by both the read
|
||||
// and the write cache. This is not supposed to
|
||||
// exceed m_cache_size
|
||||
cache_status m_cache_stats;
|
||||
int m_num_cached_blocks;
|
||||
|
||||
// in (16kB) blocks
|
||||
int m_cache_size;
|
||||
|
||||
// expiration time of cache entries in seconds
|
||||
int m_cache_expiry;
|
||||
|
||||
// if set to true, each piece flush will allocate
|
||||
// one piece worth of temporary memory on the heap
|
||||
// and copy the block data into it, and then perform
|
||||
// a single write operation from that buffer.
|
||||
// if memory is constrained, that temporary buffer
|
||||
// might is avoided by setting this to false.
|
||||
// in case the allocation fails, the piece flush
|
||||
// falls back to writing each block separately.
|
||||
bool m_coalesce_writes;
|
||||
bool m_coalesce_reads;
|
||||
bool m_use_read_cache;
|
||||
|
||||
// memory pool for read and write operations
|
||||
// and disk cache
|
||||
boost::pool<> m_pool;
|
||||
|
||||
#ifndef NDEBUG
|
||||
// number of bytes per block. The BitTorrent
|
||||
// protocol defines the block size to 16 KiB.
|
||||
int m_block_size;
|
||||
#ifndef NDEBUG
|
||||
disk_io_job m_current;
|
||||
#endif
|
||||
|
||||
|
Reference in New Issue
Block a user