Skip to content

Commit e511a77

Browse files
committed
speed up file discovery
1 parent 454b595 commit e511a77

1 file changed

Lines changed: 55 additions & 20 deletions

File tree

src/base/USongs.pas

Lines changed: 55 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -290,34 +290,69 @@ procedure TSongs.LoadSongList;
290290

291291
procedure TSongs.FindFilesByExtension(const Dir: IPath; const Ext: IPath; Recursive: Boolean; var Files: TPathDynArray);
292292
var
293+
DirList: TPathDynArray;
294+
DirCount, DirIdx: Integer;
293295
Iter: IFileIterator;
294296
FileInfo: TFileInfo;
295297
FileName: IPath;
296-
begin
297-
// search for all files and directories
298-
Iter := FileSystem.FileFind(Dir.Append('*'), faAnyFile);
299-
while (Iter.HasNext) do
298+
function CollectDirectories(const StartDir: IPath): TPathDynArray;
299+
var
300+
LocalDirs: TPathDynArray;
301+
LocalIter: IFileIterator;
302+
LocalFileInfo: TFileInfo;
303+
LocalFileName: IPath;
304+
SubDirs: TPathDynArray;
305+
SubDirCount, SubDirIdx: Integer;
300306
begin
301-
// the debug statements in this function have exactly the same message length before it prints the path
302-
FileInfo := Iter.Next;
303-
FileName := FileInfo.Name;
304-
if ((FileInfo.Attr and faDirectory) <> 0) then
307+
SetLength(LocalDirs, 1);
308+
LocalDirs[0] := StartDir;
309+
if not Recursive then
310+
Exit(LocalDirs);
311+
312+
// Only search for directories
313+
LocalIter := FileSystem.FileFind(StartDir.Append('*'), faDirectory);
314+
while (LocalIter.HasNext) do
305315
begin
306-
if Recursive and (not FileName.Equals('.')) and (not FileName.Equals('..')) and (not FileName.Equals('')) then begin
307-
Log.LogDebug('Recursing: ' + Dir.Append(FileName).ToWide, 'TSongs.FindFilesByExtension');
308-
FindFilesByExtension(Dir.Append(FileName), Ext, true, Files);
316+
LocalFileInfo := LocalIter.Next;
317+
LocalFileName := LocalFileInfo.Name;
318+
if ((LocalFileInfo.Attr and faDirectory) <> 0) and
319+
(not LocalFileName.Equals('.')) and (not LocalFileName.Equals('..')) and (not LocalFileName.Equals('')) then
320+
begin
321+
// Add subdirectory and recurse
322+
SubDirs := CollectDirectories(StartDir.Append(LocalFileName));
323+
SubDirCount := Length(SubDirs);
324+
if SubDirCount > 0 then
325+
begin
326+
SetLength(LocalDirs, Length(LocalDirs) + SubDirCount);
327+
for SubDirIdx := 0 to SubDirCount - 1 do
328+
LocalDirs[High(LocalDirs) - SubDirCount + 1 + SubDirIdx] := SubDirs[SubDirIdx];
329+
end;
309330
end;
310-
end
311-
else
331+
end;
332+
Exit(LocalDirs);
333+
end;
334+
begin
335+
// First, collect all directories (including Dir itself)
336+
DirList := CollectDirectories(Dir);
337+
DirCount := Length(DirList);
338+
339+
for DirIdx := 0 to DirCount - 1 do
340+
begin
341+
Iter := FileSystem.FileFind(DirList[DirIdx].Append('*.txt'), 0);
342+
while (Iter.HasNext) do
312343
begin
313-
// do not load files which either have wrong extension or start with a point
314-
if (Ext.Equals(FileName.GetExtension(), true) and not (FileName.ToUTF8()[1] = '.')) then
344+
FileInfo := Iter.Next;
345+
FileName := FileInfo.Name;
346+
if ((FileInfo.Attr and faDirectory) = 0) then
315347
begin
316-
Log.LogDebug('Found file ' + Dir.Append(FileName).ToWide, 'TSongs.FindFilesByExtension');
317-
SetLength(Files, Length(Files)+1);
318-
Files[High(Files)] := Dir.Append(FileName);
319-
fTotalSongsToLoad := fTotalSongsToLoad + 1;
320-
UpdateLoadingProgress;
348+
if (Ext.Equals(FileName.GetExtension(), true)) then
349+
begin
350+
Log.LogDebug('Found file ' + DirList[DirIdx].Append(FileName).ToWide, 'TSongs.FindFilesByExtension');
351+
SetLength(Files, Length(Files)+1);
352+
Files[High(Files)] := DirList[DirIdx].Append(FileName);
353+
fTotalSongsToLoad := fTotalSongsToLoad + 1;
354+
UpdateLoadingProgress;
355+
end;
321356
end;
322357
end;
323358
end;

0 commit comments

Comments
 (0)