added read cache. Not fully configurable yet

This commit is contained in:
Arvid Norberg
2008-02-22 04:11:04 +00:00
parent bf7552a4cd
commit ef9ef674d5
5 changed files with 486 additions and 79 deletions

View File

@@ -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