some more optimizations on loading torrents
This commit is contained in:
parent
c4a294e88a
commit
89055c4c7a
|
@ -119,7 +119,7 @@ namespace libtorrent
|
|||
|
||||
// internal flags for stat_file
|
||||
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);
|
||||
TORRENT_EXTRA_EXPORT void rename(std::string const& f
|
||||
, 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 combine_path(std::string const& lhs
|
||||
, 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
|
||||
TORRENT_EXTRA_EXPORT std::string complete(std::string const& f);
|
||||
TORRENT_EXTRA_EXPORT bool is_complete(std::string const& f);
|
||||
|
|
|
@ -3003,6 +3003,10 @@ namespace libtorrent
|
|||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
62
src/file.cpp
62
src/file.cpp
|
@ -325,23 +325,30 @@ namespace libtorrent
|
|||
}
|
||||
#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)
|
||||
{
|
||||
ec.clear();
|
||||
#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
|
||||
#define GetFileAttributesEx_ GetFileAttributesExW
|
||||
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
|
||||
#define GetFileAttributesEx_ GetFileAttributesExA
|
||||
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
|
||||
WIN32_FILE_ATTRIBUTE_DATA data;
|
||||
if (!GetFileAttributesEx(f.c_str(), GetFileExInfoStandard, &data))
|
||||
|
@ -364,7 +371,7 @@ namespace libtorrent
|
|||
|
||||
// posix version
|
||||
|
||||
std::string f = convert_to_native(inf);
|
||||
std::string const& f = convert_to_native(inf);
|
||||
|
||||
struct stat ret;
|
||||
int retval;
|
||||
|
@ -403,8 +410,8 @@ namespace libtorrent
|
|||
std::wstring f2 = convert_to_wstring(newf);
|
||||
if (_wrename(f1.c_str(), f2.c_str()) < 0)
|
||||
#else
|
||||
std::string f1 = convert_to_native(inf);
|
||||
std::string f2 = convert_to_native(newf);
|
||||
std::string const& f1 = convert_to_native(inf);
|
||||
std::string const& f2 = convert_to_native(newf);
|
||||
if (::rename(f1.c_str(), f2.c_str()) < 0)
|
||||
#endif
|
||||
{
|
||||
|
@ -438,7 +445,7 @@ namespace libtorrent
|
|||
std::wstring n = convert_to_wstring(f);
|
||||
#else
|
||||
#define CreateDirectory_ CreateDirectoryA
|
||||
std::string n = convert_to_native(f);
|
||||
std::string const& n = convert_to_native(f);
|
||||
#endif
|
||||
|
||||
#ifdef TORRENT_WINDOWS
|
||||
|
@ -493,8 +500,8 @@ namespace libtorrent
|
|||
std::wstring f2 = convert_to_wstring(newf);
|
||||
#else
|
||||
#define CopyFile_ CopyFileA
|
||||
std::string f1 = convert_to_native(inf);
|
||||
std::string f2 = convert_to_native(newf);
|
||||
std::string const& f1 = convert_to_native(inf);
|
||||
std::string const& f2 = convert_to_native(newf);
|
||||
#endif
|
||||
|
||||
#ifdef TORRENT_WINDOWS
|
||||
|
@ -750,6 +757,35 @@ namespace libtorrent
|
|||
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)
|
||||
{
|
||||
TORRENT_ASSERT(!is_complete(rhs));
|
||||
|
@ -917,7 +953,7 @@ namespace libtorrent
|
|||
return;
|
||||
}
|
||||
#else // TORRENT_WINDOWS
|
||||
std::string f = convert_to_native(inf);
|
||||
std::string const& f = convert_to_native(inf);
|
||||
if (::remove(f.c_str()) < 0)
|
||||
{
|
||||
ec.assign(errno, generic_category());
|
||||
|
|
|
@ -670,21 +670,42 @@ namespace libtorrent
|
|||
TORRENT_ASSERT_PRECOND(index >= 0 && index < int(m_files.size()));
|
||||
internal_file_entry const& fe = m_files[index];
|
||||
|
||||
std::string ret;
|
||||
|
||||
// -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
|
||||
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];
|
||||
|
||||
// -1 means no path
|
||||
if (fe.path_index == -1) return combine_path(save_path, fe.filename());
|
||||
ret.reserve(save_path.size() + p.size() + fe.filename_len() + 2);
|
||||
ret.assign(save_path);
|
||||
append_path(ret, p);
|
||||
append_path(ret, fe.filename_ptr(), fe.filename_len());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string const& p = m_paths[fe.path_index];
|
||||
|
||||
if (fe.no_root_dir)
|
||||
return combine_path(save_path
|
||||
, combine_path(m_paths[fe.path_index]
|
||||
, fe.filename()));
|
||||
ret.reserve(save_path.size() + m_name.size() + p.size() + fe.filename_len() + 3);
|
||||
ret.assign(save_path);
|
||||
append_path(ret, m_name);
|
||||
append_path(ret, p);
|
||||
append_path(ret, fe.filename_ptr(), fe.filename_len());
|
||||
}
|
||||
|
||||
return combine_path(save_path
|
||||
, combine_path(m_name
|
||||
, combine_path(m_paths[fe.path_index]
|
||||
, fe.filename())));
|
||||
// a single return statement, just to make NRVO more likely to kick in
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string file_storage::file_name(int index) const
|
||||
|
|
|
@ -348,11 +348,10 @@ namespace libtorrent
|
|||
// ignore pad files
|
||||
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)
|
||||
{
|
||||
file_status s;
|
||||
std::string file_path = files().file_path(file_index, m_save_path);
|
||||
stat_file(file_path, &s, ec.ec);
|
||||
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))
|
||||
|| 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);
|
||||
|
||||
if (dir != last_path)
|
||||
|
@ -389,19 +389,21 @@ namespace libtorrent
|
|||
| file::random_access, ec);
|
||||
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)
|
||||
{
|
||||
ec.file = file_index;
|
||||
ec.operation = storage_error::fallocate;
|
||||
break;
|
||||
}
|
||||
size_t mtime = m_stat_cache.get_filetime(file_index);
|
||||
m_stat_cache.set_cache(file_index, size, mtime);
|
||||
}
|
||||
ec.ec.clear();
|
||||
}
|
||||
|
||||
// close files that were opened in write mode
|
||||
m_stat_cache.clear();
|
||||
m_pool.release(this);
|
||||
|
||||
#if TORRENT_DEBUG_FILE_LEAKS
|
||||
|
@ -463,7 +465,6 @@ namespace libtorrent
|
|||
ec.operation = storage_error::stat;
|
||||
return false;
|
||||
}
|
||||
m_stat_cache.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue