Skip to content

Commit 91b40b2

Browse files
committed
Clean up
1 parent 59d265e commit 91b40b2

1 file changed

Lines changed: 134 additions & 113 deletions

File tree

Sources/Compiler/Utils/DuplicateDictionary.swift

Lines changed: 134 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public struct DuplicateDictionary<Key: Hashable, Value> {
2222
internal var _values: ContiguousArray<_Element>
2323
/// A dictionary where each value is located.
2424
@usableFromInline
25-
internal var positions: [Key: DuplicateDictionaryPositions]
25+
internal var positions: [Key: Positions]
2626

2727
public typealias Index = Int
2828
public typealias Element = (key: Key, value: Value)
@@ -46,12 +46,14 @@ public struct DuplicateDictionary<Key: Hashable, Value> {
4646

4747
/// Result value from a key lookup.
4848
public struct Entries {
49-
private let positions: DuplicateDictionaryPositions
50-
private let owner: DuplicateDictionary
49+
@usableFromInline
50+
let positions: Positions
51+
@usableFromInline
52+
let owner: DuplicateDictionary
5153

5254
@inline(__always)
5355
fileprivate init(
54-
positions: DuplicateDictionaryPositions,
56+
positions: Positions,
5557
owner: DuplicateDictionary
5658
) {
5759
self.positions = positions
@@ -71,14 +73,73 @@ public struct DuplicateDictionary<Key: Hashable, Value> {
7173
}
7274
}
7375

76+
/// Where the element is location in the `values` array.
77+
public enum Positions: Sendable, Equatable, Sequence {
78+
public typealias Index = Int
79+
public typealias Element = Int
80+
81+
/// Nowhere
82+
case empty
83+
/// Just a single location
84+
case single(Int)
85+
/// In many spots
86+
case many([Int])
87+
88+
/// How many spots it exists
89+
@inline(__always)
90+
@inlinable
91+
var count: Int {
92+
return switch self {
93+
case .empty: 0
94+
case .single: 1
95+
case .many(let i): i.count
96+
}
97+
}
98+
99+
/// Adds the index to the positions
100+
@inline(__always)
101+
mutating func adding(_ index: Int) {
102+
switch self {
103+
case .empty:
104+
self = .single(index)
105+
case .single(let existing):
106+
self = .many([existing, index])
107+
case .many(var existing):
108+
existing.append(index)
109+
self = .many(existing)
110+
}
111+
}
112+
113+
public func makeIterator() -> Iterator {
114+
Iterator(positions: self)
115+
}
116+
117+
public struct Iterator: IteratorProtocol {
118+
let positions: Positions
119+
var currentIndex = 0
120+
121+
public mutating func next() -> Element? {
122+
switch positions {
123+
case .empty:
124+
return nil
125+
case .single(let index):
126+
return currentIndex == 0 ? index : nil
127+
case .many(let indices):
128+
guard currentIndex < indices.count else { return nil }
129+
return indices[currentIndex]
130+
}
131+
}
132+
}
133+
}
134+
74135
public init() {
75136
self._values = []
76137
self.positions = [:]
77138
}
78139

79140
private init(
80141
values: ContiguousArray<_Element>,
81-
positions: [Key : DuplicateDictionaryPositions]
142+
positions: [Key : Positions]
82143
) {
83144
self._values = values
84145
self.positions = positions
@@ -92,6 +153,15 @@ public struct DuplicateDictionary<Key: Hashable, Value> {
92153
positions[key, default: .empty].adding(index)
93154
}
94155

156+
@inline(__always)
157+
public mutating func append<S: Sequence>(
158+
contentsOf collection: S
159+
) where S.Element == Element {
160+
for (key, value) in collection {
161+
append(value, for: key)
162+
}
163+
}
164+
95165
/// Gets the values for the given key
96166
@inline(__always)
97167
public subscript(key: Key) -> Entries {
@@ -107,6 +177,11 @@ public struct DuplicateDictionary<Key: Hashable, Value> {
107177
positions.reserveCapacity(minimumCapacity)
108178
}
109179

180+
public func contains(key: Key) -> Bool {
181+
guard let p = positions[key] else { return false }
182+
return p != .empty
183+
}
184+
110185
/// Map over the values and transform them into a new dictionary
111186
/// with the same keys but with the transformed values.
112187
public func mapValues<T>(
@@ -116,7 +191,13 @@ public struct DuplicateDictionary<Key: Hashable, Value> {
116191
values: ContiguousArray(_values.map{
117192
DuplicateDictionary<Key, T>._Element($0.key, try transform($0.value))
118193
}),
119-
positions: positions
194+
positions: positions.reduce(into: [:]) { r, p in
195+
r[p.key] = switch p.value {
196+
case .empty: .empty
197+
case .single(let i): .single(i)
198+
case .many(let i): .many(i)
199+
}
200+
}
120201
)
121202
}
122203
}
@@ -174,40 +255,39 @@ extension DuplicateDictionary: Collection {
174255
}
175256
}
176257

177-
extension DuplicateDictionary.Entries: Sequence {
258+
extension DuplicateDictionary.Entries: Collection {
178259
public typealias Element = Value
260+
public typealias Index = Int
179261

180262
@inline(__always)
263+
@inlinable
264+
public subscript(index: Index) -> Element {
265+
switch positions {
266+
case .empty:
267+
preconditionFailure("Index out of bounds")
268+
case .single(let i):
269+
guard index == 0 else { preconditionFailure("Index out of bounds") }
270+
return owner._values[i].value
271+
case .many(let i):
272+
return owner._values[i[index]].value
273+
}
274+
}
275+
276+
@inline(__always)
277+
@inlinable
181278
public var count: Int { positions.count }
182279

183280
@inline(__always)
184-
public func makeIterator() -> Iterator {
185-
Iterator(element: self)
186-
}
281+
@inlinable
282+
public var startIndex: Int { 0 }
187283

188-
public struct Iterator: IteratorProtocol {
189-
private let element: DuplicateDictionary.Entries
190-
private var currentIndex = 0
191-
192-
init(element: DuplicateDictionary.Entries) {
193-
self.element = element
194-
}
195-
196-
@inline(__always)
197-
public mutating func next() -> Value? {
198-
defer { currentIndex += 1 }
199-
200-
switch element.positions {
201-
case .empty:
202-
return nil
203-
case .single(let index):
204-
return currentIndex == 0 ? element.owner._values[index].value : nil
205-
case .many(let indices):
206-
guard currentIndex < indices.count else { return nil }
207-
return element.owner._values[currentIndex].value
208-
}
209-
}
210-
}
284+
@inline(__always)
285+
@inlinable
286+
public var endIndex: Int { positions.count }
287+
288+
@inline(__always)
289+
@inlinable
290+
public func index(after i: Index) -> Index { i + 1 }
211291
}
212292

213293
extension DuplicateDictionary {
@@ -216,33 +296,36 @@ extension DuplicateDictionary {
216296
Values(dictionary: self)
217297
}
218298

219-
public struct Values: Sequence {
299+
public struct Values: Collection {
220300
public typealias Element = Value
221301

302+
@usableFromInline
222303
let dictionary: DuplicateDictionary
223304

224305
init(dictionary: DuplicateDictionary) {
225306
self.dictionary = dictionary
226307
}
227308

228-
public func makeIterator() -> Iterator {
229-
return Iterator(dictionary: dictionary)
230-
}
309+
@inline(__always)
310+
@inlinable
311+
public subscript(index: Index) -> Element { dictionary._values[index].value }
231312

232-
public struct Iterator: IteratorProtocol {
233-
private let dictionary: DuplicateDictionary
234-
private var index = 0
235-
236-
@usableFromInline
237-
init(dictionary: DuplicateDictionary) {
238-
self.dictionary = dictionary
239-
}
240-
241-
public mutating func next() -> Element? {
242-
guard index < dictionary._values.count else { return nil }
243-
defer { index += 1 }
244-
return dictionary._values[index].value
245-
}
313+
@inline(__always)
314+
@inlinable
315+
public var count: Int { dictionary._values.count }
316+
317+
@inline(__always)
318+
@inlinable
319+
public var startIndex: Int { dictionary._values.startIndex }
320+
321+
@inline(__always)
322+
@inlinable
323+
public var endIndex: Int { dictionary._values.endIndex }
324+
325+
@inline(__always)
326+
@inlinable
327+
public func index(after i: Index) -> Index {
328+
dictionary._values.index(after: i)
246329
}
247330
}
248331
}
@@ -251,65 +334,3 @@ extension DuplicateDictionary: Sendable where Key: Sendable, Value: Sendable {}
251334
extension DuplicateDictionary._Element: Sendable where Key: Sendable, Value: Sendable {}
252335
extension DuplicateDictionary._Element: Equatable where Key: Equatable, Value: Equatable {}
253336
extension DuplicateDictionary: Equatable where Key: Equatable, Value: Equatable {}
254-
255-
/// Where the element is location in the `values` array.
256-
///
257-
/// This cannot be nested in the `DuplicateDictionary` struct
258-
/// due to the `mapValues` since `DuplicateDictionary<T, V>.Positions`
259-
/// is not equal too `DuplicateDictionary<T, NewValue>.Positions`
260-
public enum DuplicateDictionaryPositions: Sendable, Equatable, Sequence {
261-
public typealias Index = Int
262-
public typealias Element = Int
263-
264-
/// Nowhere
265-
case empty
266-
/// Just a single location
267-
case single(Int)
268-
/// In many spots
269-
case many([Int])
270-
271-
/// How many spots it exists
272-
@inline(__always)
273-
var count: Int {
274-
return switch self {
275-
case .empty: 0
276-
case .single: 1
277-
case .many(let i): i.count
278-
}
279-
}
280-
281-
/// Adds the index to the positions
282-
@inline(__always)
283-
mutating func adding(_ index: Int) {
284-
switch self {
285-
case .empty:
286-
self = .single(index)
287-
case .single(let existing):
288-
self = .many([existing, index])
289-
case .many(var existing):
290-
existing.append(index)
291-
self = .many(existing)
292-
}
293-
}
294-
295-
public func makeIterator() -> Iterator {
296-
Iterator(positions: self)
297-
}
298-
299-
public struct Iterator: IteratorProtocol {
300-
let positions: DuplicateDictionaryPositions
301-
var currentIndex = 0
302-
303-
public mutating func next() -> Element? {
304-
switch positions {
305-
case .empty:
306-
return nil
307-
case .single(let index):
308-
return currentIndex == 0 ? index : nil
309-
case .many(let indices):
310-
guard currentIndex < indices.count else { return nil }
311-
return indices[currentIndex]
312-
}
313-
}
314-
}
315-
}

0 commit comments

Comments
 (0)