optimize copying torrent_info and file_storage objects

This commit is contained in:
Arvid Norberg 2014-12-17 05:33:16 +00:00
parent 13a9c3c78d
commit 20b4608c38
8 changed files with 95 additions and 23 deletions

View File

@ -1,3 +1,4 @@
* optimize copying torrent_info and file_storage objects
* cancel non-critical DNS lookups when shutting down, to cut down on * cancel non-critical DNS lookups when shutting down, to cut down on
shutdown delay. shutdown delay.
* greatly simplify the debug logging infrastructure. logs are now delivered * greatly simplify the debug logging infrastructure. logs are now delivered

View File

@ -534,6 +534,10 @@ namespace libtorrent
boost::int64_t file_offset(internal_file_entry const& fe) const TORRENT_DEPRECATED; boost::int64_t file_offset(internal_file_entry const& fe) const TORRENT_DEPRECATED;
#endif #endif
// if the backing buffer changed for this storage, this is the pointer
// offset to add to any pointers to make them point into the new buffer
void apply_pointer_offset(ptrdiff_t off);
private: private:
// the number of bytes in a regular piece // the number of bytes in a regular piece
@ -590,7 +594,6 @@ namespace libtorrent
// the number of files. This is used when // the number of files. This is used when
// the torrent is unloaded // the torrent is unloaded
int m_num_files; int m_num_files;
}; };
} }

View File

@ -156,7 +156,10 @@ namespace libtorrent
, name(0) , name(0)
, path_index(fe.path_index) , path_index(fe.path_index)
{ {
set_name(fe.filename().c_str()); if (fe.name_len == name_is_owned)
name = allocate_string_copy(fe.name);
else
name = fe.name;
} }
internal_file_entry& internal_file_entry::operator=(internal_file_entry const& fe) internal_file_entry& internal_file_entry::operator=(internal_file_entry const& fe)
@ -211,6 +214,21 @@ namespace libtorrent
return name ? name : ""; return name ? name : "";
} }
void file_storage::apply_pointer_offset(ptrdiff_t off)
{
for (int i = 0; i < m_files.size(); ++i)
{
if (m_files[i].name_len == internal_file_entry::name_is_owned) continue;
m_files[i].name += off;
}
for (int i = 0; i < m_file_hashes.size(); ++i)
{
if (m_file_hashes[i] == NULL) continue;
m_file_hashes[i] += off;
}
}
#if TORRENT_USE_WSTRING #if TORRENT_USE_WSTRING
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
void file_storage::set_name(std::wstring const& n) void file_storage::set_name(std::wstring const& n)

View File

@ -697,28 +697,31 @@ namespace libtorrent
#if TORRENT_USE_INVARIANT_CHECKS #if TORRENT_USE_INVARIANT_CHECKS
t.check_invariant(); t.check_invariant();
#endif #endif
if (m_info_section_size > 0) if (m_info_section_size == 0) return;
{
error_code ec; error_code ec;
m_info_section.reset(new char[m_info_section_size]); m_info_section.reset(new char[m_info_section_size]);
memcpy(m_info_section.get(), t.m_info_section.get(), m_info_section_size); memcpy(m_info_section.get(), t.m_info_section.get(), m_info_section_size);
ptrdiff_t offset = m_info_section.get() - t.m_info_section.get();
m_files.apply_pointer_offset(offset);
if (m_orig_files)
const_cast<file_storage&>(*m_orig_files).apply_pointer_offset(offset);
#if TORRENT_USE_ASSERTS || !defined BOOST_NO_EXCEPTIONS #if TORRENT_USE_ASSERTS || !defined BOOST_NO_EXCEPTIONS
int ret = int ret =
#endif #endif
lazy_bdecode(m_info_section.get(), m_info_section.get() lazy_bdecode(m_info_section.get(), m_info_section.get()
+ m_info_section_size, m_info_dict, ec); + m_info_section_size, m_info_dict, ec);
#ifndef BOOST_NO_EXCEPTIONS #ifndef BOOST_NO_EXCEPTIONS
if (ret != 0) throw libtorrent_exception(ec); if (ret != 0) throw libtorrent_exception(ec);
#endif #endif
TORRENT_ASSERT(ret == 0); TORRENT_ASSERT(ret == 0);
ptrdiff_t offset = m_info_section.get() - t.m_info_section.get(); m_piece_hashes += offset;
TORRENT_ASSERT(m_piece_hashes >= m_info_section.get());
m_piece_hashes += offset; TORRENT_ASSERT(m_piece_hashes < m_info_section.get() + m_info_section_size);
TORRENT_ASSERT(m_piece_hashes >= m_info_section.get());
TORRENT_ASSERT(m_piece_hashes < m_info_section.get() + m_info_section_size);
}
INVARIANT_CHECK;
} }
void torrent_info::resolve_duplicate_filenames() void torrent_info::resolve_duplicate_filenames()

