From 247b8ae443a16fdefe1d442be7fe696cdafc09f3 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Tue, 14 Nov 2006 13:36:10 +0000 Subject: [PATCH] removed temporary assert and factored file_pool out of storage to prepare for a per session file pool --- Jamfile | 1 + include/Makefile.am | 1 + include/libtorrent/file_pool.hpp | 101 ++++++++++++++++++++++++ include/libtorrent/storage.hpp | 2 +- src/Makefile.am | 7 +- src/file_pool.cpp | 104 +++++++++++++++++++++++++ src/storage.cpp | 129 +------------------------------ src/torrent_handle.cpp | 3 - 8 files changed, 215 insertions(+), 133 deletions(-) create mode 100644 include/libtorrent/file_pool.hpp create mode 100644 src/file_pool.cpp diff --git a/Jamfile b/Jamfile index 38d12d1c6..996c5db75 100755 --- a/Jamfile +++ b/Jamfile @@ -55,6 +55,7 @@ SOURCES = sha1.cpp metadata_transfer.cpp logger.cpp + file_pool.cpp ; KADEMLIA_SOURCES = diff --git a/include/Makefile.am b/include/Makefile.am index 9bd59627c..51c7320b8 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -9,6 +9,7 @@ libtorrent/entry.hpp \ libtorrent/escape_string.hpp \ libtorrent/extensions.hpp \ libtorrent/file.hpp \ +libtorrent/file_pool.hpp \ libtorrent/fingerprint.hpp \ libtorrent/hasher.hpp \ libtorrent/http_tracker_connection.hpp \ diff --git a/include/libtorrent/file_pool.hpp b/include/libtorrent/file_pool.hpp new file mode 100644 index 000000000..054f9ccfe --- /dev/null +++ b/include/libtorrent/file_pool.hpp @@ -0,0 +1,101 @@ +/* + +Copyright (c) 2006, Arvid Norberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + * Neither the name of the author nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef TORRENT_FILE_POOL_HPP +#define TORRENT_FILE_POOL_HPP + +#ifdef _MSC_VER +#pragma warning(push, 1) +#endif + +#include +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#include "libtorrent/file.hpp" + +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 pt = boost::posix_time; + namespace fs = boost::filesystem; + + struct file_pool + { + file_pool(int size): m_size(size) {} + + boost::shared_ptr open_file(void* st, fs::path const& p, file::open_mode m); + void release(void* st); + + private: + int m_size; + + struct lru_file_entry + { + lru_file_entry(boost::shared_ptr const& f) + : file_ptr(f) + , last_use(pt::second_clock::universal_time()) {} + mutable boost::shared_ptr file_ptr; + fs::path file_path; + void* key; + pt::ptime last_use; + file::open_mode mode; + }; + + typedef multi_index_container< + lru_file_entry, indexed_by< + ordered_unique > + , ordered_non_unique > + , ordered_non_unique > + > + > file_set; + + file_set m_files; + }; +} + +#endif \ No newline at end of file diff --git a/include/libtorrent/storage.hpp b/include/libtorrent/storage.hpp index 44f956786..be2980816 100755 --- a/include/libtorrent/storage.hpp +++ b/include/libtorrent/storage.hpp @@ -91,7 +91,7 @@ namespace libtorrent public: storage( const torrent_info& info - , const boost::filesystem::path& path); + , const boost::filesystem::path& path); void swap(storage&); diff --git a/src/Makefile.am b/src/Makefile.am index 1e8b31c52..bcef211a1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -9,6 +9,7 @@ torrent_info.cpp tracker_manager.cpp \ http_tracker_connection.cpp udp_tracker_connection.cpp \ alert.cpp identify_client.cpp ip_filter.cpp file.cpp metadata_transfer.cpp \ logger.cpp \ +file_pool.cpp \ \ kademlia/closest_nodes.cpp \ kademlia/dht_tracker.cpp \ @@ -25,12 +26,17 @@ $(top_srcdir)/include/libtorrent/alert.hpp \ $(top_srcdir)/include/libtorrent/alert_types.hpp \ $(top_srcdir)/include/libtorrent/allocate_resources.hpp \ $(top_srcdir)/include/libtorrent/aux_/allocate_resources_impl.hpp \ +$(top_srcdir)/include/libtorrent/aux_/session_impl.hpp \ $(top_srcdir)/include/libtorrent/bencode.hpp \ $(top_srcdir)/include/libtorrent/buffer.hpp \ $(top_srcdir)/include/libtorrent/debug.hpp \ $(top_srcdir)/include/libtorrent/entry.hpp \ $(top_srcdir)/include/libtorrent/escape_string.hpp \ +$(top_srcdir)/include/libtorrent/extensions.hpp \ +$(top_srcdir)/include/libtorrent/extensions/metadata_transfer.hpp \ +$(top_srcdir)/include/libtorrent/extensions/logger.hpp \ $(top_srcdir)/include/libtorrent/file.hpp \ +$(top_srcdir)/include/libtorrent/file_pool.hpp \ $(top_srcdir)/include/libtorrent/fingerprint.hpp \ $(top_srcdir)/include/libtorrent/hasher.hpp \ $(top_srcdir)/include/libtorrent/session_settings.hpp \ @@ -51,7 +57,6 @@ $(top_srcdir)/include/libtorrent/piece_picker.hpp \ $(top_srcdir)/include/libtorrent/policy.hpp \ $(top_srcdir)/include/libtorrent/resource_request.hpp \ $(top_srcdir)/include/libtorrent/session.hpp \ -$(top_srcdir)/include/libtorrent/aux_/session_impl.hpp \ $(top_srcdir)/include/libtorrent/size_type.hpp \ $(top_srcdir)/include/libtorrent/socket.hpp \ $(top_srcdir)/include/libtorrent/stat.hpp \ diff --git a/src/file_pool.cpp b/src/file_pool.cpp new file mode 100644 index 000000000..130ca7501 --- /dev/null +++ b/src/file_pool.cpp @@ -0,0 +1,104 @@ +/* + +Copyright (c) 2006, Arvid Norberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + * Neither the name of the author nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#include "libtorrent/file_pool.hpp" + +namespace libtorrent +{ + using boost::multi_index::nth_index; + using boost::multi_index::get; + + boost::shared_ptr file_pool::open_file(void* st, fs::path const& p, file::open_mode m) + { + + assert(st != 0); + assert(p.is_complete()); + typedef nth_index::type path_view; + path_view& pt = get<0>(m_files); + path_view::iterator i = pt.find(p); + if (i != pt.end()) + { + lru_file_entry e = *i; + e.last_use = pt::second_clock::universal_time(); + + // if you hit this assert, you probably have more than one + // storage/torrent using the same file at the same time! + assert(e.key == st); + + e.key = st; + if ((e.mode & m) != m) + { + // close the file before we open it with + // the new read/write privilages + i->file_ptr.reset(); + assert(e.file_ptr.unique()); + e.file_ptr.reset(); + e.file_ptr.reset(new file(p, m)); + e.mode = m; + } + pt.replace(i, e); + return e.file_ptr; + } + // the file is not in our cache + if ((int)m_files.size() >= m_size) + { + // the file cache is at its maximum size, close + // the least recently used (lru) file from it + typedef nth_index::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 + assert(lt.size() == 1 || (i->last_use <= boost::next(i)->last_use)); + lt.erase(i); + } + lru_file_entry e(boost::shared_ptr(new file(p, m))); + e.mode = m; + e.key = st; + e.file_path = p; + pt.insert(e); + return e.file_ptr; + } + + void file_pool::release(void* st) + { + assert(st != 0); + using boost::tie; + + typedef nth_index::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); + } + +} diff --git a/src/storage.cpp b/src/storage.cpp index 33b32bad3..ca01fb0ff 100755 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -64,6 +64,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/peer_id.hpp" #include "libtorrent/file.hpp" #include "libtorrent/invariant_check.hpp" +#include "libtorrent/file_pool.hpp" #include "libtorrent/aux_/session_impl.hpp" #ifndef NDEBUG @@ -218,135 +219,7 @@ namespace log << s; log.flush(); } -/* - struct file_key - { - file_key(sha1_hash ih, path f): info_hash(ih), file_path(f) {} - file_key() {} - sha1_hash info_hash; - path file_path; - bool operator<(file_key const& fk) const - { - if (info_hash < fk.info_hash) return true; - if (fk.info_hash < info_hash) return false; - return file_path < fk.file_path; - } - }; -*/ - struct lru_file_entry - { - lru_file_entry(boost::shared_ptr const& f) - : file_ptr(f) - , last_use(pt::second_clock::universal_time()) {} - mutable boost::shared_ptr file_ptr; - path file_path; - void* key; - pt::ptime last_use; - file::open_mode mode; - }; - struct file_pool - { - file_pool(int size): m_size(size) {} - - boost::shared_ptr open_file(void* st, path const& p, file::open_mode m) - { - assert(st != 0); - assert(p.is_complete()); - typedef nth_index::type path_view; - path_view& pt = get<0>(m_files); - path_view::iterator i = pt.find(p); - if (i != pt.end()) - { - lru_file_entry e = *i; - e.last_use = pt::second_clock::universal_time(); - - // if you hit this assert, you probably have more than one - // storage/torrent using the same file at the same time! - assert(e.key == st); - - e.key = st; - if ((e.mode & m) != m) - { - // close the file before we open it with - // the new read/write privilages - i->file_ptr.reset(); - assert(e.file_ptr.unique()); - e.file_ptr.reset(); - e.file_ptr.reset(new file(p, m)); - e.mode = m; - } - pt.replace(i, e); - return e.file_ptr; - } - // the file is not in our cache - if ((int)m_files.size() >= m_size) - { - // the file cache is at its maximum size, close - // the least recently used (lru) file from it - typedef nth_index::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 -/* for (lru_view::iterator i = lt.begin(); i != lt.end(); ++i) - { - std::cerr << i->last_use << "\n"; - } -*/ assert(lt.size() == 1 || (i->last_use <= boost::next(i)->last_use)); - lt.erase(i); - } - lru_file_entry e(boost::shared_ptr(new file(p, m))); - e.mode = m; - e.key = st; - e.file_path = p; - pt.insert(e); - return e.file_ptr; - } - - void release(void* st) - { - assert(st != 0); - using boost::tie; - - typedef nth_index::type key_view; - key_view& kt = get<2>(m_files); - - key_view::iterator start, end; - tie(start, end) = kt.equal_range(st); - -/* - std::cerr << "releasing files!\n"; - for (path_view::iterator i = r.first; i != r.second; ++i) - { - std::cerr << i->key.file_path.native_file_string() << "\n"; - } -*/ - kt.erase(start, end); -/* - std::cerr << "files left: " << pt.size() << "\n"; - for (path_view::iterator i = pt.begin(); i != pt.end(); ++i) - { - std::cerr << i->key.file_path.native_file_string() << "\n"; - } -*/ - } - - private: - int m_size; - - typedef multi_index_container< - lru_file_entry, indexed_by< - ordered_unique > - , ordered_non_unique > - , ordered_non_unique > - > - > file_set; - - file_set m_files; - }; } namespace libtorrent diff --git a/src/torrent_handle.cpp b/src/torrent_handle.cpp index a16c34254..9df79f1a8 100755 --- a/src/torrent_handle.cpp +++ b/src/torrent_handle.cpp @@ -82,8 +82,6 @@ namespace libtorrent { void throw_invalid_handle() { - // TODO: TEMP! - assert(false); throw invalid_handle(); } @@ -109,7 +107,6 @@ namespace libtorrent if (t) return f(*t); } - assert(false); // throwing directly instead of calling // the throw_invalid_handle() function // avoids a warning in gcc