forked from suyu/suyu
vfs_real: misc optimizations
This commit is contained in:
parent
4112031c81
commit
734242c5bc
4 changed files with 41 additions and 24 deletions
|
@ -436,7 +436,7 @@ void IterateDirEntries(const std::filesystem::path& path, const DirEntryCallable
|
||||||
|
|
||||||
if (True(filter & DirEntryFilter::File) &&
|
if (True(filter & DirEntryFilter::File) &&
|
||||||
entry.status().type() == fs::file_type::regular) {
|
entry.status().type() == fs::file_type::regular) {
|
||||||
if (!callback(entry.path())) {
|
if (!callback(entry)) {
|
||||||
callback_error = true;
|
callback_error = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -444,7 +444,7 @@ void IterateDirEntries(const std::filesystem::path& path, const DirEntryCallable
|
||||||
|
|
||||||
if (True(filter & DirEntryFilter::Directory) &&
|
if (True(filter & DirEntryFilter::Directory) &&
|
||||||
entry.status().type() == fs::file_type::directory) {
|
entry.status().type() == fs::file_type::directory) {
|
||||||
if (!callback(entry.path())) {
|
if (!callback(entry)) {
|
||||||
callback_error = true;
|
callback_error = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -493,7 +493,7 @@ void IterateDirEntriesRecursively(const std::filesystem::path& path,
|
||||||
|
|
||||||
if (True(filter & DirEntryFilter::File) &&
|
if (True(filter & DirEntryFilter::File) &&
|
||||||
entry.status().type() == fs::file_type::regular) {
|
entry.status().type() == fs::file_type::regular) {
|
||||||
if (!callback(entry.path())) {
|
if (!callback(entry)) {
|
||||||
callback_error = true;
|
callback_error = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -501,7 +501,7 @@ void IterateDirEntriesRecursively(const std::filesystem::path& path,
|
||||||
|
|
||||||
if (True(filter & DirEntryFilter::Directory) &&
|
if (True(filter & DirEntryFilter::Directory) &&
|
||||||
entry.status().type() == fs::file_type::directory) {
|
entry.status().type() == fs::file_type::directory) {
|
||||||
if (!callback(entry.path())) {
|
if (!callback(entry)) {
|
||||||
callback_error = true;
|
callback_error = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,6 @@ DECLARE_ENUM_FLAG_OPERATORS(DirEntryFilter);
|
||||||
* @returns A boolean value.
|
* @returns A boolean value.
|
||||||
* Return true to indicate whether the callback is successful, false otherwise.
|
* Return true to indicate whether the callback is successful, false otherwise.
|
||||||
*/
|
*/
|
||||||
using DirEntryCallable = std::function<bool(const std::filesystem::path& path)>;
|
using DirEntryCallable = std::function<bool(const std::filesystem::directory_entry& entry)>;
|
||||||
|
|
||||||
} // namespace Common::FS
|
} // namespace Common::FS
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "common/fs/fs.h"
|
#include "common/fs/fs.h"
|
||||||
#include "common/fs/path_util.h"
|
#include "common/fs/path_util.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
#include "core/file_sys/vfs.h"
|
||||||
#include "core/file_sys/vfs_real.h"
|
#include "core/file_sys/vfs_real.h"
|
||||||
|
|
||||||
// For FileTimeStampRaw
|
// For FileTimeStampRaw
|
||||||
|
@ -72,7 +73,8 @@ VfsEntryType RealVfsFilesystem::GetEntryType(std::string_view path_) const {
|
||||||
return VfsEntryType::File;
|
return VfsEntryType::File;
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtualFile RealVfsFilesystem::OpenFile(std::string_view path_, Mode perms) {
|
VirtualFile RealVfsFilesystem::OpenFileFromEntry(std::string_view path_, std::optional<u64> size,
|
||||||
|
Mode perms) {
|
||||||
const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault);
|
const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault);
|
||||||
|
|
||||||
if (auto it = cache.find(path); it != cache.end()) {
|
if (auto it = cache.find(path); it != cache.end()) {
|
||||||
|
@ -81,20 +83,24 @@ VirtualFile RealVfsFilesystem::OpenFile(std::string_view path_, Mode perms) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!FS::Exists(path) || !FS::IsFile(path)) {
|
if (!size && !FS::IsFile(path)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto reference = std::make_unique<FileReference>();
|
auto reference = std::make_unique<FileReference>();
|
||||||
this->InsertReferenceIntoList(*reference);
|
this->InsertReferenceIntoList(*reference);
|
||||||
|
|
||||||
auto file =
|
auto file = std::shared_ptr<RealVfsFile>(
|
||||||
std::shared_ptr<RealVfsFile>(new RealVfsFile(*this, std::move(reference), path, perms));
|
new RealVfsFile(*this, std::move(reference), path, perms, size));
|
||||||
cache[path] = file;
|
cache[path] = file;
|
||||||
|
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VirtualFile RealVfsFilesystem::OpenFile(std::string_view path_, Mode perms) {
|
||||||
|
return OpenFileFromEntry(path_, {}, perms);
|
||||||
|
}
|
||||||
|
|
||||||
VirtualFile RealVfsFilesystem::CreateFile(std::string_view path_, Mode perms) {
|
VirtualFile RealVfsFilesystem::CreateFile(std::string_view path_, Mode perms) {
|
||||||
const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault);
|
const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault);
|
||||||
cache.erase(path);
|
cache.erase(path);
|
||||||
|
@ -243,10 +249,10 @@ void RealVfsFilesystem::RemoveReferenceFromList(FileReference& reference) {
|
||||||
}
|
}
|
||||||
|
|
||||||
RealVfsFile::RealVfsFile(RealVfsFilesystem& base_, std::unique_ptr<FileReference> reference_,
|
RealVfsFile::RealVfsFile(RealVfsFilesystem& base_, std::unique_ptr<FileReference> reference_,
|
||||||
const std::string& path_, Mode perms_)
|
const std::string& path_, Mode perms_, std::optional<u64> size_)
|
||||||
: base(base_), reference(std::move(reference_)), path(path_),
|
: base(base_), reference(std::move(reference_)), path(path_),
|
||||||
parent_path(FS::GetParentPath(path_)), path_components(FS::SplitPathComponents(path_)),
|
parent_path(FS::GetParentPath(path_)), path_components(FS::SplitPathComponents(path_)),
|
||||||
perms(perms_) {}
|
size(size_), perms(perms_) {}
|
||||||
|
|
||||||
RealVfsFile::~RealVfsFile() {
|
RealVfsFile::~RealVfsFile() {
|
||||||
base.DropReference(std::move(reference));
|
base.DropReference(std::move(reference));
|
||||||
|
@ -257,8 +263,10 @@ std::string RealVfsFile::GetName() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t RealVfsFile::GetSize() const {
|
std::size_t RealVfsFile::GetSize() const {
|
||||||
base.RefreshReference(path, perms, *reference);
|
if (size) {
|
||||||
return reference->file ? reference->file->GetSize() : 0;
|
return *size;
|
||||||
|
}
|
||||||
|
return FS::GetSize(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RealVfsFile::Resize(std::size_t new_size) {
|
bool RealVfsFile::Resize(std::size_t new_size) {
|
||||||
|
@ -309,10 +317,11 @@ std::vector<VirtualFile> RealVfsDirectory::IterateEntries<RealVfsFile, VfsFile>(
|
||||||
|
|
||||||
std::vector<VirtualFile> out;
|
std::vector<VirtualFile> out;
|
||||||
|
|
||||||
const FS::DirEntryCallable callback = [this, &out](const std::filesystem::path& full_path) {
|
const FS::DirEntryCallable callback = [this,
|
||||||
const auto full_path_string = FS::PathToUTF8String(full_path);
|
&out](const std::filesystem::directory_entry& entry) {
|
||||||
|
const auto full_path_string = FS::PathToUTF8String(entry.path());
|
||||||
|
|
||||||
out.emplace_back(base.OpenFile(full_path_string, perms));
|
out.emplace_back(base.OpenFileFromEntry(full_path_string, entry.file_size(), perms));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
@ -330,8 +339,9 @@ std::vector<VirtualDir> RealVfsDirectory::IterateEntries<RealVfsDirectory, VfsDi
|
||||||
|
|
||||||
std::vector<VirtualDir> out;
|
std::vector<VirtualDir> out;
|
||||||
|
|
||||||
const FS::DirEntryCallable callback = [this, &out](const std::filesystem::path& full_path) {
|
const FS::DirEntryCallable callback = [this,
|
||||||
const auto full_path_string = FS::PathToUTF8String(full_path);
|
&out](const std::filesystem::directory_entry& entry) {
|
||||||
|
const auto full_path_string = FS::PathToUTF8String(entry.path());
|
||||||
|
|
||||||
out.emplace_back(base.OpenDirectory(full_path_string, perms));
|
out.emplace_back(base.OpenDirectory(full_path_string, perms));
|
||||||
|
|
||||||
|
@ -483,12 +493,10 @@ std::map<std::string, VfsEntryType, std::less<>> RealVfsDirectory::GetEntries()
|
||||||
|
|
||||||
std::map<std::string, VfsEntryType, std::less<>> out;
|
std::map<std::string, VfsEntryType, std::less<>> out;
|
||||||
|
|
||||||
const FS::DirEntryCallable callback = [&out](const std::filesystem::path& full_path) {
|
const FS::DirEntryCallable callback = [&out](const std::filesystem::directory_entry& entry) {
|
||||||
const auto filename = FS::PathToUTF8String(full_path.filename());
|
const auto filename = FS::PathToUTF8String(entry.path().filename());
|
||||||
|
|
||||||
out.insert_or_assign(filename,
|
out.insert_or_assign(filename,
|
||||||
FS::IsDir(full_path) ? VfsEntryType::Directory : VfsEntryType::File);
|
entry.is_directory() ? VfsEntryType::Directory : VfsEntryType::File);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <optional>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include "common/intrusive_list.h"
|
#include "common/intrusive_list.h"
|
||||||
#include "core/file_sys/mode.h"
|
#include "core/file_sys/mode.h"
|
||||||
|
@ -20,6 +21,8 @@ struct FileReference : public Common::IntrusiveListBaseNode<FileReference> {
|
||||||
};
|
};
|
||||||
|
|
||||||
class RealVfsFile;
|
class RealVfsFile;
|
||||||
|
class RealVfsDirectory;
|
||||||
|
|
||||||
class RealVfsFilesystem : public VfsFilesystem {
|
class RealVfsFilesystem : public VfsFilesystem {
|
||||||
public:
|
public:
|
||||||
RealVfsFilesystem();
|
RealVfsFilesystem();
|
||||||
|
@ -56,6 +59,11 @@ private:
|
||||||
private:
|
private:
|
||||||
void InsertReferenceIntoList(FileReference& reference);
|
void InsertReferenceIntoList(FileReference& reference);
|
||||||
void RemoveReferenceFromList(FileReference& reference);
|
void RemoveReferenceFromList(FileReference& reference);
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class RealVfsDirectory;
|
||||||
|
VirtualFile OpenFileFromEntry(std::string_view path, std::optional<u64> size,
|
||||||
|
Mode perms = Mode::Read);
|
||||||
};
|
};
|
||||||
|
|
||||||
// An implementation of VfsFile that represents a file on the user's computer.
|
// An implementation of VfsFile that represents a file on the user's computer.
|
||||||
|
@ -78,13 +86,14 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RealVfsFile(RealVfsFilesystem& base, std::unique_ptr<FileReference> reference,
|
RealVfsFile(RealVfsFilesystem& base, std::unique_ptr<FileReference> reference,
|
||||||
const std::string& path, Mode perms = Mode::Read);
|
const std::string& path, Mode perms = Mode::Read, std::optional<u64> size = {});
|
||||||
|
|
||||||
RealVfsFilesystem& base;
|
RealVfsFilesystem& base;
|
||||||
std::unique_ptr<FileReference> reference;
|
std::unique_ptr<FileReference> reference;
|
||||||
std::string path;
|
std::string path;
|
||||||
std::string parent_path;
|
std::string parent_path;
|
||||||
std::vector<std::string> path_components;
|
std::vector<std::string> path_components;
|
||||||
|
std::optional<u64> size;
|
||||||
Mode perms;
|
Mode perms;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue