Skip to content

Commit

Permalink
fs: Remove stat when readding dirent entries (this is too expensive)
Browse files Browse the repository at this point in the history
  • Loading branch information
joel16 committed Aug 8, 2022
1 parent 38bf2b8 commit dc9c250
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 58 deletions.
4 changes: 2 additions & 2 deletions include/popups.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ namespace Popups {

void ArchivePopup(void);
void DeletePopup(WindowData &data);
void FilePropertiesPopup(WindowData &data);
void ImageProperties(bool &state, Tex &texture);
void FilePropertiesPopup(WindowData &data, bool &file_stat);
void ImageProperties(bool &state, Tex &texture, bool &file_stat);
void OptionsPopup(WindowData &data);
void UpdatePopup(bool &state, bool &connection_status, bool &available, const std::string &tag);
void ProgressBar(float offset, float size, const std::string &title, const std::string &text);
Expand Down
2 changes: 1 addition & 1 deletion include/windows.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,5 @@ namespace Windows {
void ExitWindow(void);
void ResetCheckbox(WindowData &data);
void MainWindow(WindowData &data, u64 &key, bool progress);
void ImageViewer(bool &properties);
void ImageViewer(bool &properties, bool &file_stat);
}
25 changes: 8 additions & 17 deletions source/fs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,34 +52,25 @@ namespace FS {
bool GetDirList(const std::string &device, const std::string &path, std::vector<FsDirectoryEntry> &entries) {
DIR *dir = nullptr;
struct dirent *d_entry = nullptr;

std::string full_path = device + path;
dir = opendir(full_path.c_str());
entries.clear();

if (dir) {
FsDirectoryEntry parent_entry = { 0 };
std::strncpy(parent_entry.name, "..", 3);
FsDirectoryEntry parent_entry;
std::memset(std::addressof(parent_entry), 0, sizeof(FsDirectoryEntry));
std::snprintf(parent_entry.name, 3, "..");
parent_entry.type = FsDirEntryType_Dir;
entries.push_back(parent_entry);

while((d_entry = readdir(dir))) {
FsDirectoryEntry entry = { 0 };
FsDirectoryEntry entry;
std::memset(std::addressof(entry), 0, sizeof(FsDirectoryEntry));

std::strncpy(entry.name, d_entry->d_name, FS_MAX_PATH);
std::snprintf(entry.name, FS_MAX_PATH, d_entry->d_name);
entry.type = (d_entry->d_type & DT_DIR)? FsDirEntryType_Dir : FsDirEntryType_File;

if (entry.type == FsDirEntryType_File) {
std::string path;
struct stat file_stat = { 0 };
entry.file_size = 0;

std::string file_path = full_path;
file_path.append(cwd.compare("/") == 0? "" : "/");
file_path.append(entry.name);

if (!stat(file_path.c_str(), std::addressof(file_stat)))
entry.file_size = file_stat.st_size;
}
entry.file_size = 0;

entries.push_back(entry);
}
Expand Down
6 changes: 3 additions & 3 deletions source/image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ namespace ImageViewer {

void HandleControls(u64 &key, bool &properties) {
if (key & HidNpadButton_X)
properties = !properties;
properties = true;

if (ImGui::IsKeyDown(ImGuiKey_GamepadDpadDown)) {
data.zoom_factor -= 0.5f * ImGui::GetIO().DeltaTime;
Expand Down Expand Up @@ -106,7 +106,7 @@ namespace ImageViewer {
}

namespace Windows {
void ImageViewer(bool &properties) {
void ImageViewer(bool &properties, bool &file_stat) {
Windows::SetupWindow();

ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
Expand All @@ -131,7 +131,7 @@ namespace Windows {
}

if (properties)
Popups::ImageProperties(properties, data.textures[0]);
Popups::ImageProperties(properties, data.textures[0], file_stat);

Windows::ExitWindow();
ImGui::PopStyleVar();
Expand Down
32 changes: 23 additions & 9 deletions source/popups/properties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,30 @@
#include "utils.hpp"

namespace Popups {
static std::size_t size = 0;

static char *FormatDate(char *string, time_t timestamp) {
strftime(string, 36, "%Y/%m/%d %H:%M:%S", localtime(std::addressof(timestamp)));
return string;
}

void FilePropertiesPopup(WindowData &data) {
void FilePropertiesPopup(WindowData &data, bool &file_stat) {
Popups::SetupPopup(strings[cfg.lang][Lang::OptionsProperties]);

if (ImGui::BeginPopupModal(strings[cfg.lang][Lang::OptionsProperties], nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
std::string name_text = strings[cfg.lang][Lang::PropertiesName] + std::string(data.entries[data.selected].name);
ImGui::Text(name_text.c_str());

if (data.entries[data.selected].type == FsDirEntryType_File) {
char size[16];
Utils::GetSizeString(size, static_cast<double>(data.entries[data.selected].file_size));
if (!file_stat) {
FS::GetFileSize(data.entries[data.selected].name, size);
file_stat = true;
}

char size_str[16];
Utils::GetSizeString(size_str, static_cast<double>(size));
std::string size_text = strings[cfg.lang][Lang::PropertiesSize];
size_text.append(size);
size_text.append(size_str);
ImGui::Text(size_text.c_str());
}

Expand All @@ -49,6 +56,7 @@ namespace Popups {
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing

if (ImGui::Button(strings[cfg.lang][Lang::ButtonOK], ImVec2(120, 0))) {
file_stat = false;
ImGui::CloseCurrentPopup();
data.state = WINDOW_STATE_OPTIONS;
}
Expand All @@ -57,7 +65,7 @@ namespace Popups {
Popups::ExitPopup();
}

void ImageProperties(bool &state, Tex &texture) {
void ImageProperties(bool &state, Tex &texture, bool &file_stat) {
Popups::SetupPopup(strings[cfg.lang][Lang::OptionsProperties]);

std::string new_width, new_height;
Expand All @@ -74,11 +82,16 @@ namespace Popups {
ImGui::Text(name_text.c_str());

ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing

if (!file_stat) {
FS::GetFileSize(data.entries[data.selected].name, size);
file_stat = true;
}

char size[16];
Utils::GetSizeString(size, static_cast<double>(data.entries[data.selected].file_size));
char size_str[16];
Utils::GetSizeString(size_str, static_cast<double>(size));
std::string size_text = "Size: ";
size_text.append(size);
size_text.append(size_str);
ImGui::Text(size_text.c_str());

ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
Expand All @@ -101,8 +114,9 @@ namespace Popups {
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing

if (ImGui::Button("OK", ImVec2(120, 0))) {
ImGui::CloseCurrentPopup();
state = false;
file_stat = false;
ImGui::CloseCurrentPopup();
}
}

Expand Down
23 changes: 1 addition & 22 deletions source/tabs/filebrowser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,6 @@ namespace FileBrowser {
case FS_SORT_ALPHA_DESC:
return (strcasecmp(entryB.name, entryA.name) < 0);
break;

case FS_SORT_SIZE_ASC:
return (entryA.file_size < entryB.file_size);
break;

case FS_SORT_SIZE_DESC:
return (entryB.file_size < entryA.file_size);
break;
}

return false;
Expand Down Expand Up @@ -75,11 +67,6 @@ namespace FileBrowser {
return descending? (strcasecmp(entryB.name, entryA.name) < 0) : (strcasecmp(entryA.name, entryB.name) < 0);
break;

case 2: // Size
sort = descending? FS_SORT_SIZE_DESC : FS_SORT_SIZE_ASC;
return descending? (entryB.file_size < entryA.file_size) : (entryA.file_size < entryB.file_size);
break;

default:
break;
}
Expand Down Expand Up @@ -139,13 +126,12 @@ namespace Tabs {
ImGuiTableFlags tableFlags = ImGuiTableFlags_Resizable | ImGuiTableFlags_Sortable | ImGuiTableFlags_BordersInner |
ImGuiTableFlags_BordersOuter | ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_ScrollY;

if (ImGui::BeginTable("Directory List", 3, tableFlags)) {
if (ImGui::BeginTable("Directory List", 2, tableFlags)) {
// Make header always visible
// ImGui::TableSetupScrollFreeze(0, 1);

ImGui::TableSetupColumn("", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_NoHeaderLabel | ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("Filename", ImGuiTableColumnFlags_DefaultSort);
ImGui::TableSetupColumn("Size", ImGuiTableColumnFlags_WidthFixed, 150.f);
ImGui::TableHeadersRow();

if (ImGuiTableSortSpecs *sorts_specs = ImGui::TableGetSortSpecs()) {
Expand Down Expand Up @@ -223,13 +209,6 @@ namespace Tabs {

if (ImGui::IsItemHovered())
data.selected = i;

ImGui::TableNextColumn();
if (data.entries[i].file_size != 0) {
char size[16];
Utils::GetSizeString(size, static_cast<double>(data.entries[i].file_size));
ImGui::Text(size);
}
}

ImGui::EndTable();
Expand Down
14 changes: 10 additions & 4 deletions source/window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
WindowData data;

namespace Windows {
static bool image_properties = false;
static bool image_properties = false, file_stat = false;

void SetupWindow(void) {
ImGui::SetNextWindowPos(ImVec2(0.0f, 0.0f), ImGuiCond_Once);
Expand Down Expand Up @@ -52,15 +52,15 @@ namespace Windows {
break;

case WINDOW_STATE_PROPERTIES:
Popups::FilePropertiesPopup(data);
Popups::FilePropertiesPopup(data, file_stat);
break;

case WINDOW_STATE_DELETE:
Popups::DeletePopup(data);
break;

case WINDOW_STATE_IMAGEVIEWER:
Windows::ImageViewer(image_properties);
Windows::ImageViewer(image_properties, file_stat);
ImageViewer::HandleControls(key, image_properties);
break;

Expand Down Expand Up @@ -90,13 +90,19 @@ namespace Windows {
break;

case WINDOW_STATE_PROPERTIES:
data.state = WINDOW_STATE_OPTIONS;
file_stat = false;
break;

case WINDOW_STATE_DELETE:
data.state = WINDOW_STATE_OPTIONS;
break;

case WINDOW_STATE_IMAGEVIEWER:
if (image_properties)
if (image_properties) {
image_properties = false;
file_stat = false;
}
else {
ImageViewer::ClearTextures();
data.state = WINDOW_STATE_FILEBROWSER;
Expand Down

1 comment on commit dc9c250

@joel16
Copy link
Owner Author

@joel16 joel16 commented on dc9c250 Aug 30, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You do not need separate call to stat at all. diropen + dirnext already fills stat struct for you. Just check libnx and libusbhsfs sources for that.

Thank you for the information. I'll take a stab at this when I get some free time. (As well as your info on the recursive file copy) Really appreciate it.

Please sign in to comment.