Hi, Can the FindFirst optimization in 2.1.1 for unix/sysutils.pp be merged to 2.0.5 ? Revision 4772. Not only is it more efficient, it also fixes a bug: I cannot find a single directory with FindFirst in 2.0.5.
Furthermore, attached is a patch for another optimization: do not allocate a record in case user is requesting info for a single file. Apply in rtl/unix please. Thanks, Micha
Index: sysutils.pp =================================================================== --- sysutils.pp (revision 4823) +++ sysutils.pp (working copy) @@ -424,9 +424,9 @@ if not fpstat(s,st)>=0 then exit; WinAttr:=LinuxToWinAttr(PChar(s),st); - If ((WinAttr and Not(PUnixFindData(f.FindHandle)^.searchattr))=0) Then + If (f.FindHandle = nil) or ((WinAttr and Not(PUnixFindData(f.FindHandle)^.searchattr))=0) Then Begin - f.Name:=Copy(s,PUnixFindData(f.FindHandle)^.NamePos+1,Length(s)); + f.Name:=ExtractFileName(s); f.Attr:=WinAttr; f.Size:=st.st_Size; f.Mode:=st.st_mode; @@ -503,26 +503,27 @@ fillchar(Rslt,sizeof(Rslt),0); if Path='' then exit; - { Allocate UnixFindData } - New(UnixFindData); - FillChar(UnixFindData^,sizeof(UnixFindData^),0); - Rslt.FindHandle:=UnixFindData; - {Create Info} - UnixFindData^.SearchSpec := Path; - {We always also search for readonly and archive, regardless of Attr:} - UnixFindData^.SearchAttr := Attr or faarchive or fareadonly; - UnixFindData^.NamePos := Length(UnixFindData^.SearchSpec); - while (UnixFindData^.NamePos>0) and (UnixFindData^.SearchSpec[UnixFindData^.NamePos]<>'/') do - dec(UnixFindData^.NamePos); {Wildcards?} if (Pos('?',Path)=0) and (Pos('*',Path)=0) then begin if FindGetFileInfo(Path,Rslt) then Result:=0; - UnixFindData^.SearchType:=1; end - else - Result:=FindNext(Rslt); + else + begin + { Allocate UnixFindData } + New(UnixFindData); + FillChar(UnixFindData^,sizeof(UnixFindData^),0); + Rslt.FindHandle:=UnixFindData; + {Create Info} + UnixFindData^.SearchSpec := Path; + {We always also search for readonly and archive, regardless of Attr:} + UnixFindData^.SearchAttr := Attr or faarchive or fareadonly; + UnixFindData^.NamePos := Length(UnixFindData^.SearchSpec); + while (UnixFindData^.NamePos>0) and (UnixFindData^.SearchSpec[UnixFindData^.NamePos]<>'/') do + dec(UnixFindData^.NamePos); + Result:=FindNext(Rslt); + end; End;
_______________________________________________ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel