simplify and clean up the handling of name in internal_file_entry. move should be more efficient now, by not copying the name
This commit is contained in:
parent
808a615c87
commit
19dbfce9c0
|
@ -123,7 +123,7 @@ namespace libtorrent {
|
||||||
internal_file_entry& operator=(internal_file_entry&& fe) & noexcept;
|
internal_file_entry& operator=(internal_file_entry&& fe) & noexcept;
|
||||||
~internal_file_entry();
|
~internal_file_entry();
|
||||||
|
|
||||||
void set_name(char const* n, bool borrow_string = false, int string_len = 0);
|
void set_name(string_view n, bool borrow_string = false);
|
||||||
string_view filename() const;
|
string_view filename() const;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|
|
@ -106,7 +106,7 @@ namespace libtorrent {
|
||||||
// strdup is not part of the C standard. Some systems
|
// strdup is not part of the C standard. Some systems
|
||||||
// don't have it and it won't be available when building
|
// don't have it and it won't be available when building
|
||||||
// in strict ansi mode
|
// in strict ansi mode
|
||||||
char* allocate_string_copy(char const* str);
|
char* allocate_string_copy(string_view str);
|
||||||
|
|
||||||
// searches for separator ('sep') in the string 'last'.
|
// searches for separator ('sep') in the string 'last'.
|
||||||
// if found, returns the string_view representing the range from the start of
|
// if found, returns the string_view representing the range from the start of
|
||||||
|
|
|
@ -33,7 +33,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/config.hpp"
|
#include "libtorrent/config.hpp"
|
||||||
#include "libtorrent/storage.hpp"
|
#include "libtorrent/storage.hpp"
|
||||||
#include "libtorrent/disk_io_thread.hpp"
|
#include "libtorrent/disk_io_thread.hpp"
|
||||||
#include "libtorrent/string_util.hpp" // for allocate_string_copy
|
|
||||||
#include "libtorrent/disk_buffer_holder.hpp"
|
#include "libtorrent/disk_buffer_holder.hpp"
|
||||||
#include "libtorrent/aux_/alloca.hpp"
|
#include "libtorrent/aux_/alloca.hpp"
|
||||||
#include "libtorrent/aux_/throw.hpp"
|
#include "libtorrent/aux_/throw.hpp"
|
||||||
|
|
|
@ -122,7 +122,7 @@ namespace {
|
||||||
if (is_complete(path))
|
if (is_complete(path))
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(set_name);
|
TORRENT_ASSERT(set_name);
|
||||||
e.set_name(path.c_str());
|
e.set_name(path);
|
||||||
e.path_index = -2;
|
e.path_index = -2;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -137,7 +137,7 @@ namespace {
|
||||||
|
|
||||||
if (branch_path.empty())
|
if (branch_path.empty())
|
||||||
{
|
{
|
||||||
if (set_name) e.set_name(leaf.data());
|
if (set_name) e.set_name(leaf);
|
||||||
e.path_index = -1;
|
e.path_index = -1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -162,7 +162,7 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
e.path_index = get_or_add_path(branch_path);
|
e.path_index = get_or_add_path(branch_path);
|
||||||
if (set_name) e.set_name(leaf.data());
|
if (set_name) e.set_name(leaf);
|
||||||
}
|
}
|
||||||
|
|
||||||
int file_storage::get_or_add_path(string_view const path)
|
int file_storage::get_or_add_path(string_view const path)
|
||||||
|
@ -227,10 +227,8 @@ namespace {
|
||||||
, name(nullptr)
|
, name(nullptr)
|
||||||
, path_index(fe.path_index)
|
, path_index(fe.path_index)
|
||||||
{
|
{
|
||||||
if (fe.name_len == name_is_owned)
|
bool const borrow = fe.name_len != name_is_owned;
|
||||||
name = allocate_string_copy(fe.name);
|
set_name(fe.filename(), borrow);
|
||||||
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) &
|
||||||
|
@ -245,7 +243,10 @@ namespace {
|
||||||
executable_attribute = fe.executable_attribute;
|
executable_attribute = fe.executable_attribute;
|
||||||
symlink_attribute = fe.symlink_attribute;
|
symlink_attribute = fe.symlink_attribute;
|
||||||
no_root_dir = fe.no_root_dir;
|
no_root_dir = fe.no_root_dir;
|
||||||
set_name(fe.filename().to_string().c_str());
|
// if the name is not owned, don't allocate memory, we can point into the
|
||||||
|
// same metadata buffer
|
||||||
|
bool const borrow = fe.name_len != name_is_owned;
|
||||||
|
set_name(fe.filename(), borrow);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,7 +263,7 @@ namespace {
|
||||||
, name(fe.name)
|
, name(fe.name)
|
||||||
, path_index(fe.path_index)
|
, path_index(fe.path_index)
|
||||||
{
|
{
|
||||||
fe.name_len = name_is_owned;
|
fe.name_len = 0;
|
||||||
fe.name = nullptr;
|
fe.name = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,35 +282,32 @@ namespace {
|
||||||
name = fe.name;
|
name = fe.name;
|
||||||
name_len = fe.name_len;
|
name_len = fe.name_len;
|
||||||
|
|
||||||
fe.name_len = name_is_owned;
|
fe.name_len = 0;
|
||||||
fe.name = nullptr;
|
fe.name = nullptr;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if borrow_chars >= 0, don't take ownership over n, just
|
// if borrow_string is true, don't take ownership over n, just
|
||||||
// point to it. It points to borrow_chars number of characters.
|
// point to it.
|
||||||
// if borrow_chars == -1, n is a 0-terminated string that
|
// if borrow_string is false, n will be copied and owned by the
|
||||||
// should be copied.
|
// internal_file_entry.
|
||||||
void internal_file_entry::set_name(char const* n, bool const borrow_string
|
void internal_file_entry::set_name(string_view n, bool const borrow_string)
|
||||||
, int string_len)
|
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(string_len >= 0);
|
|
||||||
|
|
||||||
// we have limited space in the length field. truncate string
|
|
||||||
// if it's too long
|
|
||||||
if (string_len >= name_is_owned) string_len = name_is_owned - 1;
|
|
||||||
|
|
||||||
// free the current string, before assigning the new one
|
// free the current string, before assigning the new one
|
||||||
if (name_len == name_is_owned) delete[] name;
|
if (name_len == name_is_owned) delete[] name;
|
||||||
if (n == nullptr)
|
if (n.empty())
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(borrow_string == false);
|
TORRENT_ASSERT(borrow_string == false);
|
||||||
name = nullptr;
|
name = nullptr;
|
||||||
}
|
}
|
||||||
else if (borrow_string)
|
else if (borrow_string)
|
||||||
{
|
{
|
||||||
name = n;
|
// we have limited space in the length field. truncate string
|
||||||
name_len = aux::numeric_cast<std::uint64_t>(string_len);
|
// if it's too long
|
||||||
|
if (n.size() >= name_is_owned) n = n.substr(name_is_owned - 1);
|
||||||
|
|
||||||
|
name = n.data();
|
||||||
|
name_len = aux::numeric_cast<std::uint64_t>(n.size());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -615,7 +613,7 @@ namespace {
|
||||||
|
|
||||||
// filename is allowed to be empty, in which case we just use path
|
// filename is allowed to be empty, in which case we just use path
|
||||||
if (!filename.empty())
|
if (!filename.empty())
|
||||||
e.set_name(filename.data(), true, int(filename.size()));
|
e.set_name(filename, true);
|
||||||
|
|
||||||
e.size = aux::numeric_cast<std::uint64_t>(file_size);
|
e.size = aux::numeric_cast<std::uint64_t>(file_size);
|
||||||
e.offset = aux::numeric_cast<std::uint64_t>(m_total_size);
|
e.offset = aux::numeric_cast<std::uint64_t>(m_total_size);
|
||||||
|
@ -680,15 +678,14 @@ namespace {
|
||||||
template <class CRC>
|
template <class CRC>
|
||||||
void process_path_lowercase(
|
void process_path_lowercase(
|
||||||
std::unordered_set<std::uint32_t>& table
|
std::unordered_set<std::uint32_t>& table
|
||||||
, CRC crc
|
, CRC crc, string_view str)
|
||||||
, char const* str, int len)
|
|
||||||
{
|
{
|
||||||
if (len == 0) return;
|
if (str.empty()) return;
|
||||||
for (int i = 0; i < len; ++i, ++str)
|
for (char const c : str)
|
||||||
{
|
{
|
||||||
if (*str == TORRENT_SEPARATOR)
|
if (c == TORRENT_SEPARATOR)
|
||||||
table.insert(crc.checksum());
|
table.insert(crc.checksum());
|
||||||
crc.process_byte(to_lower(*str) & 0xff);
|
crc.process_byte(to_lower(c) & 0xff);
|
||||||
}
|
}
|
||||||
table.insert(crc.checksum());
|
table.insert(crc.checksum());
|
||||||
}
|
}
|
||||||
|
@ -707,9 +704,7 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto const& p : m_paths)
|
for (auto const& p : m_paths)
|
||||||
{
|
process_path_lowercase(table, crc, p);
|
||||||
process_path_lowercase(table, crc, p.c_str(), int(p.size()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint32_t file_storage::file_path_hash(file_index_t const index
|
std::uint32_t file_storage::file_path_hash(file_index_t const index
|
||||||
|
|
|
@ -140,13 +140,12 @@ namespace libtorrent {
|
||||||
return static_cast<int>(it - target.begin());
|
return static_cast<int>(it - target.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
char* allocate_string_copy(char const* str)
|
char* allocate_string_copy(string_view str)
|
||||||
{
|
{
|
||||||
if (str == nullptr) return nullptr;
|
if (str.empty()) return nullptr;
|
||||||
std::size_t const len = std::strlen(str);
|
auto* tmp = new char[str.size() + 1];
|
||||||
auto* tmp = new char[len + 1];
|
std::copy(str.data(), str.data() + str.size(), tmp);
|
||||||
std::copy(str, str + len, tmp);
|
tmp[str.size()] = '\0';
|
||||||
tmp[len] = '\0';
|
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue