Optimize FileFd.get_size/get_real_size on Windows.

GitOrigin-RevId: e39efbecdd6882bf4465b17dad556b585633b56e
This commit is contained in:
levlam 2020-01-03 02:41:57 +03:00
parent db7573769f
commit 75ecd9c692

View File

@ -22,6 +22,7 @@
#include <cstring>
#include <mutex>
#include <unordered_set>
#include <utility>
#if TD_PORT_POSIX
#include <fcntl.h>
@ -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<uint64>((filetime - FILETIME_UNIX_TIME_DIFF) * 100);
}
struct FileSize {
int64 size_;
int64 real_size_;
};
Result<FileSize> 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<int64> 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<int64> 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<uint64>((filetime - FILETIME_UNIX_TIME_DIFF) * 100);
}
#endif
Result<Stat> FileFd::stat() const {
CHECK(!empty());
#if TD_PORT_POSIX
@ -509,17 +544,9 @@ Result<Stat> 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