Skip to content

Commit

Permalink
optimizes file_exists() and realpath() on Win
Browse files Browse the repository at this point in the history
uses GetFileAttributesEx() to check both directory and file attributes at one call, avoids try/catch, avoids allocs.
  • Loading branch information
jakubmisek committed Sep 13, 2022
1 parent d748c17 commit a0c1450
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 9 deletions.
25 changes: 19 additions & 6 deletions src/Peachpie.Library/FileSystem.Files.cs
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ public static void clearstatcache(bool clear_realpath_cache = false, string file
#region file_exists, touch

/// <summary>
/// Checks whether a file exists
/// Checks whether a file or a directory exists.
/// </summary>
/// <param name="ctx">Runtime context.</param>
/// <param name="path">The file to be checked.</param>
Expand All @@ -232,13 +232,26 @@ public static bool file_exists(Context ctx, string path)
{
if (!string.IsNullOrEmpty(path) && ResolvePath(ctx, ref path, true, out var wrapper))
{
if (wrapper.Scheme == FileStreamWrapper.scheme && File.Exists(path)) // faster than calling full stat
if (wrapper.Scheme == FileStreamWrapper.scheme)
{
return true;
}
// faster than calling full stat
if (CurrentPlatform.GetFileAttributes(path, out var _, out _))
{
return true;
}

var stat = wrapper.Stat(ctx.RootPath, path, StreamStatOptions.Quiet, StreamContext.Default);
return stat.IsValid; // file or directory
// check a compiled script
if (Context.TryResolveScript(ctx.RootPath, path).IsValid ||
Context.TryGetScriptsInDirectory(ctx.RootPath, path, out _))
{
return true;
}
}
else
{
var stat = wrapper.Stat(ctx.RootPath, path, StreamStatOptions.Quiet, StreamContext.Default);
return stat.IsValid; // file or directory
}
}

return false;
Expand Down
9 changes: 6 additions & 3 deletions src/Peachpie.Library/FileSystem.Path.cs
Original file line number Diff line number Diff line change
Expand Up @@ -364,9 +364,12 @@ public static string realpath(Context ctx, string path)
//
var realpath = FileSystemUtils.AbsolutePath(ctx, path);

if (File.Exists(realpath) ||
System.IO.Directory.Exists(realpath) ||
Context.TryResolveScript(ctx.RootPath, realpath).IsValid) // check a compiled script
if (CurrentPlatform.GetFileAttributes(realpath, out _, out _))
{
return realpath;
}

if (Context.TryResolveScript(ctx.RootPath, realpath).IsValid) // check a compiled script
{
return realpath;
}
Expand Down

0 comments on commit a0c1450

Please # to comment.