more disk cache cleanup optimizations
This commit is contained in:
@@ -395,7 +395,7 @@ namespace libtorrent
|
|||||||
, int options, int num_blocks, mutex::scoped_lock& l);
|
, int options, int num_blocks, mutex::scoped_lock& l);
|
||||||
int cache_read_block(disk_io_job const& j, mutex::scoped_lock& l);
|
int cache_read_block(disk_io_job const& j, mutex::scoped_lock& l);
|
||||||
int free_piece(cached_piece_entry& p, mutex::scoped_lock& l);
|
int free_piece(cached_piece_entry& p, mutex::scoped_lock& l);
|
||||||
void drain_piece_bufs(cached_piece_entry& p, std::vector<char*>& buf
|
int drain_piece_bufs(cached_piece_entry& p, std::vector<char*>& buf
|
||||||
, mutex::scoped_lock& l);
|
, mutex::scoped_lock& l);
|
||||||
int try_read_from_cache(disk_io_job const& j, bool& hit);
|
int try_read_from_cache(disk_io_job const& j, bool& hit);
|
||||||
int read_piece_from_cache_and_hash(disk_io_job const& j, sha1_hash& h);
|
int read_piece_from_cache_and_hash(disk_io_job const& j, sha1_hash& h);
|
||||||
|
@@ -522,21 +522,24 @@ namespace libtorrent
|
|||||||
if (!bufs.empty()) free_multiple_buffers(&bufs[0], bufs.size());
|
if (!bufs.empty()) free_multiple_buffers(&bufs[0], bufs.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void disk_io_thread::drain_piece_bufs(cached_piece_entry& p, std::vector<char*>& buf
|
int disk_io_thread::drain_piece_bufs(cached_piece_entry& p, std::vector<char*>& buf
|
||||||
, mutex::scoped_lock& l)
|
, mutex::scoped_lock& l)
|
||||||
{
|
{
|
||||||
int piece_size = p.storage->info()->piece_size(p.piece);
|
int piece_size = p.storage->info()->piece_size(p.piece);
|
||||||
int blocks_in_piece = (piece_size + m_block_size - 1) / m_block_size;
|
int blocks_in_piece = (piece_size + m_block_size - 1) / m_block_size;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
for (int i = 0; i < blocks_in_piece; ++i)
|
for (int i = 0; i < blocks_in_piece; ++i)
|
||||||
{
|
{
|
||||||
if (p.blocks[i].buf == 0) continue;
|
if (p.blocks[i].buf == 0) continue;
|
||||||
buf.push_back(p.blocks[i].buf);
|
buf.push_back(p.blocks[i].buf);
|
||||||
|
++ret;
|
||||||
p.blocks[i].buf = 0;
|
p.blocks[i].buf = 0;
|
||||||
--p.num_blocks;
|
--p.num_blocks;
|
||||||
--m_cache_stats.cache_size;
|
--m_cache_stats.cache_size;
|
||||||
--m_cache_stats.read_cache_size;
|
--m_cache_stats.read_cache_size;
|
||||||
}
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns the number of blocks that were freed
|
// returns the number of blocks that were freed
|
||||||
@@ -546,16 +549,20 @@ namespace libtorrent
|
|||||||
int blocks_in_piece = (piece_size + m_block_size - 1) / m_block_size;
|
int blocks_in_piece = (piece_size + m_block_size - 1) / m_block_size;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
// build a vector of all the buffers we need to free
|
||||||
|
// and free them all in one go
|
||||||
|
std::vector<char*> buffers;
|
||||||
for (int i = 0; i < blocks_in_piece; ++i)
|
for (int i = 0; i < blocks_in_piece; ++i)
|
||||||
{
|
{
|
||||||
if (p.blocks[i].buf == 0) continue;
|
if (p.blocks[i].buf == 0) continue;
|
||||||
free_buffer(p.blocks[i].buf);
|
buffers.push_back(p.blocks[i].buf);
|
||||||
++ret;
|
++ret;
|
||||||
p.blocks[i].buf = 0;
|
p.blocks[i].buf = 0;
|
||||||
--p.num_blocks;
|
--p.num_blocks;
|
||||||
--m_cache_stats.cache_size;
|
--m_cache_stats.cache_size;
|
||||||
--m_cache_stats.read_cache_size;
|
--m_cache_stats.read_cache_size;
|
||||||
}
|
}
|
||||||
|
if (!buffers.empty()) free_multiple_buffers(&buffers[0], buffers.size());
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -578,9 +585,13 @@ namespace libtorrent
|
|||||||
// don't replace an entry that is is too young
|
// don't replace an entry that is is too young
|
||||||
if (time_now() > i->expire) return 0;
|
if (time_now() > i->expire) return 0;
|
||||||
int blocks = 0;
|
int blocks = 0;
|
||||||
|
|
||||||
|
// build a vector of all the buffers we need to free
|
||||||
|
// and free them all in one go
|
||||||
|
std::vector<char*> buffers;
|
||||||
if (num_blocks >= i->num_blocks)
|
if (num_blocks >= i->num_blocks)
|
||||||
{
|
{
|
||||||
blocks = free_piece(const_cast<cached_piece_entry&>(*i), l);
|
blocks = drain_piece_bufs(const_cast<cached_piece_entry&>(*i), buffers, l);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -598,7 +609,7 @@ namespace libtorrent
|
|||||||
{
|
{
|
||||||
while (i->blocks[start].buf == 0 && start <= end) ++start;
|
while (i->blocks[start].buf == 0 && start <= end) ++start;
|
||||||
if (start > end) break;
|
if (start > end) break;
|
||||||
free_buffer(i->blocks[start].buf);
|
buffers.push_back(i->blocks[start].buf);
|
||||||
i->blocks[start].buf = 0;
|
i->blocks[start].buf = 0;
|
||||||
++blocks;
|
++blocks;
|
||||||
--const_cast<cached_piece_entry&>(*i).num_blocks;
|
--const_cast<cached_piece_entry&>(*i).num_blocks;
|
||||||
@@ -610,7 +621,7 @@ namespace libtorrent
|
|||||||
|
|
||||||
while (i->blocks[end].buf == 0 && start <= end) --end;
|
while (i->blocks[end].buf == 0 && start <= end) --end;
|
||||||
if (start > end) break;
|
if (start > end) break;
|
||||||
free_buffer(i->blocks[end].buf);
|
buffers.push_back(i->blocks[end].buf);
|
||||||
i->blocks[end].buf = 0;
|
i->blocks[end].buf = 0;
|
||||||
++blocks;
|
++blocks;
|
||||||
--const_cast<cached_piece_entry&>(*i).num_blocks;
|
--const_cast<cached_piece_entry&>(*i).num_blocks;
|
||||||
@@ -618,9 +629,10 @@ namespace libtorrent
|
|||||||
--m_cache_stats.read_cache_size;
|
--m_cache_stats.read_cache_size;
|
||||||
--num_blocks;
|
--num_blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (i->num_blocks == 0) idx.erase(i);
|
if (i->num_blocks == 0) idx.erase(i);
|
||||||
|
|
||||||
|
if (!buffers.empty()) free_multiple_buffers(&buffers[0], buffers.size());
|
||||||
return blocks;
|
return blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -805,18 +817,20 @@ namespace libtorrent
|
|||||||
j.buffer = 0;
|
j.buffer = 0;
|
||||||
j.piece = p.piece;
|
j.piece = p.piece;
|
||||||
test_error(j);
|
test_error(j);
|
||||||
|
std::vector<char*> buffers;
|
||||||
for (int i = start; i < end; ++i)
|
for (int i = start; i < end; ++i)
|
||||||
{
|
{
|
||||||
if (p.blocks[i].buf == 0) continue;
|
if (p.blocks[i].buf == 0) continue;
|
||||||
j.buffer_size = (std::min)(piece_size - i * m_block_size, m_block_size);
|
j.buffer_size = (std::min)(piece_size - i * m_block_size, m_block_size);
|
||||||
int result = j.error ? -1 : j.buffer_size;
|
int result = j.error ? -1 : j.buffer_size;
|
||||||
j.offset = i * m_block_size;
|
j.offset = i * m_block_size;
|
||||||
free_buffer(p.blocks[i].buf);
|
buffers.push_back(p.blocks[i].buf);
|
||||||
post_callback(p.blocks[i].callback, j, result);
|
post_callback(p.blocks[i].callback, j, result);
|
||||||
p.blocks[i].callback.clear();
|
p.blocks[i].callback.clear();
|
||||||
p.blocks[i].buf = 0;
|
p.blocks[i].buf = 0;
|
||||||
++ret;
|
++ret;
|
||||||
}
|
}
|
||||||
|
if (!buffers.empty()) free_multiple_buffers(&buffers[0], buffers.size());
|
||||||
|
|
||||||
TORRENT_ASSERT(buffer_size == 0);
|
TORRENT_ASSERT(buffer_size == 0);
|
||||||
// std::cerr << " flushing p: " << p.piece << " cached_blocks: " << m_cache_stats.cache_size << std::endl;
|
// std::cerr << " flushing p: " << p.piece << " cached_blocks: " << m_cache_stats.cache_size << std::endl;
|
||||||
@@ -1311,6 +1325,9 @@ namespace libtorrent
|
|||||||
TORRENT_ASSERT(p.blocks[block].buf);
|
TORRENT_ASSERT(p.blocks[block].buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// build a vector of all the buffers we need to free
|
||||||
|
// and free them all in one go
|
||||||
|
std::vector<char*> buffers;
|
||||||
while (size > 0)
|
while (size > 0)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(p.blocks[block].buf);
|
TORRENT_ASSERT(p.blocks[block].buf);
|
||||||
@@ -1331,7 +1348,7 @@ namespace libtorrent
|
|||||||
// the peer skipped
|
// the peer skipped
|
||||||
for (int i = block; i >= 0 && p.blocks[i].buf; --i)
|
for (int i = block; i >= 0 && p.blocks[i].buf; --i)
|
||||||
{
|
{
|
||||||
free_buffer(p.blocks[i].buf);
|
buffers.push_back(p.blocks[i].buf);
|
||||||
p.blocks[i].buf = 0;
|
p.blocks[i].buf = 0;
|
||||||
--p.num_blocks;
|
--p.num_blocks;
|
||||||
--m_cache_stats.cache_size;
|
--m_cache_stats.cache_size;
|
||||||
@@ -1340,6 +1357,7 @@ namespace libtorrent
|
|||||||
}
|
}
|
||||||
++block;
|
++block;
|
||||||
}
|
}
|
||||||
|
if (!buffers.empty()) free_multiple_buffers(&buffers[0], buffers.size());
|
||||||
return j.buffer_size;
|
return j.buffer_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2220,6 +2238,9 @@ namespace libtorrent
|
|||||||
cache_piece_index_t::iterator start = idx.lower_bound(std::pair<void*, int>(j.storage.get(), 0));
|
cache_piece_index_t::iterator start = idx.lower_bound(std::pair<void*, int>(j.storage.get(), 0));
|
||||||
cache_piece_index_t::iterator end = idx.upper_bound(std::pair<void*, int>(j.storage.get(), INT_MAX));
|
cache_piece_index_t::iterator end = idx.upper_bound(std::pair<void*, int>(j.storage.get(), INT_MAX));
|
||||||
|
|
||||||
|
// build a vector of all the buffers we need to free
|
||||||
|
// and free them all in one go
|
||||||
|
std::vector<char*> buffers;
|
||||||
for (cache_piece_index_t::iterator i = start; i != end; ++i)
|
for (cache_piece_index_t::iterator i = start; i != end; ++i)
|
||||||
{
|
{
|
||||||
torrent_info const& ti = *i->storage->info();
|
torrent_info const& ti = *i->storage->info();
|
||||||
@@ -2227,13 +2248,14 @@ namespace libtorrent
|
|||||||
for (int j = 0; j < blocks_in_piece; ++j)
|
for (int j = 0; j < blocks_in_piece; ++j)
|
||||||
{
|
{
|
||||||
if (i->blocks[j].buf == 0) continue;
|
if (i->blocks[j].buf == 0) continue;
|
||||||
free_buffer(i->blocks[j].buf);
|
buffers.push_back(i->blocks[j].buf);
|
||||||
i->blocks[j].buf = 0;
|
i->blocks[j].buf = 0;
|
||||||
--m_cache_stats.cache_size;
|
--m_cache_stats.cache_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
idx.erase(start, end);
|
idx.erase(start, end);
|
||||||
l.unlock();
|
l.unlock();
|
||||||
|
if (!buffers.empty()) free_multiple_buffers(&buffers[0], buffers.size());
|
||||||
release_memory();
|
release_memory();
|
||||||
|
|
||||||
ret = j.storage->delete_files_impl();
|
ret = j.storage->delete_files_impl();
|
||||||
|
Reference in New Issue
Block a user