perf: replace tr_torrentFindFile2() with tr_torrrent.findFile() (#2839)
This commit is contained in:
parent
4dd25d8112
commit
f4afb76695
|
@ -87,7 +87,7 @@ int readOrWriteBytes(
|
|||
TR_ASSERT(file_index < tor->fileCount());
|
||||
|
||||
int err = 0;
|
||||
bool const doWrite = io_mode == IoMode::Write;
|
||||
bool const do_write = io_mode == IoMode::Write;
|
||||
auto const file_size = tor->fileSize(file_index);
|
||||
TR_ASSERT(file_size == 0 || file_offset < file_size);
|
||||
TR_ASSERT(file_offset + buflen <= file_size);
|
||||
|
@ -101,35 +101,32 @@ int readOrWriteBytes(
|
|||
**** Find the fd
|
||||
***/
|
||||
|
||||
auto fd = tr_fdFileGetCached(session, tr_torrentId(tor), file_index, doWrite);
|
||||
auto fd = tr_fdFileGetCached(session, tr_torrentId(tor), file_index, do_write);
|
||||
|
||||
if (fd == TR_BAD_SYS_FILE) /* it's not cached, so open/create it now */
|
||||
if (fd == TR_BAD_SYS_FILE) // it's not cached, so open/create it now
|
||||
{
|
||||
/* see if the file exists... */
|
||||
char const* base = nullptr;
|
||||
char* subpath = nullptr;
|
||||
if (!tr_torrentFindFile2(tor, file_index, &base, &subpath, nullptr))
|
||||
auto found = tor->findFile(file_index); // see if the file exists...
|
||||
if (!found)
|
||||
{
|
||||
/* we can't read a file that doesn't exist... */
|
||||
if (!doWrite)
|
||||
if (!do_write)
|
||||
{
|
||||
err = ENOENT;
|
||||
}
|
||||
|
||||
/* figure out where the file should go, so we can create it */
|
||||
base = tr_torrentGetCurrentDir(tor);
|
||||
subpath = tr_sessionIsIncompleteFileNamingEnabled(tor->session) ? tr_torrentBuildPartial(tor, file_index) :
|
||||
tr_strvDup(tor->fileSubpath(file_index));
|
||||
// We didn't find the file that we want to write to.
|
||||
// Let's figure out where it goes so that we can create it.
|
||||
auto const base = tor->currentDir();
|
||||
auto const suffix = tor->session->isIncompleteFileNamingEnabled ? tr_torrent::PartialFileSuffix : ""sv;
|
||||
found = { {}, tr_pathbuf{ base, "/"sv, tor->fileSubpath(file_index), suffix }, std::size(base) };
|
||||
}
|
||||
|
||||
if (err == 0)
|
||||
{
|
||||
/* open (and maybe create) the file */
|
||||
auto const filename = tr_strvPath(base, subpath);
|
||||
auto const prealloc = (!doWrite || !tor->fileIsWanted(file_index)) ? TR_PREALLOCATE_NONE :
|
||||
tor->session->preallocationMode;
|
||||
// open (and maybe create) the file
|
||||
auto const prealloc = (!do_write || !tor->fileIsWanted(file_index)) ? TR_PREALLOCATE_NONE :
|
||||
tor->session->preallocationMode;
|
||||
|
||||
fd = tr_fdFileCheckout(session, tor->uniqueId, file_index, filename.c_str(), doWrite, prealloc, file_size);
|
||||
fd = tr_fdFileCheckout(session, tor->uniqueId, file_index, found->filename, do_write, prealloc, file_size);
|
||||
if (fd == TR_BAD_SYS_FILE)
|
||||
{
|
||||
err = errno;
|
||||
|
@ -137,18 +134,16 @@ int readOrWriteBytes(
|
|||
tor,
|
||||
fmt::format(
|
||||
_("Couldn't get '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", filename),
|
||||
fmt::arg("path", found->filename),
|
||||
fmt::arg("error", tr_strerror(err)),
|
||||
fmt::arg("error_code", err)));
|
||||
}
|
||||
else if (doWrite)
|
||||
else if (do_write)
|
||||
{
|
||||
/* make a note that we just created a file */
|
||||
tr_statsFileCreated(tor->session);
|
||||
}
|
||||
}
|
||||
|
||||
tr_free(subpath);
|
||||
}
|
||||
|
||||
if (err != 0)
|
||||
|
|
|
@ -601,11 +601,9 @@ void tr_torrent::setMetainfo(tr_torrent_metainfo const& tm)
|
|||
|
||||
static bool hasAnyLocalData(tr_torrent const* tor)
|
||||
{
|
||||
auto filename = std::string{};
|
||||
|
||||
for (tr_file_index_t i = 0, n = tor->fileCount(); i < n; ++i)
|
||||
{
|
||||
if (tor->findFile(filename, i))
|
||||
if (tor->findFile(i))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -642,18 +640,17 @@ static bool isNewTorrentASeed(tr_torrent* tor)
|
|||
return false;
|
||||
}
|
||||
|
||||
auto filename_buf = std::string{};
|
||||
for (tr_file_index_t i = 0, n = tor->fileCount(); i < n; ++i)
|
||||
{
|
||||
// it's not a new seed if a file is missing
|
||||
auto const found = tor->findFile(filename_buf, i);
|
||||
auto const found = tor->findFile(i);
|
||||
if (!found)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// it's not a new seed if a file is partial
|
||||
if (tr_strvEndsWith(found->filename, ".part"sv))
|
||||
if (tr_strvEndsWith(found->filename, tr_torrent::PartialFileSuffix))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -2154,31 +2151,26 @@ uint64_t tr_torrentGetBytesLeftToAllocate(tr_torrent const* tor)
|
|||
{
|
||||
TR_ASSERT(tr_isTorrent(tor));
|
||||
|
||||
uint64_t bytesLeft = 0;
|
||||
uint64_t bytes_left = 0;
|
||||
|
||||
for (tr_file_index_t i = 0, n = tor->fileCount(); i < n; ++i)
|
||||
{
|
||||
auto const file = tr_torrentFile(tor, i);
|
||||
|
||||
if (file.wanted)
|
||||
if (auto const wanted = tor->files_wanted_.fileWanted(i); !wanted)
|
||||
{
|
||||
uint64_t const length = file.length;
|
||||
char* path = tr_torrentFindFile(tor, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
bytesLeft += length;
|
||||
auto const length = tor->fileSize(i);
|
||||
bytes_left += length;
|
||||
|
||||
tr_sys_path_info info;
|
||||
if (path != nullptr && tr_sys_path_get_info(path, 0, &info) && info.type == TR_SYS_PATH_IS_FILE &&
|
||||
info.size <= length)
|
||||
{
|
||||
bytesLeft -= info.size;
|
||||
}
|
||||
|
||||
tr_free(path);
|
||||
auto const found = tor->findFile(i);
|
||||
if (found)
|
||||
{
|
||||
bytes_left -= found->size;
|
||||
}
|
||||
}
|
||||
|
||||
return bytesLeft;
|
||||
return bytes_left;
|
||||
}
|
||||
|
||||
/****
|
||||
|
@ -2276,7 +2268,7 @@ static void deleteLocalData(tr_torrent const* tor, tr_fileFunc func)
|
|||
|
||||
if (!tr_sys_path_exists(filename.c_str()))
|
||||
{
|
||||
filename += ".part"sv;
|
||||
filename += tr_torrent::PartialFileSuffix;
|
||||
|
||||
if (!tr_sys_path_exists(filename.c_str()))
|
||||
{
|
||||
|
@ -2436,22 +2428,20 @@ static void setLocationImpl(struct LocationData* const data)
|
|||
{
|
||||
auto const file_size = tor->fileSize(i);
|
||||
|
||||
char const* oldbase = nullptr;
|
||||
|
||||
if (char* sub = nullptr; tr_torrentFindFile2(tor, i, &oldbase, &sub, nullptr))
|
||||
if (auto found = tor->findFile(i); found)
|
||||
{
|
||||
auto const oldpath = tr_strvPath(oldbase, sub);
|
||||
auto const newpath = tr_strvPath(location, sub);
|
||||
auto const& oldpath = found->filename;
|
||||
auto const newpath = tr_pathbuf{ location, "/"sv, found->subpath };
|
||||
|
||||
tr_logAddTraceTor(tor, fmt::format("Found file #{}: '{}'", i, oldpath));
|
||||
|
||||
if (do_move && !tr_sys_path_is_same(oldpath.c_str(), newpath.c_str()))
|
||||
if (do_move && !tr_sys_path_is_same(oldpath, newpath))
|
||||
{
|
||||
tr_error* error = nullptr;
|
||||
|
||||
tr_logAddTraceTor(tor, fmt::format("moving '{}' to '{}'", oldpath, newpath));
|
||||
|
||||
if (!tr_moveFile(oldpath.c_str(), newpath.c_str(), &error))
|
||||
if (!tr_moveFile(oldpath, newpath, &error))
|
||||
{
|
||||
err = true;
|
||||
tr_logAddErrorTor(
|
||||
|
@ -2465,8 +2455,6 @@ static void setLocationImpl(struct LocationData* const data)
|
|||
tr_error_free(error);
|
||||
}
|
||||
}
|
||||
|
||||
tr_free(sub);
|
||||
}
|
||||
|
||||
if (data->setme_progress != nullptr)
|
||||
|
@ -2588,17 +2576,15 @@ static void tr_torrentFileCompleted(tr_torrent* tor, tr_file_index_t i)
|
|||
/* if the torrent's current filename isn't the same as the one in the
|
||||
* metadata -- for example, if it had the ".part" suffix appended to
|
||||
* it until now -- then rename it to match the one in the metadata */
|
||||
char const* base = nullptr;
|
||||
char* sub = nullptr;
|
||||
if (tr_torrentFindFile2(tor, i, &base, &sub, nullptr))
|
||||
if (auto found = tor->findFile(i); found)
|
||||
{
|
||||
if (auto const& file_subpath = tor->fileSubpath(i); file_subpath != sub)
|
||||
if (auto const& file_subpath = tor->fileSubpath(i); file_subpath != found->subpath)
|
||||
{
|
||||
auto const oldpath = tr_strvPath(base, sub);
|
||||
auto const newpath = tr_strvPath(base, file_subpath);
|
||||
auto const oldpath = tr_pathbuf{ found->base, "/"sv, found->subpath };
|
||||
auto const newpath = tr_pathbuf{ found->base, "/"sv, file_subpath };
|
||||
tr_error* error = nullptr;
|
||||
|
||||
if (!tr_sys_path_rename(oldpath.c_str(), newpath.c_str(), &error))
|
||||
if (!tr_sys_path_rename(oldpath, newpath, &error))
|
||||
{
|
||||
tr_logAddErrorTor(
|
||||
tor,
|
||||
|
@ -2611,8 +2597,6 @@ static void tr_torrentFileCompleted(tr_torrent* tor, tr_file_index_t i)
|
|||
tr_error_free(error);
|
||||
}
|
||||
}
|
||||
|
||||
tr_free(sub);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2673,8 +2657,9 @@ void tr_torrentGotBlock(tr_torrent* tor, tr_block_index_t block)
|
|||
****
|
||||
***/
|
||||
|
||||
std::optional<tr_torrent::tr_found_file_t> tr_torrent::findFile(std::string& filename, tr_file_index_t i) const
|
||||
std::optional<tr_torrent::tr_found_file_t> tr_torrent::findFile(tr_file_index_t i) const
|
||||
{
|
||||
auto filename = tr_pathbuf{};
|
||||
auto const subpath = std::string_view{ this->fileSubpath(i) };
|
||||
auto file_info = tr_sys_path_info{};
|
||||
|
||||
|
@ -2682,16 +2667,16 @@ std::optional<tr_torrent::tr_found_file_t> tr_torrent::findFile(std::string& fil
|
|||
{
|
||||
auto const base = this->downloadDir();
|
||||
|
||||
tr_buildBuf(filename, base, "/"sv, subpath);
|
||||
if (tr_sys_path_get_info(filename.c_str(), 0, &file_info))
|
||||
filename.assign(base, "/"sv, subpath);
|
||||
if (tr_sys_path_get_info(filename, 0, &file_info))
|
||||
{
|
||||
return tr_found_file_t{ file_info, filename, base };
|
||||
return tr_found_file_t{ file_info, std::move(filename), std::size(base) };
|
||||
}
|
||||
|
||||
tr_buildBuf(filename, base, "/"sv, subpath, ".part"sv);
|
||||
if (tr_sys_path_get_info(filename.c_str(), 0, &file_info))
|
||||
filename.assign(filename, base, "/"sv, subpath, PartialFileSuffix);
|
||||
if (tr_sys_path_get_info(filename, 0, &file_info))
|
||||
{
|
||||
return tr_found_file_t{ file_info, filename, base };
|
||||
return tr_found_file_t{ file_info, std::move(filename), std::size(base) };
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2699,63 +2684,33 @@ std::optional<tr_torrent::tr_found_file_t> tr_torrent::findFile(std::string& fil
|
|||
{
|
||||
auto const base = this->incompleteDir();
|
||||
|
||||
tr_buildBuf(filename, base, "/"sv, subpath);
|
||||
if (tr_sys_path_get_info(filename.c_str(), 0, &file_info))
|
||||
filename.assign(base, "/"sv, subpath);
|
||||
if (tr_sys_path_get_info(filename, 0, &file_info))
|
||||
{
|
||||
return tr_found_file_t{ file_info, filename, base };
|
||||
return tr_found_file_t{ file_info, std::move(filename), std::size(base) };
|
||||
}
|
||||
|
||||
tr_buildBuf(filename, base, "/"sv, subpath, ".part"sv);
|
||||
if (tr_sys_path_get_info(filename.c_str(), 0, &file_info))
|
||||
filename.assign(base, "/"sv, subpath, PartialFileSuffix);
|
||||
if (tr_sys_path_get_info(filename, 0, &file_info))
|
||||
{
|
||||
return tr_found_file_t{ file_info, filename, base };
|
||||
return tr_found_file_t{ file_info, std::move(filename), std::size(base) };
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
// TODO: clients that call this should call tr_torrent::findFile() instead
|
||||
bool tr_torrentFindFile2(tr_torrent const* tor, tr_file_index_t fileNum, char const** base, char** subpath, time_t* mtime)
|
||||
{
|
||||
auto filename = std::string{};
|
||||
auto const found = tor->findFile(filename, fileNum);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (base != nullptr)
|
||||
{
|
||||
*base = std::data(found->base);
|
||||
}
|
||||
|
||||
if (subpath != nullptr)
|
||||
{
|
||||
*subpath = tr_strvDup(found->subpath);
|
||||
}
|
||||
|
||||
if (mtime != nullptr)
|
||||
{
|
||||
*mtime = found->last_modified_at;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: clients that call this should call tr_torrent::findFile() instead
|
||||
char* tr_torrentFindFile(tr_torrent const* tor, tr_file_index_t fileNum)
|
||||
{
|
||||
auto filename = std::string{};
|
||||
auto const found = tor->findFile(filename, fileNum);
|
||||
return found ? tr_strdup(filename.c_str()) : nullptr;
|
||||
auto const found = tor->findFile(fileNum);
|
||||
return found ? tr_strdup(found->filename.c_str()) : nullptr;
|
||||
}
|
||||
|
||||
/* Decide whether we should be looking for files in downloadDir or incompleteDir. */
|
||||
static void refreshCurrentDir(tr_torrent* tor)
|
||||
{
|
||||
tr_interned_string dir;
|
||||
auto dir = tr_interned_string{};
|
||||
|
||||
if (std::empty(tor->incompleteDir()))
|
||||
{
|
||||
|
@ -2767,8 +2722,7 @@ static void refreshCurrentDir(tr_torrent* tor)
|
|||
}
|
||||
else
|
||||
{
|
||||
auto filename = std::string{};
|
||||
auto const found = tor->findFile(filename, 0);
|
||||
auto const found = tor->findFile(0);
|
||||
dir = found ? tr_interned_string{ found->base } : tor->incompleteDir();
|
||||
}
|
||||
|
||||
|
@ -2778,11 +2732,6 @@ static void refreshCurrentDir(tr_torrent* tor)
|
|||
tor->current_dir = dir;
|
||||
}
|
||||
|
||||
char* tr_torrentBuildPartial(tr_torrent const* tor, tr_file_index_t i)
|
||||
{
|
||||
return tr_strvDup(tr_strvJoin(tor->fileSubpath(i), ".part"sv));
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
@ -2972,14 +2921,15 @@ static int renamePath(tr_torrent* tor, char const* oldpath, char const* newname)
|
|||
|
||||
if (!tr_sys_path_exists(src.c_str())) /* check for it as a partial */
|
||||
{
|
||||
src += ".part"sv;
|
||||
src += tr_torrent::PartialFileSuffix;
|
||||
}
|
||||
|
||||
if (tr_sys_path_exists(src.c_str()))
|
||||
{
|
||||
auto const parent = tr_sys_path_dirname(src);
|
||||
auto const tgt = tr_strvEndsWith(src, ".part"sv) ? tr_strvJoin(parent, TR_PATH_DELIMITER_STR, newname, ".part"sv) :
|
||||
tr_strvPath(parent, newname);
|
||||
auto const tgt = tr_strvEndsWith(src, tr_torrent::PartialFileSuffix) ?
|
||||
tr_strvJoin(parent, TR_PATH_DELIMITER_STR, newname, tr_torrent::PartialFileSuffix) :
|
||||
tr_strvPath(parent, newname);
|
||||
|
||||
auto tmp = errno;
|
||||
bool const tgt_exists = tr_sys_path_exists(tgt.c_str());
|
||||
|
@ -3210,10 +3160,9 @@ void tr_torrent::initCheckedPieces(tr_bitfield const& checked, time_t const* mti
|
|||
auto const n = this->fileCount();
|
||||
this->file_mtimes_.resize(n);
|
||||
|
||||
auto filename = std::string{};
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
{
|
||||
auto const found = this->findFile(filename, i);
|
||||
auto const found = this->findFile(i);
|
||||
auto const mtime = found ? found->last_modified_at : 0;
|
||||
|
||||
this->file_mtimes_[i] = mtime;
|
||||
|
|
|
@ -372,20 +372,20 @@ public:
|
|||
|
||||
struct tr_found_file_t : public tr_sys_path_info
|
||||
{
|
||||
std::string& filename; // /home/foo/Downloads/torrent/01-file-one.txt
|
||||
tr_pathbuf filename; // /home/foo/Downloads/torrent/01-file-one.txt
|
||||
std::string_view base; // /home/foo/Downloads
|
||||
std::string_view subpath; // /torrent/01-file-one.txt
|
||||
|
||||
tr_found_file_t(tr_sys_path_info info, std::string& f, std::string_view b)
|
||||
tr_found_file_t(tr_sys_path_info info, tr_pathbuf&& filename_in, size_t base_len)
|
||||
: tr_sys_path_info{ info }
|
||||
, filename{ f }
|
||||
, base{ b }
|
||||
, subpath{ f.c_str() + std::size(b) + 1 }
|
||||
, filename{ std::move(filename_in) }
|
||||
, base{ filename.sv().substr(0, base_len) }
|
||||
, subpath{ filename.sv().substr(base_len + 1) }
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
std::optional<tr_found_file_t> findFile(std::string& filename, tr_file_index_t i) const;
|
||||
std::optional<tr_found_file_t> findFile(tr_file_index_t i) const;
|
||||
|
||||
/// METAINFO - TRACKERS
|
||||
|
||||
|
@ -582,6 +582,8 @@ public:
|
|||
torrent's content than any other mime-type. */
|
||||
std::string_view primaryMimeType() const;
|
||||
|
||||
static constexpr std::string_view PartialFileSuffix = std::string_view{ ".part" };
|
||||
|
||||
tr_torrent_metainfo metainfo_;
|
||||
|
||||
// TODO(ckerr): make private once some of torrent.cc's `tr_torrentFoo()` methods are member functions
|
||||
|
@ -765,27 +767,6 @@ constexpr bool tr_isTorrent(tr_torrent const* tor)
|
|||
*/
|
||||
void tr_torrentGotBlock(tr_torrent* tor, tr_block_index_t blockIndex);
|
||||
|
||||
/**
|
||||
* @brief Like tr_torrentFindFile(), but splits the filename into base and subpath.
|
||||
*
|
||||
* If the file is found, "tr_strvPath(base, subpath, nullptr)"
|
||||
* will generate the complete filename.
|
||||
*
|
||||
* @return true if the file is found, false otherwise.
|
||||
*
|
||||
* @param base if the torrent is found, this will be either
|
||||
* tor->downloadDir or tor->incompleteDir
|
||||
* @param subpath on success, this pointer is assigned a newly-allocated
|
||||
* string holding the second half of the filename.
|
||||
*/
|
||||
bool tr_torrentFindFile2(tr_torrent const*, tr_file_index_t fileNo, char const** base, char** subpath, time_t* mtime);
|
||||
|
||||
/* Returns a newly-allocated version of the tr_file.name string
|
||||
* that's been modified to denote that it's not a complete file yet.
|
||||
* In the current implementation this is done by appending ".part"
|
||||
* a la Firefox. */
|
||||
char* tr_torrentBuildPartial(tr_torrent const*, tr_file_index_t fileNo);
|
||||
|
||||
tr_peer_id_t const& tr_torrentGetPeerId(tr_torrent* tor);
|
||||
|
||||
tr_torrent_metainfo&& tr_ctorStealMetainfo(tr_ctor* ctor);
|
||||
|
|
|
@ -34,13 +34,13 @@ static bool verifyTorrent(tr_torrent* tor, bool const* stopFlag)
|
|||
auto const begin = tr_time();
|
||||
|
||||
tr_sys_file_t fd = TR_BAD_SYS_FILE;
|
||||
uint64_t filePos = 0;
|
||||
uint64_t file_pos = 0;
|
||||
bool changed = false;
|
||||
bool hadPiece = false;
|
||||
time_t lastSleptAt = 0;
|
||||
uint32_t piecePos = 0;
|
||||
tr_file_index_t fileIndex = 0;
|
||||
tr_file_index_t prevFileIndex = ~fileIndex;
|
||||
bool had_piece = false;
|
||||
time_t last_slept_at = 0;
|
||||
uint32_t piece_pos = 0;
|
||||
tr_file_index_t file_index = 0;
|
||||
tr_file_index_t prev_file_index = ~file_index;
|
||||
tr_piece_index_t piece = 0;
|
||||
auto buffer = std::vector<std::byte>(1024 * 256);
|
||||
auto sha = tr_sha1_init();
|
||||
|
@ -50,58 +50,56 @@ static bool verifyTorrent(tr_torrent* tor, bool const* stopFlag)
|
|||
|
||||
while (!*stopFlag && piece < tor->pieceCount())
|
||||
{
|
||||
auto const file_length = tor->fileSize(fileIndex);
|
||||
auto const file_length = tor->fileSize(file_index);
|
||||
|
||||
/* if we're starting a new piece... */
|
||||
if (piecePos == 0)
|
||||
if (piece_pos == 0)
|
||||
{
|
||||
hadPiece = tor->hasPiece(piece);
|
||||
had_piece = tor->hasPiece(piece);
|
||||
}
|
||||
|
||||
/* if we're starting a new file... */
|
||||
if (filePos == 0 && fd == TR_BAD_SYS_FILE && fileIndex != prevFileIndex)
|
||||
if (file_pos == 0 && fd == TR_BAD_SYS_FILE && file_index != prev_file_index)
|
||||
{
|
||||
char* const filename = tr_torrentFindFile(tor, fileIndex);
|
||||
fd = filename == nullptr ? TR_BAD_SYS_FILE :
|
||||
tr_sys_file_open(filename, TR_SYS_FILE_READ | TR_SYS_FILE_SEQUENTIAL, 0);
|
||||
tr_free(filename);
|
||||
prevFileIndex = fileIndex;
|
||||
auto const found = tor->findFile(file_index);
|
||||
fd = !found ? TR_BAD_SYS_FILE : tr_sys_file_open(found->filename, TR_SYS_FILE_READ | TR_SYS_FILE_SEQUENTIAL, 0);
|
||||
prev_file_index = file_index;
|
||||
}
|
||||
|
||||
/* figure out how much we can read this pass */
|
||||
uint64_t leftInPiece = tor->pieceSize(piece) - piecePos;
|
||||
uint64_t leftInFile = file_length - filePos;
|
||||
uint64_t bytesThisPass = std::min(leftInFile, leftInPiece);
|
||||
bytesThisPass = std::min(bytesThisPass, uint64_t(std::size(buffer)));
|
||||
uint64_t left_in_piece = tor->pieceSize(piece) - piece_pos;
|
||||
uint64_t left_in_file = file_length - file_pos;
|
||||
uint64_t bytes_this_pass = std::min(left_in_file, left_in_piece);
|
||||
bytes_this_pass = std::min(bytes_this_pass, uint64_t(std::size(buffer)));
|
||||
|
||||
/* read a bit */
|
||||
if (fd != TR_BAD_SYS_FILE)
|
||||
{
|
||||
auto numRead = uint64_t{};
|
||||
if (tr_sys_file_read_at(fd, std::data(buffer), bytesThisPass, filePos, &numRead) && numRead > 0)
|
||||
auto num_read = uint64_t{};
|
||||
if (tr_sys_file_read_at(fd, std::data(buffer), bytes_this_pass, file_pos, &num_read) && num_read > 0)
|
||||
{
|
||||
bytesThisPass = numRead;
|
||||
tr_sha1_update(sha, std::data(buffer), bytesThisPass);
|
||||
tr_sys_file_advise(fd, filePos, bytesThisPass, TR_SYS_FILE_ADVICE_DONT_NEED);
|
||||
bytes_this_pass = num_read;
|
||||
tr_sha1_update(sha, std::data(buffer), bytes_this_pass);
|
||||
tr_sys_file_advise(fd, file_pos, bytes_this_pass, TR_SYS_FILE_ADVICE_DONT_NEED);
|
||||
}
|
||||
}
|
||||
|
||||
/* move our offsets */
|
||||
leftInPiece -= bytesThisPass;
|
||||
leftInFile -= bytesThisPass;
|
||||
piecePos += bytesThisPass;
|
||||
filePos += bytesThisPass;
|
||||
left_in_piece -= bytes_this_pass;
|
||||
left_in_file -= bytes_this_pass;
|
||||
piece_pos += bytes_this_pass;
|
||||
file_pos += bytes_this_pass;
|
||||
|
||||
/* if we're finishing a piece... */
|
||||
if (leftInPiece == 0)
|
||||
if (left_in_piece == 0)
|
||||
{
|
||||
auto hash = tr_sha1_final(sha);
|
||||
auto const hasPiece = hash && *hash == tor->pieceHash(piece);
|
||||
auto const hash = tr_sha1_final(sha);
|
||||
auto const has_piece = hash && *hash == tor->pieceHash(piece);
|
||||
|
||||
if (hasPiece || hadPiece)
|
||||
if (has_piece || had_piece)
|
||||
{
|
||||
tor->setHasPiece(piece, hasPiece);
|
||||
changed |= hasPiece != hadPiece;
|
||||
tor->setHasPiece(piece, has_piece);
|
||||
changed |= has_piece != had_piece;
|
||||
}
|
||||
|
||||
tor->checked_pieces_.set(piece, true);
|
||||
|
@ -109,20 +107,20 @@ static bool verifyTorrent(tr_torrent* tor, bool const* stopFlag)
|
|||
|
||||
/* sleeping even just a few msec per second goes a long
|
||||
* way towards reducing IO load... */
|
||||
if (auto const now = tr_time(); lastSleptAt != now)
|
||||
if (auto const now = tr_time(); last_slept_at != now)
|
||||
{
|
||||
lastSleptAt = now;
|
||||
last_slept_at = now;
|
||||
tr_wait_msec(MsecToSleepPerSecondDuringVerify);
|
||||
}
|
||||
|
||||
sha = tr_sha1_init();
|
||||
++piece;
|
||||
tor->verify_progress = piece / double(tor->pieceCount());
|
||||
piecePos = 0;
|
||||
piece_pos = 0;
|
||||
}
|
||||
|
||||
/* if we're finishing a file... */
|
||||
if (leftInFile == 0)
|
||||
if (left_in_file == 0)
|
||||
{
|
||||
if (fd != TR_BAD_SYS_FILE)
|
||||
{
|
||||
|
@ -130,8 +128,8 @@ static bool verifyTorrent(tr_torrent* tor, bool const* stopFlag)
|
|||
fd = TR_BAD_SYS_FILE;
|
||||
}
|
||||
|
||||
fileIndex++;
|
||||
filePos = 0;
|
||||
++file_index;
|
||||
file_pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue