made file_pool use std::map instead of multi-index, and use std::string::operator< instead of the quite inefficient filesystem::path::operator<

This commit is contained in:
Arvid Norberg 2009-05-09 21:11:25 +00:00
parent 1eb2799a03
commit 9523d88909
4 changed files with 29 additions and 62 deletions

View File

@ -38,9 +38,6 @@ POSSIBILITY OF SUCH DAMAGE.
#endif
#include <boost/filesystem/path.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
@ -53,12 +50,6 @@ POSSIBILITY OF SUCH DAMAGE.
namespace libtorrent
{
using boost::multi_index::multi_index_container;
using boost::multi_index::ordered_non_unique;
using boost::multi_index::ordered_unique;
using boost::multi_index::indexed_by;
using boost::multi_index::member;
namespace fs = boost::filesystem;
struct TORRENT_EXPORT file_pool : boost::noncopyable
@ -72,28 +63,21 @@ namespace libtorrent
void resize(int size);
private:
void remove_oldest();
int m_size;
struct lru_file_entry
{
lru_file_entry(): last_use(time_now()) {}
mutable boost::shared_ptr<file> file_ptr;
fs::path file_path;
void* key;
ptime last_use;
int mode;
};
typedef multi_index_container<
lru_file_entry, indexed_by<
ordered_unique<member<lru_file_entry, fs::path
, &lru_file_entry::file_path> >
, ordered_non_unique<member<lru_file_entry, ptime
, &lru_file_entry::last_use> >
, ordered_non_unique<member<lru_file_entry, void*
, &lru_file_entry::key> >
>
> file_set;
typedef std::map<std::string, lru_file_entry> file_set;
file_set m_files;
boost::mutex m_mutex;

View File

@ -60,9 +60,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include <boost/iterator_adaptors.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/limits.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/next_prior.hpp>
#include <boost/noncopyable.hpp>
#include <boost/optional.hpp>

View File

@ -37,9 +37,6 @@ POSSIBILITY OF SUCH DAMAGE.
namespace libtorrent
{
using boost::multi_index::nth_index;
using boost::multi_index::get;
boost::shared_ptr<file> file_pool::open_file(void* st, fs::path const& p
, int m, error_code& ec)
{
@ -48,12 +45,10 @@ namespace libtorrent
TORRENT_ASSERT((m & file::rw_mask) == file::read_only
|| (m & file::rw_mask) == file::read_write);
boost::mutex::scoped_lock l(m_mutex);
typedef nth_index<file_set, 0>::type path_view;
path_view& pt = get<0>(m_files);
path_view::iterator i = pt.find(p);
if (i != pt.end())
file_set::iterator i = m_files.find(p.string());
if (i != m_files.end())
{
lru_file_entry e = *i;
lru_file_entry& e = i->second;
e.last_use = time_now();
if (e.key != st && ((e.mode & file::rw_mask) != file::read_only
@ -76,7 +71,6 @@ namespace libtorrent
{
// close the file before we open it with
// the new read/write privilages
i->file_ptr.reset();
TORRENT_ASSERT(e.file_ptr.unique());
e.file_ptr->close();
if (!e.file_ptr->open(p, m, ec))
@ -87,7 +81,6 @@ namespace libtorrent
TORRENT_ASSERT(e.file_ptr->is_open());
e.mode = m;
}
pt.replace(i, e);
TORRENT_ASSERT((e.mode & file::no_buffer) == (m & file::no_buffer));
return e.file_ptr;
}
@ -96,12 +89,7 @@ namespace libtorrent
{
// the file cache is at its maximum size, close
// the least recently used (lru) file from it
typedef nth_index<file_set, 1>::type lru_view;
lru_view& lt = get<1>(m_files);
lru_view::iterator i = lt.begin();
// the first entry in this view is the least recently used
TORRENT_ASSERT(lt.size() == 1 || (i->last_use <= boost::next(i)->last_use));
lt.erase(i);
remove_oldest();
}
lru_file_entry e;
e.file_ptr.reset(new (std::nothrow)file);
@ -114,34 +102,41 @@ namespace libtorrent
return boost::shared_ptr<file>();
e.mode = m;
e.key = st;
e.file_path = p;
pt.insert(e);
m_files.insert(std::make_pair(p.string(), e));
TORRENT_ASSERT(e.file_ptr->is_open());
return e.file_ptr;
}
void file_pool::remove_oldest()
{
file_set::iterator i = std::min_element(m_files.begin(), m_files.end()
, boost::bind(&lru_file_entry::last_use, boost::bind(&file_set::value_type::second, _1))
< boost::bind(&lru_file_entry::last_use, boost::bind(&file_set::value_type::second, _2)));
if (i == m_files.end()) return;
m_files.erase(i);
}
void file_pool::release(fs::path const& p)
{
boost::mutex::scoped_lock l(m_mutex);
typedef nth_index<file_set, 0>::type path_view;
path_view& pt = get<0>(m_files);
path_view::iterator i = pt.find(p);
if (i != pt.end()) pt.erase(i);
file_set::iterator i = m_files.find(p.string());
if (i != m_files.end()) m_files.erase(i);
}
void file_pool::release(void* st)
{
boost::mutex::scoped_lock l(m_mutex);
TORRENT_ASSERT(st != 0);
using boost::tie;
typedef nth_index<file_set, 2>::type key_view;
key_view& kt = get<2>(m_files);
key_view::iterator start, end;
tie(start, end) = kt.equal_range(st);
kt.erase(start, end);
for (file_set::iterator i = m_files.begin();
i != m_files.end();)
{
if (i->second.key == st)
m_files.erase(i++);
else
++i;
}
}
void file_pool::resize(int size)
@ -153,15 +148,8 @@ namespace libtorrent
if (int(m_files.size()) <= m_size) return;
// close the least recently used files
typedef nth_index<file_set, 1>::type lru_view;
lru_view& lt = get<1>(m_files);
lru_view::iterator i = lt.begin();
while (int(m_files.size()) > m_size)
{
// the first entry in this view is the least recently used
TORRENT_ASSERT(lt.size() == 1 || (i->last_use <= boost::next(i)->last_use));
lt.erase(i++);
}
remove_oldest();
}
}

View File

@ -107,8 +107,6 @@ POSSIBILITY OF SUCH DAMAGE.
namespace fs = boost::filesystem;
using boost::bind;
using namespace ::boost::multi_index;
using boost::multi_index::multi_index_container;
#if defined TORRENT_DEBUG && defined TORRENT_STORAGE_DEBUG && TORRENT_USE_IOSTREAM
namespace