Skip to content

Commit 9984b06

Browse files
authored
Merge pull request #655 from CodaFi/inverse-square-laws
Fix quadratic COW copies in DictionaryOfDictionaries
2 parents aad8c2c + 7f830d8 commit 9984b06

File tree

2 files changed

+23
-27
lines changed

2 files changed

+23
-27
lines changed

Sources/SwiftDriver/IncrementalCompilation/DictionaryOfDictionaries.swift

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -92,50 +92,48 @@ extension DictionaryOfDictionaries {
9292
}
9393

9494
public subscript(key: Key) -> Value? {
95-
get {outerDict[key.0]?[key.1]}
95+
get { outerDict[key.0]?[key.1] }
9696
set {
97-
if let v = newValue { _ = updateValue(v, forKey: key) }
98-
else { _ = removeValue(forKey: key) }
97+
if let v = newValue {
98+
outerDict[key.0, default: [:]][key.1] = v
99+
} else {
100+
// Remove the inner key from the inner dictionary.
101+
outerDict[key.0]?[key.1] = nil
102+
103+
// If that was the last entry in the inner dictionary,
104+
// remove the entire inner entry.
105+
if outerDict[key.0]?.isEmpty == true {
106+
outerDict[key.0] = nil
107+
}
108+
}
99109
}
100110
}
101111

102112
public subscript(key: OuterKey) -> [InnerKey: Value]? {
103-
get {outerDict[key]}
113+
get { outerDict[key] }
104114
set {
105-
if let v = newValue { _ = outerDict.updateValue(v, forKey: key) }
106-
else { _ = outerDict.removeValue(forKey: key) }
115+
outerDict[key] = newValue
107116
}
108117
}
109118
}
110119

111120
// MARK: - mutating
112121
extension DictionaryOfDictionaries {
113-
mutating func updateValue(_ v: Value, forKey keys : (OuterKey,InnerKey)
122+
mutating func updateValue(_ v: Value, forKey key: Key
114123
) -> Value? {
115-
if var innerDict = outerDict[keys.0] {
116-
let old = innerDict.updateValue(v, forKey: keys.1)
117-
outerDict.updateValue(innerDict, forKey: keys.0)
118-
return old
119-
}
120-
outerDict.updateValue([keys.1: v], forKey: keys.0)
121-
return nil
124+
let old = self[key]
125+
self[key] = v
126+
return old
122127
}
123128

124-
mutating func removeValue(forKey keys : (OuterKey,InnerKey)
129+
mutating func removeValue(forKey key: Key
125130
) -> Value? {
126-
guard var innerDict = outerDict[keys.0]
127-
else { return nil }
128-
let old = innerDict.removeValue(forKey: keys.1)
129-
if innerDict.isEmpty {
130-
outerDict.removeValue(forKey: keys.0)
131-
}
132-
else {
133-
outerDict.updateValue(innerDict, forKey: keys.0)
134-
}
131+
let old = self[key]
132+
self[key] = nil
135133
return old
136134
}
137135
}
138136

139137
// MARK: - identity
140138

141-
extension DictionaryOfDictionaries: Equatable where Value: Equatable {}
139+
extension DictionaryOfDictionaries: Equatable where Value: Equatable {}

Sources/SwiftDriver/IncrementalCompilation/TwoDMap.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ public struct TwoDMap<Key1: Hashable, Key2: Hashable, Value: Equatable>: Mutable
2121
public typealias Element = (Key, Value)
2222
public typealias Index = DictionaryOfDictionaries<Key1, Key2, Value>.Index
2323

24-
25-
2624
public init() {}
2725

2826
public subscript(position: Index) -> Element {

0 commit comments

Comments
 (0)