added disk cache expiration
This commit is contained in:
parent
cecd0dfcd2
commit
6c552db68e
|
@ -2591,6 +2591,7 @@ struct session_settings
|
||||||
int send_buffer_watermark;
|
int send_buffer_watermark;
|
||||||
bool auto_upload_slots;
|
bool auto_upload_slots;
|
||||||
int cache_size;
|
int cache_size;
|
||||||
|
int cache_expiry;
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
<p><tt class="docutils literal"><span class="pre">user_agent</span></tt> this is the client identification to the tracker.
|
<p><tt class="docutils literal"><span class="pre">user_agent</span></tt> this is the client identification to the tracker.
|
||||||
|
@ -2715,6 +2716,8 @@ less than what has been set by <tt class="docutils literal"><span class="pre">se
|
||||||
current number of upload slots, see <tt class="docutils literal"><span class="pre">session_status::allowed_upload_slots</span></tt>.</p>
|
current number of upload slots, see <tt class="docutils literal"><span class="pre">session_status::allowed_upload_slots</span></tt>.</p>
|
||||||
<p><tt class="docutils literal"><span class="pre">cache_size</span></tt> is the disk write cache. It is specified in units of 16 KiB blocks.
|
<p><tt class="docutils literal"><span class="pre">cache_size</span></tt> is the disk write cache. It is specified in units of 16 KiB blocks.
|
||||||
It defaults to 128 (= 2 MB).</p>
|
It defaults to 128 (= 2 MB).</p>
|
||||||
|
<p><tt class="docutils literal"><span class="pre">cache_expiry</span></tt> is the number of seconds from the last cached write to a piece
|
||||||
|
in the write cache, to when it's forcefully flushed to disk. Default is 60 second.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<h1><a id="pe-settings" name="pe-settings">pe_settings</a></h1>
|
<h1><a id="pe-settings" name="pe-settings">pe_settings</a></h1>
|
||||||
|
|
|
@ -2580,6 +2580,7 @@ that will be sent to the tracker. The user-agent is a good way to identify your
|
||||||
int send_buffer_watermark;
|
int send_buffer_watermark;
|
||||||
bool auto_upload_slots;
|
bool auto_upload_slots;
|
||||||
int cache_size;
|
int cache_size;
|
||||||
|
int cache_expiry;
|
||||||
};
|
};
|
||||||
|
|
||||||
``user_agent`` this is the client identification to the tracker.
|
``user_agent`` this is the client identification to the tracker.
|
||||||
|
@ -2733,6 +2734,10 @@ current number of upload slots, see ``session_status::allowed_upload_slots``.
|
||||||
``cache_size`` is the disk write cache. It is specified in units of 16 KiB blocks.
|
``cache_size`` is the disk write cache. It is specified in units of 16 KiB blocks.
|
||||||
It defaults to 128 (= 2 MB).
|
It defaults to 128 (= 2 MB).
|
||||||
|
|
||||||
|
``cache_expiry`` is the number of seconds from the last cached write to a piece
|
||||||
|
in the write cache, to when it's forcefully flushed to disk. Default is 60 second.
|
||||||
|
|
||||||
|
|
||||||
pe_settings
|
pe_settings
|
||||||
===========
|
===========
|
||||||
|
|
||||||
|
|
|
@ -389,7 +389,7 @@ void print_peer_info(std::ostream& out, std::vector<libtorrent::peer_info> const
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
out << progress_bar(0.f, 15);
|
out << progress_bar(0.f, 14);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
|
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
|
||||||
|
@ -1197,7 +1197,9 @@ int main(int ac, char* av[])
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
char* piece_state[4] = {"", "slow", "medium", "fast"};
|
char* piece_state[4] = {"", "slow", "medium", "fast"};
|
||||||
out << "] " << piece_state[i->piece_state] << "\n";
|
out << "] " << piece_state[i->piece_state];
|
||||||
|
if (cp) out << (i->piece_state > 0?" | ":"") << "cache age: " << total_seconds(time_now() - cp->last_write);
|
||||||
|
out << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
out << "___________________________________\n";
|
out << "___________________________________\n";
|
||||||
|
|
|
@ -146,6 +146,7 @@ namespace libtorrent
|
||||||
|
|
||||||
cache_status status() const;
|
cache_status status() const;
|
||||||
void set_cache_size(int s);
|
void set_cache_size(int s);
|
||||||
|
void set_cache_expiry(int ex);
|
||||||
|
|
||||||
void operator()();
|
void operator()();
|
||||||
|
|
||||||
|
@ -175,6 +176,7 @@ namespace libtorrent
|
||||||
std::vector<cached_piece_entry>::iterator find_cached_piece(
|
std::vector<cached_piece_entry>::iterator find_cached_piece(
|
||||||
disk_io_job const& j, mutex_t::scoped_lock& l);
|
disk_io_job const& j, mutex_t::scoped_lock& l);
|
||||||
void flush_oldest_piece(mutex_t::scoped_lock& l);
|
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_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 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);
|
void cache_block(disk_io_job& j, mutex_t::scoped_lock& l);
|
||||||
|
@ -189,6 +191,8 @@ namespace libtorrent
|
||||||
int m_num_cached_blocks;
|
int m_num_cached_blocks;
|
||||||
// in (16kB) blocks
|
// in (16kB) blocks
|
||||||
int m_cache_size;
|
int m_cache_size;
|
||||||
|
// expiration time of cache entries in seconds
|
||||||
|
int m_cache_expiry;
|
||||||
|
|
||||||
// memory pool for read and write operations
|
// memory pool for read and write operations
|
||||||
// and disk cache
|
// and disk cache
|
||||||
|
|
|
@ -121,6 +121,7 @@ namespace libtorrent
|
||||||
, send_buffer_watermark(80 * 1024)
|
, send_buffer_watermark(80 * 1024)
|
||||||
, auto_upload_slots(true)
|
, auto_upload_slots(true)
|
||||||
, cache_size(512)
|
, cache_size(512)
|
||||||
|
, cache_expiry(60)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// this is the user agent that will be sent to the tracker
|
// this is the user agent that will be sent to the tracker
|
||||||
|
@ -320,8 +321,13 @@ namespace libtorrent
|
||||||
bool auto_upload_slots;
|
bool auto_upload_slots;
|
||||||
|
|
||||||
// the disk write cache, specified in 16 KiB blocks.
|
// the disk write cache, specified in 16 KiB blocks.
|
||||||
// defaul is 512 (= 8 MB)
|
// default is 512 (= 8 MB)
|
||||||
int cache_size;
|
int cache_size;
|
||||||
|
|
||||||
|
// the number of seconds a write cache entry sits
|
||||||
|
// idle in the cache before it's forcefully flushed
|
||||||
|
// to disk. Default is 60 seconds.
|
||||||
|
int cache_expiry;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
|
|
|
@ -51,6 +51,7 @@ namespace libtorrent
|
||||||
, m_queue_buffer_size(0)
|
, m_queue_buffer_size(0)
|
||||||
, m_num_cached_blocks(0)
|
, m_num_cached_blocks(0)
|
||||||
, m_cache_size(512) // 512 * 16kB = 8MB
|
, m_cache_size(512) // 512 * 16kB = 8MB
|
||||||
|
, m_cache_expiry(60) // 1 minute
|
||||||
, m_pool(block_size)
|
, m_pool(block_size)
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
, m_block_size(block_size)
|
, m_block_size(block_size)
|
||||||
|
@ -146,6 +147,13 @@ namespace libtorrent
|
||||||
m_cache_size = s;
|
m_cache_size = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void disk_io_thread::set_cache_expiry(int ex)
|
||||||
|
{
|
||||||
|
mutex_t::scoped_lock l(m_mutex);
|
||||||
|
TORRENT_ASSERT(ex > 0);
|
||||||
|
m_cache_expiry = ex;
|
||||||
|
}
|
||||||
|
|
||||||
// aborts read operations
|
// aborts read operations
|
||||||
void disk_io_thread::stop(boost::intrusive_ptr<piece_manager> s)
|
void disk_io_thread::stop(boost::intrusive_ptr<piece_manager> s)
|
||||||
{
|
{
|
||||||
|
@ -210,6 +218,23 @@ namespace libtorrent
|
||||||
return m_pieces.end();
|
return m_pieces.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void disk_io_thread::flush_expired_pieces(mutex_t::scoped_lock& l)
|
||||||
|
{
|
||||||
|
ptime now = time_now();
|
||||||
|
|
||||||
|
TORRENT_ASSERT(l.locked());
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
std::vector<cached_piece_entry>::iterator i = std::min_element(
|
||||||
|
m_pieces.begin(), m_pieces.end()
|
||||||
|
, bind(&cached_piece_entry::last_write, _1)
|
||||||
|
< bind(&cached_piece_entry::last_write, _1));
|
||||||
|
if (i == m_pieces.end()) return;
|
||||||
|
if (total_seconds(now - i->last_write) < m_cache_expiry) return;
|
||||||
|
flush_and_remove(i, l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void disk_io_thread::flush_oldest_piece(mutex_t::scoped_lock& l)
|
void disk_io_thread::flush_oldest_piece(mutex_t::scoped_lock& l)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(l.locked());
|
TORRENT_ASSERT(l.locked());
|
||||||
|
@ -234,6 +259,9 @@ namespace libtorrent
|
||||||
TORRENT_ASSERT(l.locked());
|
TORRENT_ASSERT(l.locked());
|
||||||
cached_piece_entry& p = *e;
|
cached_piece_entry& p = *e;
|
||||||
int piece_size = p.storage->info()->piece_size(p.piece);
|
int piece_size = p.storage->info()->piece_size(p.piece);
|
||||||
|
#ifdef TORRENT_DISK_STATS
|
||||||
|
m_log << log_time() << " flushing " << piece_size << std::endl;
|
||||||
|
#endif
|
||||||
TORRENT_ASSERT(piece_size > 0);
|
TORRENT_ASSERT(piece_size > 0);
|
||||||
// char* buf = (char*)alloca(piece_size);
|
// char* buf = (char*)alloca(piece_size);
|
||||||
std::vector<char> temp(piece_size);
|
std::vector<char> temp(piece_size);
|
||||||
|
@ -425,6 +453,8 @@ namespace libtorrent
|
||||||
disk_io_job j = m_jobs.front();
|
disk_io_job j = m_jobs.front();
|
||||||
m_jobs.pop_front();
|
m_jobs.pop_front();
|
||||||
m_queue_buffer_size -= j.buffer_size;
|
m_queue_buffer_size -= j.buffer_size;
|
||||||
|
|
||||||
|
flush_expired_pieces(l);
|
||||||
l.unlock();
|
l.unlock();
|
||||||
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
@ -457,9 +487,6 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
ret = j.storage->read_impl(j.buffer, j.piece, j.offset
|
ret = j.storage->read_impl(j.buffer, j.piece, j.offset
|
||||||
, j.buffer_size);
|
, j.buffer_size);
|
||||||
|
|
||||||
// simulates slow drives
|
|
||||||
// usleep(300);
|
|
||||||
break;
|
break;
|
||||||
case disk_io_job::write:
|
case disk_io_job::write:
|
||||||
{
|
{
|
||||||
|
@ -479,9 +506,6 @@ namespace libtorrent
|
||||||
++m_num_cached_blocks;
|
++m_num_cached_blocks;
|
||||||
++p->num_blocks;
|
++p->num_blocks;
|
||||||
p->last_write = time_now();
|
p->last_write = time_now();
|
||||||
// std::cerr << " adding cache entry for p: " << j.piece
|
|
||||||
// << " block: " << block
|
|
||||||
// << " cached_blocks: " << m_num_cached_blocks << std::endl;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -490,9 +514,6 @@ namespace libtorrent
|
||||||
free_current_buffer = false;
|
free_current_buffer = false;
|
||||||
if (m_num_cached_blocks >= m_cache_size)
|
if (m_num_cached_blocks >= m_cache_size)
|
||||||
flush_oldest_piece(l);
|
flush_oldest_piece(l);
|
||||||
|
|
||||||
// simulates a slow drive
|
|
||||||
// usleep(300);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case disk_io_job::hash:
|
case disk_io_job::hash:
|
||||||
|
|
|
@ -811,6 +811,8 @@ namespace detail
|
||||||
TORRENT_ASSERT(s.unchoke_interval >= 5);
|
TORRENT_ASSERT(s.unchoke_interval >= 5);
|
||||||
if (m_settings.cache_size != s.cache_size)
|
if (m_settings.cache_size != s.cache_size)
|
||||||
m_disk_thread.set_cache_size(s.cache_size);
|
m_disk_thread.set_cache_size(s.cache_size);
|
||||||
|
if (m_settings.cache_expiry != s.cache_expiry)
|
||||||
|
m_disk_thread.set_cache_size(s.cache_expiry);
|
||||||
m_settings = s;
|
m_settings = s;
|
||||||
m_files.resize(m_settings.file_pool_size);
|
m_files.resize(m_settings.file_pool_size);
|
||||||
if (!s.auto_upload_slots) m_allowed_upload_slots = m_max_uploads;
|
if (!s.auto_upload_slots) m_allowed_upload_slots = m_max_uploads;
|
||||||
|
|
Loading…
Reference in New Issue