00001
00002
00003
00004
00005
00006
00007
00008 #include "libtorrent/file_pool.hpp"
00009
00010 #include <iostream>
00011
00012 namespace libtorrent
00013 {
00014 using boost::multi_index::nth_index;
00015 using boost::multi_index::get;
00016
00017 boost::shared_ptr<file> file_pool::open_file(void* st, fs::path const& p, file::open_mode m)
00018 {
00019 assert(st != 0);
00020 assert(p.is_complete());
00021 boost::mutex::scoped_lock l(m_mutex);
00022 typedef nth_index<file_set, 0>::type path_view;
00023 path_view& pt = get<0>(m_files);
00024 path_view::iterator i = pt.find(p);
00025 if (i != pt.end())
00026 {
00027 lru_file_entry e = *i;
00028 e.last_use = pt::second_clock::universal_time();
00029
00030
00031
00032 assert(e.key == st);
00033
00034 e.key = st;
00035 if ((e.mode & m) != m)
00036 {
00037
00038
00039 i->file_ptr.reset();
00040 assert(e.file_ptr.unique());
00041 e.file_ptr.reset();
00042 e.file_ptr.reset(new file(p, m));
00043 e.mode = m;
00044 }
00045 pt.replace(i, e);
00046 return e.file_ptr;
00047 }
00048
00049 if ((int)m_files.size() >= m_size)
00050 {
00051
00052
00053 typedef nth_index<file_set, 1>::type lru_view;
00054 lru_view& lt = get<1>(m_files);
00055 lru_view::iterator i = lt.begin();
00056
00057 assert(lt.size() == 1 || (i->last_use <= boost::next(i)->last_use));
00058 lt.erase(i);
00059 }
00060 lru_file_entry e(boost::shared_ptr<file>(new file(p, m)));
00061 e.mode = m;
00062 e.key = st;
00063 e.file_path = p;
00064 pt.insert(e);
00065 return e.file_ptr;
00066 }
00067
00068 void file_pool::release(void* st)
00069 {
00070 boost::mutex::scoped_lock l(m_mutex);
00071 assert(st != 0);
00072 using boost::tie;
00073
00074 typedef nth_index<file_set, 2>::type key_view;
00075 key_view& kt = get<2>(m_files);
00076
00077 key_view::iterator start, end;
00078 tie(start, end) = kt.equal_range(st);
00079 kt.erase(start, end);
00080 }
00081
00082 void file_pool::resize(int size)
00083 {
00084 assert(size > 0);
00085 if (size == m_size) return;
00086 boost::mutex::scoped_lock l(m_mutex);
00087 m_size = size;
00088 if (int(m_files.size()) <= m_size) return;
00089
00090
00091 typedef nth_index<file_set, 1>::type lru_view;
00092 lru_view& lt = get<1>(m_files);
00093 lru_view::iterator i = lt.begin();
00094 while (int(m_files.size()) > m_size)
00095 {
00096
00097 assert(lt.size() == 1 || (i->last_use <= boost::next(i)->last_use));
00098 lt.erase(i++);
00099 }
00100 }
00101
00102 }