Skip to content

Commit

Permalink
DOS drive cache: Fix directory listing performance issues by deferrin…
Browse files Browse the repository at this point in the history
…g filename sort until after all entries have been added. [#5039]
  • Loading branch information
joncampbell123 committed Jun 17, 2024
1 parent 0f38f55 commit 3ff38b6
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 5 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
Next:
- DOS drive cache: When listing a directory, defer the filename sort until
the entire list is built. This improves directory listing performance
in directories with many files. (joncampbell123).
- INT 10h, if instructed, will now use the video parameter table to set
standard VGA modes instead of internal logic. (joncampbell123).
- Removed erroneous VGA display compensation code for certain EGA/VGA
Expand Down
2 changes: 1 addition & 1 deletion include/dos_system.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ class DOS_Drive_Cache {
CFileInfo* FindDirInfo (const char* path, char* expandedPath);
bool RemoveSpaces (char* str);
bool OpenDir (CFileInfo* dir, const char* expand, uint16_t& id);
char* CreateEntry (CFileInfo* dir, const char* name, const char* sname, bool is_directory);
char* CreateEntry (CFileInfo* dir, const char* name, const char* sname, bool is_directory, bool skipSort=false);
void CopyEntry (CFileInfo* dir, CFileInfo* from);
uint16_t GetFreeID (CFileInfo* dir);
void Clear (void);
Expand Down
11 changes: 7 additions & 4 deletions src/dos/drive_cache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -824,7 +824,7 @@ bool DOS_Drive_Cache::OpenDir(CFileInfo* dir, const char* expand, uint16_t& id)
return false;
}

char* DOS_Drive_Cache::CreateEntry(CFileInfo* dir, const char* name, const char* sname, bool is_directory) {
char* DOS_Drive_Cache::CreateEntry(CFileInfo* dir, const char* name, const char* sname, bool is_directory, bool skipSort) {
CFileInfo* info = new CFileInfo;
strcpy(info->shortname, sname);
strcpy(info->orgname, name);
Expand All @@ -835,7 +835,7 @@ char* DOS_Drive_Cache::CreateEntry(CFileInfo* dir, const char* name, const char*
if (sname[0]==0) CreateShortName(dir, info);

// keep list sorted (so GetLongName works correctly, used by CreateShortName in this routine)
if (dir->fileList.size()>0) {
if (dir->fileList.size()>0 && !skipSort) {
if (!(strcmp(info->shortname,dir->fileList.back()->shortname)<0)) {
// append at end of list
dir->fileList.push_back(info);
Expand Down Expand Up @@ -891,12 +891,15 @@ bool DOS_Drive_Cache::ReadDir(uint16_t id, char* &result, char * &lresult) {
char dir_name[CROSS_LEN], dir_sname[DOS_NAMELENGTH+1];
bool is_directory;
if (drive->read_directory_first(dirp, dir_name, dir_sname, is_directory)) {
CreateEntry(dirSearch[id], dir_name, dir_sname, is_directory);
CreateEntry(dirSearch[id], dir_name, dir_sname, is_directory, /*skip search*/true);
while (drive->read_directory_next(dirp, dir_name, dir_sname, is_directory)) {
CreateEntry(dirSearch[id], dir_name, dir_sname, is_directory);
CreateEntry(dirSearch[id], dir_name, dir_sname, is_directory, /*skip search*/true);
}
}

// Insertion skipped sorting, now sort in one go, which should be faster when faced with many files
std::sort(dirSearch[id]->fileList.begin(), dirSearch[id]->fileList.end(), SortByName);

// close dir
drive->closedir(dirp);

Expand Down

0 comments on commit 3ff38b6

Please sign in to comment.