Skip to content

Commit

Permalink
Improve source map performance for directories with same path
Browse files Browse the repository at this point in the history
This PR aggregates the directories to a map of paths to tuples
containing prefixes and suffixes.

This will reduce the overhead of scanning paths when multiple directory
elements are defined with the same path but differnet prefixes or
suffixes.

Addresses #6111
  • Loading branch information
dantleech authored and sebastianbergmann committed Jan 30, 2025
1 parent 5f8c741 commit e9be224
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 4 deletions.
41 changes: 37 additions & 4 deletions src/TextUI/Configuration/SourceMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@ public function map(Source $source): array

$files = [];

foreach ($source->includeDirectories() as $directory) {
foreach ((new FileIteratorFacade)->getFilesAsArray($directory->path(), $directory->suffix(), $directory->prefix()) as $file) {
$directories = $this->aggregateDirectories($source->includeDirectories());

foreach ($directories as $path => [$prefixes, $suffixes]) {
foreach ((new FileIteratorFacade)->getFilesAsArray($path, $suffixes, $prefixes) as $file) {
$file = realpath($file);

if (!$file) {
Expand All @@ -62,8 +64,10 @@ public function map(Source $source): array
$files[$file] = true;
}

foreach ($source->excludeDirectories() as $directory) {
foreach ((new FileIteratorFacade)->getFilesAsArray($directory->path(), $directory->suffix(), $directory->prefix()) as $file) {
$directories = $this->aggregateDirectories($source->excludeDirectories());

foreach ($directories as $path => [$prefixes, $suffixes]) {
foreach ((new FileIteratorFacade)->getFilesAsArray($path, $suffixes, $prefixes) as $file) {
$file = realpath($file);

if (!$file) {
Expand Down Expand Up @@ -96,4 +100,33 @@ public function map(Source $source): array

return $files;
}

/**
* @return array<string,array{list<string>,list<string>}>
*/
private function aggregateDirectories(FilterDirectoryCollection $directories): array
{
$aggregated = [];

foreach ($directories as $directory) {
if (!isset($aggregated[$directory->path()])) {
$aggregated[$directory->path()] = [
0 => [],
1 => [],
];
}
$prefix = $directory->prefix();

if ($prefix !== '') {
$aggregated[$directory->path()][0][] = $prefix;
}
$suffix = $directory->suffix();

if ($suffix !== '') {
$aggregated[$directory->path()][1][] = $suffix;
}
}

return $aggregated;
}
}
76 changes: 76 additions & 0 deletions tests/unit/TextUI/SourceMapperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,82 @@ public static function provider(): Generator
),
),
];

yield 'files included using same directory and different suffixes' => [
[
self::fixturePath('a/c/Prefix.php') => true,
self::fixturePath('a/c/d/Prefix.php') => true,
self::fixturePath('b/e/PrefixExampleSuffix.php') => true,
],
self::createSource(
includeDirectories: FilterDirectoryCollection::fromArray(
[
new FilterDirectory(
self::fixturePath(),
'',
'ExampleSuffix.php',
),
new FilterDirectory(
self::fixturePath(),
'',
'Prefix.php',
),
],
),
),
];

yield 'files included using same directory and different prefixes' => [
[
self::fixturePath('a/c/Suffix.php') => true,
self::fixturePath('a/c/d/Suffix.php') => true,
self::fixturePath('b/e/PrefixExampleSuffix.php') => true,
],
self::createSource(
includeDirectories: FilterDirectoryCollection::fromArray(
[
new FilterDirectory(
self::fixturePath(),
'Suffix',
'.php',
),
new FilterDirectory(
self::fixturePath(),
'PrefixExample',
'.php',
),
],
),
),
];

yield 'files excluded using same directory and different prefixes' => [
[
],
self::createSource(
includeDirectories: FilterDirectoryCollection::fromArray([
new FilterDirectory(
self::fixturePath(),
'',
'.php',
),
]),
excludeDirectories: FilterDirectoryCollection::fromArray(
[
new FilterDirectory(
self::fixturePath(),
'Prefix',
'.php',
),
new FilterDirectory(
self::fixturePath(),
'Suffix',
'.php',
),
],
),
),
];
}

public static function fixturePath(?string $subPath = null): string
Expand Down

0 comments on commit e9be224

Please sign in to comment.