Skip to content

Commit 2e8b39f

Browse files
committed
Implement LookupCache with LRUCache. Move LRUCache.swift to swift-syntax module with package level access.
1 parent 07aa269 commit 2e8b39f

File tree

7 files changed

+23
-11
lines changed

7 files changed

+23
-11
lines changed

CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ if(NOT DEFINED SWIFTSYNTAX_PACKAGE_NAME)
5757
set(SWIFTSYNTAX_PACKAGE_NAME "${SWIFT_MODULE_ABI_NAME_PREFIX}${PROJECT_NAME}")
5858
endif()
5959

60+
add_compile_options(
61+
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-Xfrontend -package-name -Xfrontend ${SWIFTSYNTAX_PACKAGE_NAME}>"
62+
)
63+
6064
# Determine the module triple.
6165
if("${SWIFT_HOST_MODULE_TRIPLE}" STREQUAL "")
6266
set(module_triple_command "${CMAKE_Swift_COMPILER}" -print-target-info)

Sources/SwiftCompilerPluginMessageHandling/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
add_swift_syntax_library(SwiftCompilerPluginMessageHandling
1010
CompilerPluginMessageHandler.swift
1111
Diagnostics.swift
12-
LRUCache.swift
1312
Macros.swift
1413
PluginMacroExpansionContext.swift
1514
PluginMessageCompatibility.swift

Sources/SwiftLexicalLookup/LookupCache.swift

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,21 @@ import SwiftSyntax
1717
public class LookupCache {
1818
/// Cached results of `ScopeSyntax.lookupParent` calls.
1919
/// Identified by `SyntaxIdentifier`.
20-
private var ancestorResultsCache: [SyntaxIdentifier: [LookupResult]] = [:]
20+
private let ancestorResultsCache: LRUCache<SyntaxIdentifier, [LookupResult]>
2121
/// Cached results of `SequentialScopeSyntax.sequentialLookup` calls.
2222
/// Identified by `SyntaxIdentifier`.
23-
private var sequentialResultsCache: [SyntaxIdentifier: [LookupResult]] = [:]
23+
private let sequentialResultsCache: LRUCache<SyntaxIdentifier, [LookupResult]>
2424
/// Looked-up scope identifiers during cache accesses.
2525
private var hits: Set<SyntaxIdentifier> = []
2626

2727
private let dropMod: Int
2828
private var evictionCount = 0
2929

3030
/// Creates a new unqualified lookup cache.
31+
/// `capacity` describes the maximum amount of entries in the cache.
32+
/// The cache size is maintained according to the LRU (Least Recently Used) policy.
3133
/// `drop` parameter specifies how many eviction calls will be
32-
/// ignored before evicting not-hit members of the cache.
34+
/// ignored before evicting not-hit members from subsequent lookups.
3335
///
3436
/// Example cache eviction sequences (s - skip, e - evict):
3537
/// - `drop = 0` - `e -> e -> e -> e -> e -> ...`
@@ -44,7 +46,9 @@ public class LookupCache {
4446
/// memory accesses could take longer, slowing down the eviction process. That's why the `drop` value
4547
/// could be fine-tuned to maximize the performance given file size,
4648
/// number of lookups, and amount of available memory.
47-
public init(drop: Int = 0) {
49+
public init(capacity: Int, drop: Int = 0) {
50+
self.ancestorResultsCache = LRUCache(capacity: (capacity + 1) / 2)
51+
self.sequentialResultsCache = LRUCache(capacity: capacity / 2)
4852
self.dropMod = drop + 1
4953
}
5054

@@ -91,9 +95,9 @@ public class LookupCache {
9195
guard evictionCount != 0 else { return }
9296
}
9397

94-
for key in Set(ancestorResultsCache.keys).union(sequentialResultsCache.keys).subtracting(hits) {
95-
ancestorResultsCache.removeValue(forKey: key)
96-
sequentialResultsCache.removeValue(forKey: key)
98+
for key in ancestorResultsCache.keysInCache.union(sequentialResultsCache.keysInCache).subtracting(hits) {
99+
ancestorResultsCache[key] = nil
100+
sequentialResultsCache[key] = nil
97101
}
98102

99103
hits = []

Sources/SwiftSyntax/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ add_swift_syntax_library(SwiftSyntax
1717
CustomTraits.swift
1818
EditorPlaceholder.swift
1919
Identifier.swift
20+
LRUCache.swift
2021
MemoryLayout.swift
2122
MissingNodeInitializers.swift
2223
SourceEdit.swift

Sources/SwiftCompilerPluginMessageHandling/LRUCache.swift renamed to Sources/SwiftSyntax/LRUCache.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
/// Simple LRU cache.
14-
@_spi(Testing)
15-
public class LRUCache<Key: Hashable, Value> {
14+
package class LRUCache<Key: Hashable, Value> {
1615
private class _Node {
1716
unowned var prev: _Node? = nil
1817
unowned var next: _Node? = nil
@@ -33,12 +32,14 @@ public class LRUCache<Key: Hashable, Value> {
3332
private unowned var tail: _Node?
3433

3534
public let capacity: Int
35+
public private(set) var keysInCache: Set<Key>
3636

3737
public init(capacity: Int) {
3838
self.table = [:]
3939
self.head = nil
4040
self.tail = nil
4141
self.capacity = capacity
42+
self.keysInCache = []
4243
}
4344

4445
public var count: Int {
@@ -60,6 +61,7 @@ public class LRUCache<Key: Hashable, Value> {
6061
self.ensureCapacityForNewValue()
6162
let node = _Node(key: key, value: newValue)
6263
addToHead(node: node)
64+
keysInCache.insert(key)
6365
table[key] = node
6466

6567
case let (node?, newValue?): // update.
@@ -68,6 +70,7 @@ public class LRUCache<Key: Hashable, Value> {
6870

6971
case let (node?, nil): // delete.
7072
remove(node: node)
73+
keysInCache.remove(key)
7174
table[key] = nil
7275

7376
case (nil, nil): // no-op.

Tests/SwiftCompilerPluginTest/LRUCacheTests.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
import SwiftSyntax
1314
@_spi(Testing) import SwiftCompilerPluginMessageHandling
1415
import XCTest
1516

Tests/SwiftLexicalLookupTest/Assertions.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ func assertLexicalNameLookup(
116116
)
117117

118118
// Perform test with cache
119-
let cache = LookupCache()
119+
let cache = LookupCache(capacity: 10)
120120
assertLexicalScopeQuery(
121121
source: source,
122122
methodUnderTest: { marker, tokenAtMarker in

0 commit comments

Comments
 (0)