View File

@ -113,6 +113,7 @@ EXTRA_DIST = Jamfile \
test_torrents/invalid_file_size.torrent \ test_torrents/invalid_file_size.torrent \
test_torrents/empty_path_multi.torrent \ test_torrents/empty_path_multi.torrent \
test_torrents/duplicate_web_seeds.torrent \ test_torrents/duplicate_web_seeds.torrent \
test_torrents/sample.torrent \
eztv.xml \ eztv.xml \
kat.xml \ kat.xml \
cb.xml \ cb.xml \

View File

@ -34,12 +34,12 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/file_storage.hpp" #include "libtorrent/file_storage.hpp"
#include "libtorrent/torrent_info.hpp" #include "libtorrent/torrent_info.hpp"
#include "libtorrent/create_torrent.hpp" #include "libtorrent/create_torrent.hpp"
#include <boost/make_shared.hpp>
using namespace libtorrent; using namespace libtorrent;
int test_main() void test_storage()
{ {
file_storage fs; file_storage fs;
fs.add_file("test/temporary.txt", 0x4000); fs.add_file("test/temporary.txt", 0x4000);
@ -90,6 +90,53 @@ int test_main()
fprintf(stderr, "%s == %s\n", p.c_str(), filenames[i]); fprintf(stderr, "%s == %s\n", p.c_str(), filenames[i]);
TEST_CHECK(p == filenames[i]); TEST_CHECK(p == filenames[i]);
} }
}
void test_copy()
{
boost::shared_ptr<torrent_info> a(boost::make_shared<torrent_info>(
libtorrent::combine_path("..", libtorrent::combine_path("test_torrents", "sample.torrent"))));
boost::shared_ptr<torrent_info> b(boost::make_shared<torrent_info>(*a));
// clear out the buffer for a, just to make sure b doesn't have any
// references into it by mistake
int s = a->metadata_size();
memset(a->metadata().get(), 0, s);
a.reset();
TEST_EQUAL(b->num_files(), 3);
char const* expected_files[] =
{
"sample/text_file2.txt",
"sample/.____padding_file/0",
"sample/text_file.txt",
};
sha1_hash file_hashes[] =
{
sha1_hash(0),
sha1_hash(0),
sha1_hash("abababababababababab")
};
for (int i = 0; i < b->num_files(); ++i)
{
std::string p = b->file_at(i).path;
convert_path_to_posix(p);
TEST_EQUAL(p, expected_files[i]);
fprintf(stderr, "%s\n", p.c_str());
TEST_EQUAL(b->files().hash(i), file_hashes[i]);
}
}
int test_main()
{
test_storage();
test_copy();
return 0; return 0;
} }

Binary file not shown.

View File

@ -317,8 +317,7 @@ int EXPORT run_http_suite(int proxy, char const* protocol, bool test_url_seed
// generate a torrent with pad files to make sure they // generate a torrent with pad files to make sure they
// are not requested web seeds // are not requested web seeds
libtorrent::create_torrent t(fs, piece_size, 0x4000, libtorrent::create_torrent::optimize libtorrent::create_torrent t(fs, piece_size, 0x4000, libtorrent::create_torrent::optimize);
| libtorrent::create_torrent::calculate_file_hashes);
char tmp[512]; char tmp[512];
if (test_url_seed) if (test_url_seed)