Skip to content

Commit d9d7215

Browse files
authored
Merge pull request #34 from rameel/optimize-globbing-traversal
Skip enumeration entirely for excluded directories
2 parents de32a83 + 7816450 commit d9d7215

2 files changed

Lines changed: 75 additions & 15 deletions

File tree

src/Ramstack.FileSystem.Globbing/GlobbingDirectory.cs

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -56,18 +56,21 @@ protected override ValueTask DeleteCoreAsync(CancellationToken cancellationToken
5656
/// <inheritdoc />
5757
protected override async IAsyncEnumerable<VirtualNode> GetFileNodesCoreAsync([EnumeratorCancellation] CancellationToken cancellationToken)
5858
{
59-
await foreach (var node in _directory.GetFileNodesAsync(cancellationToken).ConfigureAwait(false))
59+
if (_included)
6060
{
61-
if (!_fs.IsExcluded(node.FullName))
61+
await foreach (var node in _directory.GetFileNodesAsync(cancellationToken).ConfigureAwait(false))
6262
{
63-
if (node is VirtualFile file)
64-
{
65-
if (_fs.IsIncluded(node.FullName))
66-
yield return new GlobbingFile(_fs, file, true);
67-
}
68-
else
63+
if (!_fs.IsExcluded(node.FullName))
6964
{
70-
yield return new GlobbingDirectory(_fs, (VirtualDirectory)node, true);
65+
if (node is VirtualFile file)
66+
{
67+
if (_fs.IsIncluded(node.FullName))
68+
yield return new GlobbingFile(_fs, file, true);
69+
}
70+
else
71+
{
72+
yield return new GlobbingDirectory(_fs, (VirtualDirectory)node, true);
73+
}
7174
}
7275
}
7376
}
@@ -76,20 +79,26 @@ protected override async IAsyncEnumerable<VirtualNode> GetFileNodesCoreAsync([En
7679
/// <inheritdoc />
7780
protected override async IAsyncEnumerable<VirtualFile> GetFilesCoreAsync([EnumeratorCancellation] CancellationToken cancellationToken)
7881
{
79-
await foreach (var file in _directory.GetFilesAsync(cancellationToken).ConfigureAwait(false))
82+
if (_included)
8083
{
81-
if (_fs.IsFileIncluded(file.FullName))
82-
yield return new GlobbingFile(_fs, file, true);
84+
await foreach (var file in _directory.GetFilesAsync(cancellationToken).ConfigureAwait(false))
85+
{
86+
if (_fs.IsFileIncluded(file.FullName))
87+
yield return new GlobbingFile(_fs, file, true);
88+
}
8389
}
8490
}
8591

8692
/// <inheritdoc />
8793
protected override async IAsyncEnumerable<VirtualDirectory> GetDirectoriesCoreAsync([EnumeratorCancellation] CancellationToken cancellationToken)
8894
{
89-
await foreach (var directory in _directory.GetDirectoriesAsync(cancellationToken).ConfigureAwait(false))
95+
if (_included)
9096
{
91-
if (_fs.IsDirectoryIncluded(directory.FullName))
92-
yield return new GlobbingDirectory(_fs, directory, true);
97+
await foreach (var directory in _directory.GetDirectoriesAsync(cancellationToken).ConfigureAwait(false))
98+
{
99+
if (_fs.IsDirectoryIncluded(directory.FullName))
100+
yield return new GlobbingDirectory(_fs, directory, true);
101+
}
93102
}
94103
}
95104
}

tests/Ramstack.FileSystem.Globbing.Tests/GlobingFileSystemTests.cs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,57 @@ public void Setup()
2929
public void Cleanup() =>
3030
_storage.Dispose();
3131

32+
[Test]
33+
public async Task ExcludedDirectory_HasNoFileNodes()
34+
{
35+
using var storage = new TempFileStorage();
36+
using var fs = new GlobbingFileSystem(new PhysicalFileSystem(storage.Root), "**", exclude: "/project/src/**");
37+
38+
var directories = new[]
39+
{
40+
"/project/src",
41+
"/project/src/App",
42+
"/project/src/Modules",
43+
"/project/src/Modules/Module1",
44+
"/project/src/Modules/Module1/Submodule",
45+
"/project/src/Modules/Module2"
46+
};
47+
48+
foreach (var path in directories)
49+
{
50+
var directory = fs.GetDirectory(path);
51+
52+
Assert.That(
53+
await directory.ExistsAsync(),
54+
Is.False);
55+
56+
Assert.That(
57+
await directory.GetFileNodesAsync("**").CountAsync(),
58+
Is.Zero);
59+
}
60+
61+
var files = new[]
62+
{
63+
"/project/src/App/App.csproj",
64+
"/project/src/App/Program.cs",
65+
"/project/src/App/Utils.cs",
66+
"/project/src/Modules/Module1/Module1.cs",
67+
"/project/src/Modules/Module1/Module1.csproj",
68+
"/project/src/Modules/Module1/Submodule/Submodule1.cs",
69+
"/project/src/Modules/Module1/Submodule/Submodule2.cs",
70+
"/project/src/Modules/Module1/Submodule/Submodule.csproj",
71+
"/project/src/Modules/Module2/Module2.cs",
72+
"/project/src/Modules/Module2/Module2.csproj",
73+
"/project/src/App.sln"
74+
};
75+
76+
foreach (var path in files)
77+
{
78+
var file = fs.GetFile(path);
79+
Assert.That(await file.ExistsAsync(), Is.False);
80+
}
81+
}
82+
3283
protected override IVirtualFileSystem GetFileSystem()
3384
{
3485
var fs = new PhysicalFileSystem(_storage.Root);

0 commit comments

Comments
 (0)