Skip to content

Commit 695a7f9

Browse files
committed
[stdlib] Move Dictionary(grouping:by) down a level
1 parent 4bfa2bf commit 695a7f9

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
@@ -1813,9 +1813,7 @@ public struct Dictionary<Key : Hashable, Value> :
18131813
by keyForValue: (S.Element) throws -> Key
18141814
) rethrows where Value == [S.Element] {
18151815
self = [:]
1816-
for value in values {
1817-
self[try keyForValue(value), default: []].append(value)
1818-
}
1816+
try _variantBuffer.nativeGroup(values, by: keyForValue)
18191817
}
18201818

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

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

0 commit comments

Comments
 (0)