Skip to content

'--max-depth 1' & '--exact--depth 1' just parse results? #1705

Open
@donferris

Description

@donferris

What version of fd are you using?
[fd 10.2.0]

Apologies if this is the wrong place for this.

Running some simple tests, fd takes roughly the exact amount of time in a vast directory regardless of if --max-depth 1/--exact--depth 1 (--max-depth 0 yields nothing). This makes me think that it simply filters the results but still searches all entries all levels deep? I'm sure I don't fully understand hence my question. If so, why not just limit the iteration to whatever the level is instead? Or maybe just add a '--top-level-only' flag This could cut down on processing time. For context, here is what i'm doing:

private static readonly string[] BaseFdOptions = [
     "--print0",
     "--full-path",
     "--absolute-path",
     "--unrestricted"
 ];

 public static Result<List<string>> SearchPathsFd(string searchDir, string searchTerm, EntryType matchType, bool ignoreCase, bool recursive)
 {
     if (!Directory.Exists(searchDir))
         return Result<List<string>>.Failure($"'{searchDir}' does not exist.");

     string fdPath = Path.Combine(AppContext.BaseDirectory, "Resources", "fd.exe");
     if (!File.Exists(fdPath))
         return Result<List<string>>.Failure($"'{fdPath}' does not exist.");

     string arguments = BuildFdArguments(searchDir, searchTerm, matchType, ignoreCase, recursive);

     try
     {
         using var process = Process.Start(new ProcessStartInfo
         {
             FileName = fdPath,
             Arguments = arguments,
             RedirectStandardOutput = true,
             RedirectStandardError = true,
             UseShellExecute = false,
             CreateNoWindow = true,
             StandardOutputEncoding = Encoding.UTF8,
         });

         using var memoryStream = new MemoryStream();
         process.StandardOutput.BaseStream.CopyTo(memoryStream);

         if (!process.WaitForExit(30000))
         {
             process.Kill();
             return Result<List<string>>.Failure("Hit 'WaitForExit' timeout.");
         }

         string errorOutput = process.StandardError.ReadToEnd();
         if (!string.IsNullOrWhiteSpace(errorOutput))
             return Result<List<string>>.Failure(errorOutput);

         var outputBuffer = memoryStream.ToArray();
         if (outputBuffer.Length == 0)
             return Result<List<string>>.Failure("No output received from fd.");

         string outputString = Encoding.UTF8.GetString(outputBuffer);
         return Result<List<string>>.Success([.. outputString.Split(['\0'], StringSplitOptions.RemoveEmptyEntries)], null);
     }
     catch (Exception ex)
     {
         return Result<List<string>>.Failure($"Exception: {ex.Message}");
     }
 }

private static string BuildFdArguments(string searchDir, string searchTerm, EntryType matchType, bool ignoreCase, bool recursive)
{
    var sb = new StringBuilder();

    foreach (var option in BaseFdOptions)
        sb.Append(option).Append(' ');

    sb.Append(ignoreCase ? "--ignore-case " : "--case-sensitive ");

    if (matchType == EntryType.File)
        sb.Append("--type f ");
    else if (matchType == EntryType.Directory)
        sb.Append("--type d ");

    if (!recursive)
        sb.Append("--max-depth 1 ");

    sb.Append(searchTerm).Append(' ')
      .Append('"').Append(searchDir).Append('"');

    return sb.ToString();
}

On a side note, i noticed that the '--unrestricted' flag seems to increase performance by like 3x in my use case. Any insight into that?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions