made the storage into a customization point. it is now interchangable for a custom implementation

This commit is contained in:
Arvid Norberg 2007-03-16 05:29:23 +00:00
parent 52d6a201be
commit 029953c5ae
11 changed files with 239 additions and 167 deletions

View File

@ -98,7 +98,8 @@ int main(int argc, char* argv[])
t.set_piece_size(piece_size);
file_pool fp;
storage st(t, full_path.branch_path(), fp);
boost::scoped_ptr<storage_interface> st(
default_storage_constructor(t, full_path.branch_path(), fp));
t.add_tracker(argv[2]);
// calculate the hash for all pieces
@ -106,7 +107,7 @@ int main(int argc, char* argv[])
std::vector<char> buf(piece_size);
for (int i = 0; i < num; ++i)
{
st.read(&buf[0], i, 0, t.piece_size(i));
st->read(&buf[0], i, 0, t.piece_size(i));
hasher h(&buf[0], t.piece_size(i));
t.set_hash(i, h.final());
std::cerr << (i+1) << "/" << num << "\r";

View File

@ -238,7 +238,8 @@ namespace libtorrent
, boost::filesystem::path const& save_path
, entry const& resume_data
, bool compact_mode
, int block_size);
, int block_size
, storage_constructor_type sc);
torrent_handle add_torrent(
char const* tracker_url
@ -247,7 +248,8 @@ namespace libtorrent
, boost::filesystem::path const& save_path
, entry const& resume_data
, bool compact_mode
, int block_size);
, int block_size
, storage_constructor_type sc);
void remove_torrent(torrent_handle const& h);

View File

