some more optimizations on loading torrents

This commit is contained in:
Arvid Norberg 2015-02-18 03:32:49 +00:00
parent c4a294e88a
commit 89055c4c7a
5 changed files with 96 additions and 30 deletions

View File

@ -119,7 +119,7 @@ namespace libtorrent
// internal flags for stat_file // internal flags for stat_file
enum { dont_follow_links = 1 }; enum { dont_follow_links = 1 };
TORRENT_EXTRA_EXPORT void stat_file(std::string f, file_status* s TORRENT_EXTRA_EXPORT void stat_file(std::string const& f, file_status* s
, error_code& ec, int flags = 0); , error_code& ec, int flags = 0);
TORRENT_EXTRA_EXPORT void rename(std::string const& f TORRENT_EXTRA_EXPORT void rename(std::string const& f
, std::string const& newf, error_code& ec); , std::string const& newf, error_code& ec);
@ -157,6 +157,10 @@ namespace libtorrent
TORRENT_EXTRA_EXPORT std::string filename(std::string const& f); TORRENT_EXTRA_EXPORT std::string filename(std::string const& f);
TORRENT_EXTRA_EXPORT std::string combine_path(std::string const& lhs TORRENT_EXTRA_EXPORT std::string combine_path(std::string const& lhs
, std::string const& rhs); , std::string const& rhs);
TORRENT_EXTRA_EXPORT void append_path(std::string& branch
, std::string const& leaf);
TORRENT_EXTRA_EXPORT void append_path(std::string& branch
, char const* str, int len);
// internal used by create_torrent.hpp // internal used by create_torrent.hpp
TORRENT_EXTRA_EXPORT std::string complete(std::string const& f); TORRENT_EXTRA_EXPORT std::string complete(std::string const& f);
TORRENT_EXTRA_EXPORT bool is_complete(std::string const& f); TORRENT_EXTRA_EXPORT bool is_complete(std::string const& f);

View File

@ -3003,6 +3003,10 @@ namespace libtorrent
} }
else else
{ {
// do this to trigger parsing of the info-dict here. It's better
// than to have it be done in the network thread. It has enough to
// do as it is.
std::string cert = t->ssl_cert();
j->buffer = (char*)t; j->buffer = (char*)t;
} }

View File

