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
shutdown delay.
* 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;
#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:
// the number of bytes in a regular piece
@ -590,7 +594,6 @@ namespace libtorrent
// the number of files. This is used when
// the torrent is unloaded
int m_num_files;
};
}

View File

@ -156,7 +156,10 @@ namespace libtorrent
, name(0)
, 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)
@ -211,6 +214,21 @@ namespace libtorrent
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
#ifndef TORRENT_NO_DEPRECATE
void file_storage::set_name(std::wstring const& n)

View File

@ -697,28 +697,31 @@ namespace libtorrent
#if TORRENT_USE_INVARIANT_CHECKS
t.check_invariant();
#endif
if (m_info_section_size > 0)
{
error_code ec;
m_info_section.reset(new char[m_info_section_size]);
memcpy(m_info_section.get(), t.m_info_section.get(), m_info_section_size);
if (m_info_section_size == 0) return;
error_code ec;
m_info_section.reset(new char[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
int ret =
int ret =
#endif
lazy_bdecode(m_info_section.get(), m_info_section.get()
+ m_info_section_size, m_info_dict, ec);
lazy_bdecode(m_info_section.get(), m_info_section.get()
+ m_info_section_size, m_info_dict, ec);
#ifndef BOOST_NO_EXCEPTIONS
if (ret != 0) throw libtorrent_exception(ec);
if (ret != 0) throw libtorrent_exception(ec);
#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());
TORRENT_ASSERT(m_piece_hashes < m_info_section.get() + m_info_section_size);
}
INVARIANT_CHECK;
m_piece_hashes += offset;
TORRENT_ASSERT(m_piece_hashes >= m_info_section.get());
TORRENT_ASSERT(m_piece_hashes < m_info_section.get() + m_info_section_size);
}
void torrent_info::resolve_duplicate_filenames()

View File

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

View File

@ -34,12 +34,12 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/file_storage.hpp"
#include "libtorrent/torrent_info.hpp"
#include "libtorrent/create_torrent.hpp"
#include <boost/make_shared.hpp>
using namespace libtorrent;
int test_main()
void test_storage()
{
file_storage fs;
fs.add_file("test/temporary.txt", 0x4000);
@ -90,6 +90,53 @@ int test_main()
fprintf(stderr, "%s == %s\n", p.c_str(), 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;
}

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
// are not requested web seeds
libtorrent::create_torrent t(fs, piece_size, 0x4000, libtorrent::create_torrent::optimize
| libtorrent::create_torrent::calculate_file_hashes);
libtorrent::create_torrent t(fs, piece_size, 0x4000, libtorrent::create_torrent::optimize);
char tmp[512];
if (test_url_seed)