@ -1,3 +1,35 @@
/*
Copyright (c) 2007, 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_NATPMP_HPP
#define TORRENT_NATPMP_HPP

View File

@ -61,6 +61,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/fingerprint.hpp"
#include "libtorrent/resource_request.hpp"
#include "libtorrent/storage.hpp"
#ifdef _MSC_VER
# include <eh.h>
@ -137,7 +138,8 @@ namespace libtorrent
, boost::filesystem::path const& save_path
, entry const& resume_data = entry()
, bool compact_mode = true
, int block_size = 16 * 1024);
, int block_size = 16 * 1024
, storage_constructor_type sc = default_storage_constructor);
// TODO: deprecated, this is for backwards compatibility only
torrent_handle add_torrent(
@ -145,10 +147,11 @@ namespace libtorrent
, boost::filesystem::path const& save_path
, entry const& resume_data = entry()
, bool compact_mode = true
, int block_size = 16 * 1024)
, int block_size = 16 * 1024
, storage_constructor_type sc = default_storage_constructor)
{
return add_torrent(torrent_info(e), save_path, resume_data
, compact_mode, block_size);
, compact_mode, block_size, sc);
}
torrent_handle add_torrent(
@ -158,7 +161,8 @@ namespace libtorrent
, boost::filesystem::path const& save_path
, entry const& resume_data = entry()
, bool compact_mode = true
, int block_size = 16 * 1024);
, int block_size = 16 * 1024
, storage_constructor_type sc = default_storage_constructor);
session_proxy abort() { return session_proxy(m_impl); }

View File

@ -87,40 +87,30 @@ namespace libtorrent
std::string m_msg;
};
class TORRENT_EXPORT storage
struct TORRENT_EXPORT storage_interface
{
public:
storage(
const torrent_info& info
, const boost::filesystem::path& path
, file_pool& fp);
void swap(storage&);
// may throw file_error if storage for slot does not exist
size_type read(char* buf, int slot, int offset, int size);
virtual size_type read(char* buf, int slot, int offset, int size) = 0;
// may throw file_error if storage for slot hasn't been allocated
void write(const char* buf, int slot, int offset, int size);
virtual void write(const char* buf, int slot, int offset, int size) = 0;
bool move_storage(boost::filesystem::path save_path);
virtual bool move_storage(boost::filesystem::path save_path) = 0;
// this will close all open files that are opened for
// writing. This is called when a torrent has finished
// downloading.
void release_files();
#ifndef NDEBUG
// overwrites some slots with the
// contents of others
void shuffle();
#endif
private:
class impl;
boost::shared_ptr<impl> m_pimpl;
virtual void release_files() = 0;
virtual ~storage_interface() {}
};
typedef storage_interface* (&storage_constructor_type)(
torrent_info const&, boost::filesystem::path const&
, file_pool&);
TORRENT_EXPORT storage_interface* default_storage_constructor(torrent_info const& ti
, boost::filesystem::path const& path, file_pool& fp);
class TORRENT_EXPORT piece_manager : boost::noncopyable
{
public:
@ -128,7 +118,8 @@ namespace libtorrent
piece_manager(
const torrent_info& info
, const boost::filesystem::path& path
, file_pool& fp);
, file_pool& fp
, storage_constructor_type sc);
~piece_manager();

View File

@ -68,6 +68,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/config.hpp"
#include "libtorrent/escape_string.hpp"
#include "libtorrent/bandwidth_manager.hpp"
#include "libtorrent/storage.hpp"
namespace libtorrent
{
@ -100,7 +101,8 @@ namespace libtorrent
, tcp::endpoint const& net_interface
, bool compact_mode
, int block_size
, session_settings const& s);
, session_settings const& s
, storage_constructor_type sc);
// used with metadata-less torrents
// (the metadata is downloaded from the peers)
@ -114,7 +116,8 @@ namespace libtorrent
, tcp::endpoint const& net_interface
, bool compact_mode
, int block_size
, session_settings const& s);
, session_settings const& s
, storage_constructor_type sc);
~torrent();
@ -657,6 +660,8 @@ namespace libtorrent
boost::scoped_ptr<std::string> m_name;
session_settings const& m_settings;
storage_constructor_type m_storage_constructor;
#ifndef TORRENT_DISABLE_EXTENSIONS
typedef std::list<boost::shared_ptr<torrent_plugin> > extension_list_t;

View File

@ -1,3 +1,35 @@
/*
Copyright (c) 2007, 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/natpmp.hpp>
#include <libtorrent/io.hpp>
#include <boost/bind.hpp>
@ -31,7 +63,16 @@ natpmp::natpmp(io_service& ios, portmap_callback_t const& cb)
if (i->endpoint().address().is_v4()) break;
}
if (i == udp::resolver_iterator()) return;
if (i == udp::resolver_iterator())
{
#if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING)
m_log << "local host name did not resolve to an IPv4 address. "
"disabling NAT-PMP" << std::endl;
#endif
m_disabled = true;
return;
}
address_v4 local = i->endpoint().address().to_v4();
#if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING)
m_log << to_simple_string(microsec_clock::universal_time())
@ -45,7 +86,7 @@ natpmp::natpmp(io_service& ios, portmap_callback_t const& cb)
// the local address seems to be an external
// internet address. Assume it is not behind a NAT
#if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING)
m_log << "not on a NAT. disable NAT-PMP" << std::endl;
m_log << "not on a NAT. disabling NAT-PMP" << std::endl;
#endif
m_disabled = true;
return;

View File

@ -167,10 +167,11 @@ namespace libtorrent
, boost::filesystem::path const& save_path
, entry const& resume_data
, bool compact_mode
, int block_size)
, int block_size
, storage_constructor_type sc)
{
return m_impl->add_torrent(ti, save_path, resume_data
, compact_mode, block_size);
, compact_mode, block_size, sc);
}
torrent_handle session::add_torrent(
@ -180,10 +181,11 @@ namespace libtorrent
, boost::filesystem::path const& save_path
, entry const& e
, bool compact_mode
, int block_size)
, int block_size
, storage_constructor_type sc)
{
return m_impl->add_torrent(tracker_url, info_hash, name, save_path, e
, compact_mode, block_size);
, compact_mode, block_size, sc);
}
void session::remove_torrent(const torrent_handle& h)

View File

@ -1219,7 +1219,8 @@ namespace libtorrent { namespace detail
, boost::filesystem::path const& save_path
, entry const& resume_data
, bool compact_mode
, int block_size)
, int block_size
, storage_constructor_type sc)
{
// make sure the block_size is an even power of 2
#ifndef NDEBUG
@ -1259,7 +1260,7 @@ namespace libtorrent { namespace detail
boost::shared_ptr<torrent> torrent_ptr(
new torrent(*this, m_checker_impl, ti, save_path
, m_listen_interface, compact_mode, block_size
, settings()));
, settings(), sc));
#ifndef TORRENT_DISABLE_EXTENSIONS
for (extension_list_t::iterator i = m_extensions.begin()
@ -1304,7 +1305,8 @@ namespace libtorrent { namespace detail
, boost::filesystem::path const& save_path
, entry const&
, bool compact_mode
, int block_size)
, int block_size
, storage_constructor_type sc)
{
// make sure the block_size is an even power of 2
#ifndef NDEBUG
@ -1345,7 +1347,7 @@ namespace libtorrent { namespace detail
boost::shared_ptr<torrent> torrent_ptr(
new torrent(*this, m_checker_impl, tracker_url, info_hash, name
, save_path, m_listen_interface, compact_mode, block_size
, settings()));
, settings(), sc));
#ifndef TORRENT_DISABLE_EXTENSIONS
for (extension_list_t::iterator i = m_extensions.begin()

View File

@ -341,53 +341,41 @@ namespace libtorrent
int slot;
};
class storage::impl : public thread_safe_storage, boost::noncopyable
class storage : public storage_interface, thread_safe_storage, boost::noncopyable
{
public:
impl(torrent_info const& info, path const& path, file_pool& fp)
storage(torrent_info const& info, path const& path, file_pool& fp)
: thread_safe_storage(info.num_pieces())
, info(info)
, files(fp)
, m_info(info)
, m_files(fp)
{
save_path = complete(path);
assert(save_path.is_complete());
assert(info.begin_files() != info.end_files());
m_save_path = complete(path);
assert(m_save_path.is_complete());
}
impl(impl const& x)
: thread_safe_storage(x.info.num_pieces())
, info(x.info)
, save_path(x.save_path)
, files(x.files)
{}
void release_files();
~impl()
bool move_storage(path save_path);
size_type read(char* buf, int slot, int offset, int size);
void write(const char* buf, int slot, int offset, int size);
~storage()
{
files.release(this);
m_files.release(this);
}
torrent_info const& info;
path save_path;
torrent_info const& m_info;
path m_save_path;
// the file pool is typically stored in
// the session, to make all storage
// instances use the same pool
file_pool& files;
file_pool& m_files;
};
storage::storage(torrent_info const& info, path const& path
, file_pool& fp)
: m_pimpl(new impl(info, path, fp))
{
assert(info.begin_files() != info.end_files());
}
void storage::release_files()
{
m_pimpl->files.release(m_pimpl.get());
}
void storage::swap(storage& other)
{
m_pimpl.swap(other.m_pimpl);
m_files.release(this);
}
// returns true on success
@ -396,7 +384,7 @@ namespace libtorrent
path old_path;
path new_path;
save_path = complete(save_path);
m_save_path = complete(save_path);
#if defined(_WIN32) && defined(UNICODE)
std::wstring wsave_path(safe_convert(save_path.native_file_string()));
@ -415,10 +403,10 @@ namespace libtorrent
return false;
#endif
m_pimpl->files.release(m_pimpl.get());
m_files.release(this);
old_path = m_pimpl->save_path / m_pimpl->info.name();
new_path = save_path / m_pimpl->info.name();
old_path = m_save_path / m_info.name();
new_path = save_path / m_info.name();
try
{
@ -427,7 +415,7 @@ namespace libtorrent
#else
rename(old_path, new_path);
#endif
m_pimpl->save_path = save_path;
m_save_path = save_path;
return true;
}
catch (std::exception&) {}
@ -435,15 +423,14 @@ namespace libtorrent
}
#ifndef NDEBUG
/*
void storage::shuffle()
{
int num_pieces = m_pimpl->info.num_pieces();
int num_pieces = m_info.num_pieces();
std::vector<int> pieces(num_pieces);
for (std::vector<int>::iterator i = pieces.begin();
i != pieces.end();
++i)
i != pieces.end(); ++i)
{
*i = static_cast<int>(i - pieces.begin());
}
@ -456,13 +443,13 @@ namespace libtorrent
{
const int slot_index = targets[i];
const int piece_index = pieces[i];
const int slot_size =static_cast<int>(m_pimpl->info.piece_size(slot_index));
const int slot_size =static_cast<int>(m_info.piece_size(slot_index));
std::vector<char> buf(slot_size);
read(&buf[0], piece_index, 0, slot_size);
write(&buf[0], slot_index, 0, slot_size);
}
}
*/
#endif
size_type storage::read(
@ -472,27 +459,27 @@ namespace libtorrent
, int size)
{
assert(buf != 0);
assert(slot >= 0 && slot < m_pimpl->info.num_pieces());
assert(slot >= 0 && slot < m_info.num_pieces());
assert(offset >= 0);
assert(offset < m_pimpl->info.piece_size(slot));
assert(offset < m_info.piece_size(slot));
assert(size > 0);
slot_lock lock(*m_pimpl, slot);
slot_lock lock(*this, slot);
#ifndef NDEBUG
std::vector<file_slice> slices
= m_pimpl->info.map_block(slot, offset, size);
= m_info.map_block(slot, offset, size);
assert(!slices.empty());
#endif
size_type start = slot * (size_type)m_pimpl->info.piece_length() + offset;
assert(start + size <= m_pimpl->info.total_size());
size_type start = slot * (size_type)m_info.piece_length() + offset;
assert(start + size <= m_info.total_size());
// find the file iterator and file offset
size_type file_offset = start;
std::vector<file_entry>::const_iterator file_iter;
for (file_iter = m_pimpl->info.begin_files();;)
for (file_iter = m_info.begin_files();;)
{
if (file_offset < file_iter->size)
break;
@ -501,10 +488,8 @@ namespace libtorrent
++file_iter;
}
boost::shared_ptr<file> in(m_pimpl->files.open_file(
m_pimpl.get()
, m_pimpl->save_path / file_iter->path
, file::in));
boost::shared_ptr<file> in(m_files.open_file(
this, m_save_path / file_iter->path, file::in));
assert(file_offset < file_iter->size);
@ -523,7 +508,7 @@ namespace libtorrent
#endif
int left_to_read = size;
int slot_size = static_cast<int>(m_pimpl->info.piece_size(slot));
int slot_size = static_cast<int>(m_info.piece_size(slot));
if (offset + left_to_read > slot_size)
left_to_read = slot_size - offset;
@ -549,7 +534,7 @@ namespace libtorrent
assert(int(slices.size()) > counter);
size_type slice_size = slices[counter].size;
assert(slice_size == read_bytes);
assert(m_pimpl->info.file_at(slices[counter].file_index).path
assert(m_info.file_at(slices[counter].file_index).path
== file_iter->path);
#endif
@ -575,12 +560,11 @@ namespace libtorrent
// this file was empty, don't increment the slice counter
if (read_bytes > 0) ++counter;
#endif
path path = m_pimpl->save_path / file_iter->path;
path path = m_save_path / file_iter->path;
file_offset = 0;
in = m_pimpl->files.open_file(
m_pimpl.get()
, path, file::in);
in = m_files.open_file(
this, path, file::in);
in->seek(0);
}
}
@ -597,38 +581,37 @@ namespace libtorrent
{
assert(buf != 0);
assert(slot >= 0);
assert(slot < m_pimpl->info.num_pieces());
assert(slot < m_info.num_pieces());
assert(offset >= 0);
assert(size > 0);
slot_lock lock(*m_pimpl, slot);
slot_lock lock(*this, slot);
#ifndef NDEBUG
std::vector<file_slice> slices
= m_pimpl->info.map_block(slot, offset, size);
= m_info.map_block(slot, offset, size);
assert(!slices.empty());
#endif
size_type start = slot * (size_type)m_pimpl->info.piece_length() + offset;
size_type start = slot * (size_type)m_info.piece_length() + offset;
// find the file iterator and file offset
size_type file_offset = start;
std::vector<file_entry>::const_iterator file_iter;
for (file_iter = m_pimpl->info.begin_files();;)
for (file_iter = m_info.begin_files();;)
{
if (file_offset < file_iter->size)
break;
file_offset -= file_iter->size;
++file_iter;
assert(file_iter != m_pimpl->info.end_files());
assert(file_iter != m_info.end_files());
}
path p(m_pimpl->save_path / file_iter->path);
boost::shared_ptr<file> out = m_pimpl->files.open_file(
m_pimpl.get()
, p, file::out | file::in);
path p(m_save_path / file_iter->path);
boost::shared_ptr<file> out = m_files.open_file(
this, p, file::out | file::in);
assert(file_offset < file_iter->size);
assert(slices[0].offset == file_offset);
@ -643,7 +626,7 @@ namespace libtorrent
}
int left_to_write = size;
int slot_size = static_cast<int>(m_pimpl->info.piece_size(slot));
int slot_size = static_cast<int>(m_info.piece_size(slot));
if (offset + left_to_write > slot_size)
left_to_write = slot_size - offset;
@ -667,7 +650,7 @@ namespace libtorrent
{
assert(int(slices.size()) > counter);
assert(slices[counter].size == write_bytes);
assert(m_pimpl->info.file_at(slices[counter].file_index).path
assert(m_info.file_at(slices[counter].file_index).path
== file_iter->path);
assert(buf_pos >= 0);
@ -695,21 +678,22 @@ namespace libtorrent
#endif
++file_iter;
assert(file_iter != m_pimpl->info.end_files());
path p = m_pimpl->save_path / file_iter->path;
assert(file_iter != m_info.end_files());
path p = m_save_path / file_iter->path;
file_offset = 0;
out = m_pimpl->files.open_file(
m_pimpl.get()
, p, file::out | file::in);
out = m_files.open_file(
this, p, file::out | file::in);
out->seek(0);
}
}
}
storage_interface* default_storage_constructor(torrent_info const& ti
, boost::filesystem::path const& path, file_pool& fp)
{
return new storage(ti, path, fp);
}
// -- piece_manager -----------------------------------------------------
@ -721,7 +705,8 @@ namespace libtorrent
impl(
torrent_info const& info
, path const& path
, file_pool& fp);
, file_pool& fp
, storage_constructor_type sc);
bool check_fastresume(
aux::piece_checker_data& d
@ -761,7 +746,7 @@ namespace libtorrent
bool move_storage(path save_path)
{
if (m_storage.move_storage(save_path))
if (m_storage->move_storage(save_path))
{
m_save_path = complete(save_path);
return true;
@ -788,7 +773,7 @@ namespace libtorrent
void debug_log() const;
#endif
#endif
storage m_storage;
boost::scoped_ptr<storage_interface> m_storage;
// if this is true, pieces are always allocated at the
// lowest possible slot index. If it is false, pieces
@ -871,8 +856,9 @@ namespace libtorrent
piece_manager::impl::impl(
torrent_info const& info
, path const& save_path
, file_pool& fp)
: m_storage(info, save_path, fp)
, file_pool& fp
, storage_constructor_type sc)
: m_storage(sc(info, save_path, fp))
, m_compact_mode(false)
, m_fill_mode(true)
, m_info(info)
@ -885,8 +871,9 @@ namespace libtorrent
piece_manager::piece_manager(
torrent_info const& info
, path const& save_path
, file_pool& fp)
: m_pimpl(new impl(info, save_path, fp))
, file_pool& fp
, storage_constructor_type sc)
: m_pimpl(new impl(info, save_path, fp, sc))
{
}
@ -901,7 +888,7 @@ namespace libtorrent
void piece_manager::impl::release_files()
{
m_storage.release_files();
m_storage->release_files();
}
void piece_manager::impl::export_piece_map(
@ -1003,7 +990,7 @@ namespace libtorrent
for (int i = 0; i < num_blocks-1; ++i)
{
if (!bitmask[i]) continue;
m_storage.read(
m_storage->read(
&buf[0]
, slot_index
, i * block_size
@ -1012,7 +999,7 @@ namespace libtorrent
}
if (bitmask[num_blocks - 1])
{
m_storage.read(
m_storage->read(
&buf[0]
, slot_index
, block_size * (num_blocks - 1)
@ -1024,9 +1011,9 @@ namespace libtorrent
size_type piece_manager::impl::read(
char* buf
, int piece_index
, int offset
, int size)
, int piece_index
, int offset
, int size)
{
assert(buf);
assert(offset >= 0);
@ -1035,14 +1022,14 @@ namespace libtorrent
assert(m_piece_to_slot[piece_index] >= 0 && m_piece_to_slot[piece_index] < (int)m_slot_to_piece.size());
int slot = m_piece_to_slot[piece_index];
assert(slot >= 0 && slot < (int)m_slot_to_piece.size());
return m_storage.read(buf, slot, offset, size);
return m_storage->read(buf, slot, offset, size);
}
size_type piece_manager::read(
char* buf
, int piece_index
, int offset
, int size)
, int piece_index
, int offset
, int size)
{
return m_pimpl->read(buf, piece_index, offset, size);
}
@ -1059,7 +1046,7 @@ namespace libtorrent
assert(piece_index >= 0 && piece_index < (int)m_piece_to_slot.size());
int slot = allocate_slot_for_piece(piece_index);
assert(slot >= 0 && slot < (int)m_slot_to_piece.size());
m_storage.write(buf, slot, offset, size);
m_storage->write(buf, slot, offset, size);
}
void piece_manager::write(
@ -1241,7 +1228,7 @@ namespace libtorrent
// use while debugging to find
// states that cannot be scanned
// by check_pieces.
// m_storage.shuffle();
// m_storage->shuffle();
m_piece_to_slot.resize(m_info.num_pieces(), has_no_slot);
m_slot_to_piece.resize(m_info.num_pieces(), unallocated);
@ -1389,7 +1376,7 @@ namespace libtorrent
try
{
m_storage.read(
m_storage->read(
&m_piece_data[0]
, m_current_slot
, 0
@ -1468,14 +1455,14 @@ namespace libtorrent
const int slot1_size = static_cast<int>(m_info.piece_size(piece_index));
const int slot2_size = other_piece >= 0 ? static_cast<int>(m_info.piece_size(other_piece)) : 0;
std::vector<char> buf1(slot1_size);
m_storage.read(&buf1[0], m_current_slot, 0, slot1_size);
m_storage->read(&buf1[0], m_current_slot, 0, slot1_size);
if (slot2_size > 0)
{
std::vector<char> buf2(slot2_size);
m_storage.read(&buf2[0], piece_index, 0, slot2_size);
m_storage.write(&buf2[0], m_current_slot, 0, slot2_size);
m_storage->read(&buf2[0], piece_index, 0, slot2_size);
m_storage->write(&buf2[0], m_current_slot, 0, slot2_size);
}
m_storage.write(&buf1[0], piece_index, 0, slot1_size);
m_storage->write(&buf1[0], piece_index, 0, slot1_size);
assert(m_slot_to_piece[m_current_slot] == unassigned
|| m_piece_to_slot[m_slot_to_piece[m_current_slot]] == m_current_slot);
}
@ -1501,14 +1488,14 @@ namespace libtorrent
const int slot1_size = static_cast<int>(m_info.piece_size(other_piece));
const int slot2_size = piece_index >= 0 ? static_cast<int>(m_info.piece_size(piece_index)) : 0;
std::vector<char> buf1(slot1_size);
m_storage.read(&buf1[0], other_slot, 0, slot1_size);
m_storage->read(&buf1[0], other_slot, 0, slot1_size);
if (slot2_size > 0)
{
std::vector<char> buf2(slot2_size);
m_storage.read(&buf2[0], m_current_slot, 0, slot2_size);
m_storage.write(&buf2[0], other_slot, 0, slot2_size);
m_storage->read(&buf2[0], m_current_slot, 0, slot2_size);
m_storage->write(&buf2[0], other_slot, 0, slot2_size);
}
m_storage.write(&buf1[0], m_current_slot, 0, slot1_size);
m_storage->write(&buf1[0], m_current_slot, 0, slot1_size);
assert(m_slot_to_piece[m_current_slot] == unassigned
|| m_piece_to_slot[m_slot_to_piece[m_current_slot]] == m_current_slot);
}
@ -1550,10 +1537,10 @@ namespace libtorrent
std::vector<char> buf1(static_cast<int>(slot1_size));
std::vector<char> buf2(static_cast<int>(slot3_size));
m_storage.read(&buf2[0], m_current_slot, 0, slot3_size);
m_storage.read(&buf1[0], slot1, 0, slot1_size);
m_storage.write(&buf1[0], m_current_slot, 0, slot1_size);
m_storage.write(&buf2[0], slot1, 0, slot3_size);
m_storage->read(&buf2[0], m_current_slot, 0, slot3_size);
m_storage->read(&buf1[0], slot1, 0, slot1_size);
m_storage->write(&buf1[0], m_current_slot, 0, slot1_size);
m_storage->write(&buf2[0], slot1, 0, slot3_size);
assert(m_slot_to_piece[m_current_slot] == unassigned
|| m_piece_to_slot[m_slot_to_piece[m_current_slot]] == m_current_slot);
@ -1592,15 +1579,15 @@ namespace libtorrent
std::vector<char> buf1(static_cast<int>(m_info.piece_length()));
std::vector<char> buf2(static_cast<int>(m_info.piece_length()));
m_storage.read(&buf2[0], m_current_slot, 0, slot3_size);
m_storage.read(&buf1[0], slot2, 0, slot2_size);
m_storage.write(&buf1[0], m_current_slot, 0, slot2_size);
m_storage->read(&buf2[0], m_current_slot, 0, slot3_size);
m_storage->read(&buf1[0], slot2, 0, slot2_size);
m_storage->write(&buf1[0], m_current_slot, 0, slot2_size);
if (slot1_size > 0)
{
m_storage.read(&buf1[0], slot1, 0, slot1_size);
m_storage.write(&buf1[0], slot2, 0, slot1_size);
m_storage->read(&buf1[0], slot1, 0, slot1_size);
m_storage->write(&buf1[0], slot2, 0, slot1_size);
}
m_storage.write(&buf2[0], slot1, 0, slot3_size);
m_storage->write(&buf2[0], slot1, 0, slot3_size);
assert(m_slot_to_piece[m_current_slot] == unassigned
|| m_piece_to_slot[m_slot_to_piece[m_current_slot]] == m_current_slot);
}
@ -1778,8 +1765,8 @@ namespace libtorrent
const int slot_size = static_cast<int>(m_info.piece_size(slot_index));
std::vector<char> buf(slot_size);
m_storage.read(&buf[0], piece_index, 0, slot_size);
m_storage.write(&buf[0], slot_index, 0, slot_size);
m_storage->read(&buf[0], piece_index, 0, slot_size);
m_storage->write(&buf[0], slot_index, 0, slot_size);
assert(m_slot_to_piece[piece_index] == piece_index);
assert(m_piece_to_slot[piece_index] == piece_index);
@ -1866,7 +1853,7 @@ namespace libtorrent
if (m_piece_to_slot[pos] != has_no_slot)
{
assert(m_piece_to_slot[pos] >= 0);
m_storage.read(&buffer[0], m_piece_to_slot[pos], 0, static_cast<int>(m_info.piece_size(pos)));
m_storage->read(&buffer[0], m_piece_to_slot[pos], 0, static_cast<int>(m_info.piece_size(pos)));
new_free_slot = m_piece_to_slot[pos];
m_slot_to_piece[pos] = pos;
m_piece_to_slot[pos] = pos;
@ -1877,7 +1864,7 @@ namespace libtorrent
m_free_slots.push_back(new_free_slot);
if (write_back || m_fill_mode)
m_storage.write(&buffer[0], pos, 0, static_cast<int>(m_info.piece_size(pos)));
m_storage->write(&buffer[0], pos, 0, static_cast<int>(m_info.piece_size(pos)));
}
assert(m_free_slots.size() > 0);

View File

@ -226,7 +226,8 @@ namespace libtorrent
, tcp::endpoint const& net_interface
, bool compact_mode
, int block_size
, session_settings const& s)
, session_settings const& s
, storage_constructor_type sc)
: m_torrent_file(tf)
, m_abort(false)
, m_paused(false)
@ -265,6 +266,7 @@ namespace libtorrent
, m_default_block_size(block_size)
, m_connections_initialized(true)
, m_settings(s)
, m_storage_constructor(sc)
{
#ifndef NDEBUG
m_initial_done = 0;
@ -315,7 +317,8 @@ namespace libtorrent
, tcp::endpoint const& net_interface
, bool compact_mode
, int block_size
, session_settings const& s)
, session_settings const& s
, storage_constructor_type sc)
: m_torrent_file(info_hash)
, m_abort(false)
, m_paused(false)
@ -353,6 +356,7 @@ namespace libtorrent
, m_default_block_size(block_size)
, m_connections_initialized(false)
, m_settings(s)
, m_storage_constructor(sc)
{
#ifndef NDEBUG
m_initial_done = 0;
@ -452,7 +456,8 @@ namespace libtorrent
assert(m_torrent_file.total_size() >= 0);
m_have_pieces.resize(m_torrent_file.num_pieces(), false);
m_storage.reset(new piece_manager(m_torrent_file, m_save_path, m_ses.m_files));
m_storage.reset(new piece_manager(m_torrent_file, m_save_path
, m_ses.m_files, m_storage_constructor));
m_block_size = calculate_block_size(m_torrent_file, m_default_block_size);
m_picker.reset(new piece_picker(
static_cast<int>(m_torrent_file.piece_length() / m_block_size)