Optimize FileFd.get_size/get_real_size on Windows.
GitOrigin-RevId: e39efbecdd6882bf4465b17dad556b585633b56e
This commit is contained in:
parent
db7573769f
commit
75ecd9c692
@ -22,6 +22,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#if TD_PORT_POSIX
|
#if TD_PORT_POSIX
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@ -475,23 +476,57 @@ NativeFd FileFd::move_as_native_fd() {
|
|||||||
return res;
|
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 {
|
Result<int64> FileFd::get_size() const {
|
||||||
|
#if TD_PORT_POSIX
|
||||||
TRY_RESULT(s, stat());
|
TRY_RESULT(s, stat());
|
||||||
|
#else if TD_PORT_WINDOWS
|
||||||
|
TRY_RESULT(s, get_file_size(*this));
|
||||||
|
#endif
|
||||||
return s.size_;
|
return s.size_;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<int64> FileFd::get_real_size() const {
|
Result<int64> FileFd::get_real_size() const {
|
||||||
|
#if TD_PORT_POSIX
|
||||||
TRY_RESULT(s, stat());
|
TRY_RESULT(s, stat());
|
||||||
|
#else if TD_PORT_WINDOWS
|
||||||
|
TRY_RESULT(s, get_file_size(*this));
|
||||||
|
#endif
|
||||||
return s.real_size_;
|
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 {
|
Result<Stat> FileFd::stat() const {
|
||||||
CHECK(!empty());
|
CHECK(!empty());
|
||||||
#if TD_PORT_POSIX
|
#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_dir_ = (basic_info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
|
||||||
res.is_reg_ = !res.is_dir_; // TODO this is still wrong
|
res.is_reg_ = !res.is_dir_; // TODO this is still wrong
|
||||||
|
|
||||||
FILE_STANDARD_INFO standard_info;
|
TRY_RESULT(file_size, get_file_size(*this));
|
||||||
status = GetFileInformationByHandleEx(get_native_fd().fd(), FileStandardInfo, &standard_info, sizeof(standard_info));
|
res.size_ = file_size.size_;
|
||||||
if (!status) {
|
res.real_size_ = file_size.real_size_;
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user