allow padfiles of equal size to share the same filename
This commit is contained in:
parent
ed867e0062
commit
e106602f49
|
@ -59,6 +59,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/lazy_entry.hpp"
|
#include "libtorrent/lazy_entry.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
@ -637,9 +638,8 @@ namespace {
|
||||||
void torrent_info::resolve_duplicate_filenames_slow()
|
void torrent_info::resolve_duplicate_filenames_slow()
|
||||||
{
|
{
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
int cnt = 0;
|
|
||||||
|
|
||||||
std::unordered_set<std::string, string_hash_no_case, string_eq_no_case> files;
|
std::unordered_map<std::string, file_index_t, string_hash_no_case, string_eq_no_case> files;
|
||||||
|
|
||||||
std::vector<std::string> const& paths = m_files.paths();
|
std::vector<std::string> const& paths = m_files.paths();
|
||||||
files.reserve(paths.size() + aux::numeric_cast<std::size_t>(m_files.num_files()));
|
files.reserve(paths.size() + aux::numeric_cast<std::size_t>(m_files.num_files()));
|
||||||
|
@ -649,14 +649,14 @@ namespace {
|
||||||
for (auto const& i : paths)
|
for (auto const& i : paths)
|
||||||
{
|
{
|
||||||
std::string p = combine_path(m_files.name(), i);
|
std::string p = combine_path(m_files.name(), i);
|
||||||
files.insert(p);
|
files.insert({p, file_index_t{-1}});
|
||||||
while (has_parent_path(p))
|
while (has_parent_path(p))
|
||||||
{
|
{
|
||||||
p = parent_path(p);
|
p = parent_path(std::move(p));
|
||||||
// we don't want trailing slashes here
|
// we don't want trailing slashes here
|
||||||
TORRENT_ASSERT(p[p.size() - 1] == TORRENT_SEPARATOR);
|
TORRENT_ASSERT(p[p.size() - 1] == TORRENT_SEPARATOR);
|
||||||
p.resize(p.size() - 1);
|
p.resize(p.size() - 1);
|
||||||
files.insert(p);
|
files.insert({p, file_index_t{-1}});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -665,23 +665,31 @@ namespace {
|
||||||
// as long as this file already exists
|
// as long as this file already exists
|
||||||
// increase the counter
|
// increase the counter
|
||||||
std::string filename = m_files.file_path(i);
|
std::string filename = m_files.file_path(i);
|
||||||
if (!files.insert(filename).second)
|
auto const ret = files.insert({filename, i});
|
||||||
{
|
if (ret.second) continue;
|
||||||
std::string base = remove_extension(filename);
|
// pad files are allowed to collide with each-other, as long as they have
|
||||||
std::string ext = extension(filename);
|
// the same size.
|
||||||
do
|
file_index_t const other_idx = ret.first->second;
|
||||||
{
|
if (other_idx != file_index_t{-1}
|
||||||
++cnt;
|
&& (m_files.file_flags(i) & file_storage::flag_pad_file)
|
||||||
char new_ext[50];
|
&& (m_files.file_flags(other_idx) & file_storage::flag_pad_file)
|
||||||
std::snprintf(new_ext, sizeof(new_ext), ".%d%s", cnt, ext.c_str());
|
&& m_files.file_size(i) == m_files.file_size(other_idx))
|
||||||
filename = base + new_ext;
|
continue;
|
||||||
}
|
|
||||||
while (!files.insert(filename).second);
|
|
||||||
|
|
||||||
copy_on_write();
|
std::string base = remove_extension(filename);
|
||||||
m_files.rename_file(i, filename);
|
std::string ext = extension(filename);
|
||||||
|
int cnt = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
++cnt;
|
||||||
|
char new_ext[50];
|
||||||
|
std::snprintf(new_ext, sizeof(new_ext), ".%d%s", cnt, ext.c_str());
|
||||||
|
filename = base + new_ext;
|
||||||
}
|
}
|
||||||
cnt = 0;
|
while (!files.insert({filename, i}).second);
|
||||||
|
|
||||||
|
copy_on_write();
|
||||||
|
m_files.rename_file(i, filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -913,6 +913,40 @@ std::vector<lt::aux::vector<file_t, lt::file_index_t>> const test_cases
|
||||||
{"test/filler-1", 0x4000, {}, "test/filler-1"},
|
{"test/filler-1", 0x4000, {}, "test/filler-1"},
|
||||||
{"test/filler-2", 0x4000, {}, "test/filler-2"},
|
{"test/filler-2", 0x4000, {}, "test/filler-2"},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
// pad files are allowed to collide, as long as they have the same size
|
||||||
|
{"test/.pad/1234", 0x4000, file_storage::flag_pad_file, "test/.pad/1234"},
|
||||||
|
{"test/filler-1", 0x4000, {}, "test/filler-1"},
|
||||||
|
{"test/.pad/1234", 0x4000, file_storage::flag_pad_file, "test/.pad/1234"},
|
||||||
|
{"test/filler-2", 0x4000, {}, "test/filler-2"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// pad files of different sizes are NOT allowed to collide
|
||||||
|
{"test/.pad/1234", 0x8000, file_storage::flag_pad_file, "test/.pad/1234"},
|
||||||
|
{"test/filler-1", 0x4000, {}, "test/filler-1"},
|
||||||
|
{"test/.pad/1234", 0x4000, file_storage::flag_pad_file, "test/.pad/1234.1"},
|
||||||
|
{"test/filler-2", 0x4000, {}, "test/filler-2"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// pad files are NOT allowed to collide with normal files
|
||||||
|
{"test/.pad/1234", 0x4000, {}, "test/.pad/1234"},
|
||||||
|
{"test/filler-1", 0x4000, {}, "test/filler-1"},
|
||||||
|
{"test/.pad/1234", 0x4000, file_storage::flag_pad_file, "test/.pad/1234.1"},
|
||||||
|
{"test/filler-2", 0x4000, {}, "test/filler-2"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// normal files are NOT allowed to collide with pad files
|
||||||
|
{"test/.pad/1234", 0x4000, file_storage::flag_pad_file, "test/.pad/1234"},
|
||||||
|
{"test/filler-1", 0x4000, {}, "test/filler-1"},
|
||||||
|
{"test/.pad/1234", 0x4000, {}, "test/.pad/1234.1"},
|
||||||
|
{"test/filler-2", 0x4000, {}, "test/filler-2"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// pad files are NOT allowed to collide with directories
|
||||||
|
{"test/.pad/1234", 0x4000, file_storage::flag_pad_file, "test/.pad/1234.1"},
|
||||||
|
{"test/filler-1", 0x4000, {}, "test/filler-1"},
|
||||||
|
{"test/.pad/1234/filler-2", 0x4000, {}, "test/.pad/1234/filler-2"},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
void test_resolve_duplicates(aux::vector<file_t, file_index_t> const& test)
|
void test_resolve_duplicates(aux::vector<file_t, file_index_t> const& test)
|
||||||
|
|
Loading…
Reference in New Issue