Skip to content

Commit 1da820d

Browse files
author
Dave Abrahams
authored
Merge pull request #10275 from natecook1000/nc-dict-grouping
[stdlib] Move Dictionary(grouping:by) down a level
2 parents 406e72d + 695a7f9 commit 1da820d

File tree

1 file changed

+27
-3
lines changed

1 file changed

+27
-3
lines changed

stdlib/public/core/HashedCollections.swift.gyb

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1810,9 +1810,7 @@ public struct Dictionary<Key : Hashable, Value> :
18101810
by keyForValue: (S.Element) throws -> Key
18111811
) rethrows where Value == [S.Element] {
18121812
self = [:]
1813-
for value in values {
1814-
self[try keyForValue(value), default: []].append(value)
1815-
}
1813+
try _variantBuffer.nativeGroup(values, by: keyForValue)
18161814
}
18171815

18181816
internal init(_nativeBuffer: _NativeDictionaryBuffer<Key, Value>) {
@@ -5053,6 +5051,32 @@ internal enum _Variant${Self}Buffer<${TypeParametersDecl}> : _HashBuffer {
50535051
#endif
50545052
}
50555053
}
5054+
5055+
internal mutating func nativeGroup<S: Sequence>(
5056+
_ values: S,
5057+
by keyForValue: (S.Element) throws -> Key
5058+
) rethrows where Value == [S.Element] {
5059+
defer { _fixLifetime(asNative) }
5060+
for value in values {
5061+
let key = try keyForValue(value)
5062+
var (i, found) = asNative._find(key, startBucket: asNative._bucket(key))
5063+
if found {
5064+
asNative.values[i.offset].append(value)
5065+
} else {
5066+
let minCapacity = NativeBuffer.minimumCapacity(
5067+
minimumCount: asNative.count + 1,
5068+
maxLoadFactorInverse: _hashContainerDefaultMaxLoadFactorInverse)
5069+
5070+
let (_, capacityChanged) = ensureUniqueNativeBuffer(minCapacity)
5071+
if capacityChanged {
5072+
i = asNative._find(key, startBucket: asNative._bucket(key)).pos
5073+
}
5074+
5075+
asNative.initializeKey(key, value: [value], at: i.offset)
5076+
asNative.count += 1
5077+
}
5078+
}
5079+
}
50565080
%end
50575081

50585082
/// - parameter idealBucket: The ideal bucket for the element being deleted.

0 commit comments

Comments
 (0)