@ -325,23 +325,30 @@ namespace libtorrent
} }
#endif #endif
void stat_file(std::string inf, file_status* s void stat_file(std::string const& inf, file_status* s
, error_code& ec, int flags) , error_code& ec, int flags)
{ {
ec.clear(); ec.clear();
#ifdef TORRENT_WINDOWS #ifdef TORRENT_WINDOWS
// apparently windows doesn't expect paths
// to directories to ever end with a \ or /
if (!inf.empty() && (inf[inf.size() - 1] == '\\'
|| inf[inf.size() - 1] == '/'))
inf.resize(inf.size() - 1);
#if TORRENT_USE_WSTRING && defined TORRENT_WINDOWS #if TORRENT_USE_WSTRING && defined TORRENT_WINDOWS
#define GetFileAttributesEx_ GetFileAttributesExW #define GetFileAttributesEx_ GetFileAttributesExW
std::wstring f = convert_to_wstring(inf); std::wstring f = convert_to_wstring(inf);
// apparently windows doesn't expect paths
// to directories to ever end with a \ or /
if (!f.empty() && (f[f.size() - 1] == L'\\'
|| f[f.size() - 1] == L'/'))
f.resize(f.size() - 1);
#else #else
#define GetFileAttributesEx_ GetFileAttributesExA #define GetFileAttributesEx_ GetFileAttributesExA
std::string f = convert_to_native(inf); std::string f = convert_to_native(inf);
// apparently windows doesn't expect paths
// to directories to ever end with a \ or /
if (!f.empty() && (f[f.size() - 1] == '\\'
|| f[f.size() - 1] == '/'))
f.resize(f.size() - 1);
#endif #endif
WIN32_FILE_ATTRIBUTE_DATA data; WIN32_FILE_ATTRIBUTE_DATA data;
if (!GetFileAttributesEx(f.c_str(), GetFileExInfoStandard, &data)) if (!GetFileAttributesEx(f.c_str(), GetFileExInfoStandard, &data))
@ -364,7 +371,7 @@ namespace libtorrent
// posix version // posix version
std::string f = convert_to_native(inf); std::string const& f = convert_to_native(inf);
struct stat ret; struct stat ret;
int retval; int retval;
@ -403,8 +410,8 @@ namespace libtorrent
std::wstring f2 = convert_to_wstring(newf); std::wstring f2 = convert_to_wstring(newf);
if (_wrename(f1.c_str(), f2.c_str()) < 0) if (_wrename(f1.c_str(), f2.c_str()) < 0)
#else #else
std::string f1 = convert_to_native(inf); std::string const& f1 = convert_to_native(inf);
std::string f2 = convert_to_native(newf); std::string const& f2 = convert_to_native(newf);
if (::rename(f1.c_str(), f2.c_str()) < 0) if (::rename(f1.c_str(), f2.c_str()) < 0)
#endif #endif
{ {
@ -438,7 +445,7 @@ namespace libtorrent
std::wstring n = convert_to_wstring(f); std::wstring n = convert_to_wstring(f);
#else #else
#define CreateDirectory_ CreateDirectoryA #define CreateDirectory_ CreateDirectoryA
std::string n = convert_to_native(f); std::string const& n = convert_to_native(f);
#endif #endif
#ifdef TORRENT_WINDOWS #ifdef TORRENT_WINDOWS
@ -493,8 +500,8 @@ namespace libtorrent
std::wstring f2 = convert_to_wstring(newf); std::wstring f2 = convert_to_wstring(newf);
#else #else
#define CopyFile_ CopyFileA #define CopyFile_ CopyFileA
std::string f1 = convert_to_native(inf); std::string const& f1 = convert_to_native(inf);
std::string f2 = convert_to_native(newf); std::string const& f2 = convert_to_native(newf);
#endif #endif
#ifdef TORRENT_WINDOWS #ifdef TORRENT_WINDOWS
@ -750,6 +757,35 @@ namespace libtorrent
return std::string(sep + 1); return std::string(sep + 1);
} }
void append_path(std::string& branch, std::string const& leaf)
{
append_path(branch, leaf.c_str(), leaf.size());
}
void append_path(std::string& branch
, char const* str, int len)
{
TORRENT_ASSERT(!is_complete(std::string(str, len)));
if (branch.empty() || branch == ".")
{
branch.assign(str, len);
return;
}
if (len == 0) return;
#if defined(TORRENT_WINDOWS) || defined(TORRENT_OS2)
#define TORRENT_SEPARATOR_CHAR '\\'
bool need_sep = branch[branch.size()-1] != '\\'
&& branch[branch.size()-1] != '/';
#else
#define TORRENT_SEPARATOR_CHAR '/'
bool need_sep = branch[branch.size()-1] != '/';
#endif
if (need_sep) branch += TORRENT_SEPARATOR_CHAR;
branch.append(str, len);
}
std::string combine_path(std::string const& lhs, std::string const& rhs) std::string combine_path(std::string const& lhs, std::string const& rhs)
{ {
TORRENT_ASSERT(!is_complete(rhs)); TORRENT_ASSERT(!is_complete(rhs));
@ -917,7 +953,7 @@ namespace libtorrent
return; return;
} }
#else // TORRENT_WINDOWS #else // TORRENT_WINDOWS
std::string f = convert_to_native(inf); std::string const& f = convert_to_native(inf);
if (::remove(f.c_str()) < 0) if (::remove(f.c_str()) < 0)
{ {
ec.assign(errno, generic_category()); ec.assign(errno, generic_category());

View File

@ -670,21 +670,42 @@ namespace libtorrent
TORRENT_ASSERT_PRECOND(index >= 0 && index < int(m_files.size())); TORRENT_ASSERT_PRECOND(index >= 0 && index < int(m_files.size()));
internal_file_entry const& fe = m_files[index]; internal_file_entry const& fe = m_files[index];
std::string ret;
// -2 means this is an absolute path filename // -2 means this is an absolute path filename
if (fe.path_index == -2) return fe.filename(); if (fe.path_index == -2)
{
ret.assign(fe.filename_ptr(), fe.filename_len());
}
else if (fe.path_index == -1)
{
// -1 means no path // -1 means no path
if (fe.path_index == -1) return combine_path(save_path, fe.filename()); ret.reserve(save_path.size() + fe.filename_len() + 1);
ret.assign(save_path);
append_path(ret, fe.filename_ptr(), fe.filename_len());
}
else if (fe.no_root_dir)
{
std::string const& p = m_paths[fe.path_index];
if (fe.no_root_dir) ret.reserve(save_path.size() + p.size() + fe.filename_len() + 2);
return combine_path(save_path ret.assign(save_path);
, combine_path(m_paths[fe.path_index] append_path(ret, p);
, fe.filename())); append_path(ret, fe.filename_ptr(), fe.filename_len());
}
else
{
std::string const& p = m_paths[fe.path_index];
return combine_path(save_path ret.reserve(save_path.size() + m_name.size() + p.size() + fe.filename_len() + 3);
, combine_path(m_name ret.assign(save_path);
, combine_path(m_paths[fe.path_index] append_path(ret, m_name);
, fe.filename()))); append_path(ret, p);
append_path(ret, fe.filename_ptr(), fe.filename_len());
}
// a single return statement, just to make NRVO more likely to kick in
return ret;
} }
std::string file_storage::file_name(int index) const std::string file_storage::file_name(int index) const

View File

@ -348,11 +348,10 @@ namespace libtorrent
// ignore pad files // ignore pad files
if (files().pad_file_at(file_index)) continue; if (files().pad_file_at(file_index)) continue;
std::string file_path = files().file_path(file_index, m_save_path);
if (m_stat_cache.get_filesize(file_index) == stat_cache::not_in_cache) if (m_stat_cache.get_filesize(file_index) == stat_cache::not_in_cache)
{ {
file_status s; file_status s;
std::string file_path = files().file_path(file_index, m_save_path);
stat_file(file_path, &s, ec.ec); stat_file(file_path, &s, ec.ec);
if (ec && ec.ec != boost::system::errc::no_such_file_or_directory) if (ec && ec.ec != boost::system::errc::no_such_file_or_directory)
{ {
@ -370,6 +369,7 @@ namespace libtorrent
if ((!ec && m_stat_cache.get_filesize(file_index) > files().file_size(file_index)) if ((!ec && m_stat_cache.get_filesize(file_index) > files().file_size(file_index))
|| files().file_size(file_index) == 0) || files().file_size(file_index) == 0)
{ {
std::string file_path = files().file_path(file_index, m_save_path);
std::string dir = parent_path(file_path); std::string dir = parent_path(file_path);
if (dir != last_path) if (dir != last_path)
@ -389,19 +389,21 @@ namespace libtorrent
| file::random_access, ec); | file::random_access, ec);
if (ec) return; if (ec) return;
f->set_size(files().file_size(file_index), ec.ec); boost::int64_t size = files().file_size(file_index);
f->set_size(size, ec.ec);
if (ec) if (ec)
{ {
ec.file = file_index; ec.file = file_index;
ec.operation = storage_error::fallocate; ec.operation = storage_error::fallocate;
break; break;
} }
size_t mtime = m_stat_cache.get_filetime(file_index);
m_stat_cache.set_cache(file_index, size, mtime);
} }
ec.ec.clear(); ec.ec.clear();
} }
// close files that were opened in write mode // close files that were opened in write mode
m_stat_cache.clear();
m_pool.release(this); m_pool.release(this);
#if TORRENT_DEBUG_FILE_LEAKS #if TORRENT_DEBUG_FILE_LEAKS
@ -463,7 +465,6 @@ namespace libtorrent
ec.operation = storage_error::stat; ec.operation = storage_error::stat;
return false; return false;
} }
m_stat_cache.clear();
return false; return false;
} }