Skip to content

Commit

Permalink
fix performance bug in the file pool, evicting MRU instead of LRU. Di…
Browse files Browse the repository at this point in the history
…scovered by HanabishiRecca
  • Loading branch information
arvidn committed Oct 29, 2024
1 parent 6a2c1ee commit e5fe95f
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 7 deletions.
1 change: 1 addition & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

2.0.11 not released

* fix performance bug in the file pool, evicting MRU instead of LRU (HanabishiRecca)
* fix bug where file_progress could sometimes be reported as >100%
* don't hint FADV_RANDOM on posix systems. May improve seeding performance
* allow boost connect while checking resume data if no_verify_files flag is set
Expand Down
3 changes: 2 additions & 1 deletion include/libtorrent/aux_/file_view_pool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,8 @@ namespace aux {
mi::indexed_by<
// look up files by (torrent, file) key
mi::ordered_unique<mi::member<file_entry, file_id, &file_entry::key>>,
// look up files by least recently used
// look up files by least recently used. New items are added to the
// back, and old items are removed from the front.
mi::sequenced<>
#if TORRENT_HAVE_MAP_VIEW_OF_FILE
// look up files with dirty pages
Expand Down
21 changes: 15 additions & 6 deletions src/file_view_pool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,12 @@ namespace libtorrent { namespace aux {
});

auto& lru_view = m_files.get<1>();
lru_view.relocate(m_files.project<1>(i), lru_view.begin());
lru_view.relocate(lru_view.end(), m_files.project<1>(i));

#if TORRENT_USE_ASSERTS
// ensure the LRU index is maintained as we would expect it to be
TORRENT_ASSERT(lru_view.back().key == i->key);
#endif
return i->mapping;
}

Expand Down Expand Up @@ -174,7 +178,7 @@ namespace libtorrent { namespace aux {

// there's an edge case where two threads are racing to insert a newly
// opened file, one thread is opening a file for writing and the other
// fore reading. If the reading thread wins, it's important that the
// for reading. If the reading thread wins, it's important that the
// thread opening for writing still overwrites the file in the pool,
// since a file opened for reading and writing can be used for both.
// So, we can't move e in here, because we may need it again of the
Expand All @@ -200,8 +204,13 @@ namespace libtorrent { namespace aux {
}

auto& lru_view = m_files.get<1>();
lru_view.relocate(m_files.project<1>(i), lru_view.begin());
lru_view.relocate(lru_view.end(), m_files.project<1>(i));
}
#if TORRENT_USE_ASSERTS
// ensure the LRU index is maintained as we would expect it to be
auto& lru_view = m_files.get<1>();
TORRENT_ASSERT(lru_view.back().key == e.key);
#endif
notify_file_open(ofe, i->mapping, storage_error());
return i->mapping;
}
Expand Down Expand Up @@ -351,11 +360,11 @@ namespace libtorrent { namespace aux {

#if TRACE_FILE_VIEW_POOL
std::cout << std::this_thread::get_id() << " removing: ("
<< lru_view.back().key.first << ", " << lru_view.back().key.second << ")\n";
<< lru_view.front().key.first << ", " << lru_view.front().key.second << ")\n";
#endif

auto mapping = std::move(lru_view.back().mapping);
lru_view.pop_back();
auto mapping = std::move(lru_view.front().mapping);
lru_view.pop_front();

// closing a file may be long running operation (mac os x)
// let the caller destruct it once it has released the mutex
Expand Down

0 comments on commit e5fe95f

Please sign in to comment.