From 75ecd9c6920c55d48295fad65fcc3a7da481f4a4 Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 3 Jan 2020 02:41:57 +0300 Subject: [PATCH] Optimize FileFd.get_size/get_real_size on Windows. GitOrigin-RevId: e39efbecdd6882bf4465b17dad556b585633b56e --- tdutils/td/utils/port/FileFd.cpp | 63 +++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 18 deletions(-) diff --git a/tdutils/td/utils/port/FileFd.cpp b/tdutils/td/utils/port/FileFd.cpp index 2f65df61..df55b90a 100644 --- a/tdutils/td/utils/port/FileFd.cpp +++ b/tdutils/td/utils/port/FileFd.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #if TD_PORT_POSIX #include @@ -475,23 +476,57 @@ NativeFd FileFd::move_as_native_fd() { return res; } +#if TD_PORT_WINDOWS +namespace { + +uint64 filetime_to_unix_time_nsec(LONGLONG filetime) { + const auto FILETIME_UNIX_TIME_DIFF = 116444736000000000ll; + return static_cast((filetime - FILETIME_UNIX_TIME_DIFF) * 100); +} + +struct FileSize { + int64 size_; + int64 real_size_; +}; + +Result get_file_size(const FileFd &file_fd) { + FILE_STANDARD_INFO standard_info; + if (!GetFileInformationByHandleEx(file_fd.get_native_fd().fd(), FileStandardInfo, &standard_info, + sizeof(standard_info))) { + return OS_ERROR("Get FileStandardInfo failed"); + } + FileSize res; + res.size_ = standard_info.EndOfFile.QuadPart; + res.real_size_ = standard_info.AllocationSize.QuadPart; + + if (res.size_ > 0 && res.real_size_ <= 0) { + res.real_size_ = res.size_; // just in case + } + + return res; +} + +} // namespace +#endif + Result FileFd::get_size() const { +#if TD_PORT_POSIX TRY_RESULT(s, stat()); +#else if TD_PORT_WINDOWS + TRY_RESULT(s, get_file_size(*this)); +#endif return s.size_; } Result FileFd::get_real_size() const { +#if TD_PORT_POSIX TRY_RESULT(s, stat()); +#else if TD_PORT_WINDOWS + TRY_RESULT(s, get_file_size(*this)); +#endif return s.real_size_; } -#if TD_PORT_WINDOWS -static uint64 filetime_to_unix_time_nsec(LONGLONG filetime) { - const auto FILETIME_UNIX_TIME_DIFF = 116444736000000000ll; - return static_cast((filetime - FILETIME_UNIX_TIME_DIFF) * 100); -} -#endif - Result FileFd::stat() const { CHECK(!empty()); #if TD_PORT_POSIX @@ -509,17 +544,9 @@ Result FileFd::stat() const { res.is_dir_ = (basic_info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; res.is_reg_ = !res.is_dir_; // TODO this is still wrong - FILE_STANDARD_INFO standard_info; - status = GetFileInformationByHandleEx(get_native_fd().fd(), FileStandardInfo, &standard_info, sizeof(standard_info)); - if (!status) { - return OS_ERROR("Get FileStandardInfo failed"); - } - res.size_ = standard_info.EndOfFile.QuadPart; - res.real_size_ = standard_info.AllocationSize.QuadPart; - - if (res.size_ != 0 && res.real_size_ <= 0 ) { - res.real_size_ = res.size_; // just in case - } + TRY_RESULT(file_size, get_file_size(*this)); + res.size_ = file_size.size_; + res.real_size_ = file_size.real_size_; return res; #endif