Skip to content

Commit 3cf015a

Browse files
authored
Merge pull request #1866 from ahoppen/cache-path-components
Cache path components for directories returned from build system
2 parents f59fb2b + a61bbff commit 3cf015a

File tree

1 file changed

+21
-7
lines changed

1 file changed

+21
-7
lines changed

Sources/BuildSystemIntegration/BuildSystemManager.swift

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,10 @@ package actor BuildSystemManager: QueueBasedMessageHandler {
338338
let files: [DocumentURI: SourceFileInfo]
339339

340340
/// The source directories in the workspace, ie. all `SourceItem`s that have `kind == .directory`.
341-
let directories: [DocumentURI: SourceFileInfo]
341+
///
342+
/// `pathComponents` is the result of `key.fileURL?.pathComponents`. We frequently need these path components to
343+
/// determine if a file is descendent of the directory and computing them from the `DocumentURI` is expensive.
344+
let directories: [DocumentURI: (pathComponents: [String]?, info: SourceFileInfo)]
342345
}
343346

344347
private let cachedSourceFilesAndDirectories = Cache<SourceFilesAndDirectoriesKey, SourceFilesAndDirectories>()
@@ -679,12 +682,12 @@ package actor BuildSystemManager: QueueBasedMessageHandler {
679682
if let targets = filesAndDirectories.files[document]?.targets {
680683
result.formUnion(targets)
681684
}
682-
if !filesAndDirectories.directories.isEmpty, let documentPath = document.fileURL {
683-
for (directory, info) in filesAndDirectories.directories {
684-
guard let directoryPath = directory.fileURL else {
685+
if !filesAndDirectories.directories.isEmpty, let documentPathComponents = document.fileURL?.pathComponents {
686+
for (directory, (directoryPathComponents, info)) in filesAndDirectories.directories {
687+
guard let directoryPathComponents, let directoryPath = directory.fileURL else {
685688
continue
686689
}
687-
if documentPath.isDescendant(of: directoryPath) {
690+
if isDescendant(documentPathComponents, of: directoryPathComponents) {
688691
result.formUnion(info.targets)
689692
}
690693
}
@@ -1055,7 +1058,7 @@ package actor BuildSystemManager: QueueBasedMessageHandler {
10551058

10561059
return try await cachedSourceFilesAndDirectories.get(key, isolation: self) { key in
10571060
var files: [DocumentURI: SourceFileInfo] = [:]
1058-
var directories: [DocumentURI: SourceFileInfo] = [:]
1061+
var directories: [DocumentURI: (pathComponents: [String]?, info: SourceFileInfo)] = [:]
10591062
for sourcesItem in key.sourcesItems {
10601063
let target = targets[sourcesItem.target]?.target
10611064
let isPartOfRootProject = !(target?.tags.contains(.dependency) ?? false)
@@ -1077,7 +1080,9 @@ package actor BuildSystemManager: QueueBasedMessageHandler {
10771080
case .file:
10781081
files[sourceItem.uri] = info.merging(files[sourceItem.uri])
10791082
case .directory:
1080-
directories[sourceItem.uri] = info.merging(directories[sourceItem.uri])
1083+
directories[sourceItem.uri] = (
1084+
sourceItem.uri.fileURL?.pathComponents, info.merging(directories[sourceItem.uri]?.info)
1085+
)
10811086
}
10821087
}
10831088
}
@@ -1226,3 +1231,12 @@ package actor BuildSystemManager: QueueBasedMessageHandler {
12261231
}
12271232
}
12281233
}
1234+
1235+
/// Returns `true` if the path components `selfPathComponents`, retrieved from `URL.pathComponents` are a descendent
1236+
/// of the other path components.
1237+
///
1238+
/// This operates directly on path components instead of `URL`s because computing the path components of a URL is
1239+
/// expensive and this allows us to cache the path components.
1240+
private func isDescendant(_ selfPathComponents: [String], of otherPathComponents: [String]) -> Bool {
1241+
return selfPathComponents.dropLast().starts(with: otherPathComponents)
1242+
}

0 commit comments

Comments
 (0)