diff --git a/stdlib/public/core/DictionaryStorage.swift b/stdlib/public/core/DictionaryStorage.swift index 39ac76578f126..ac931fd2ed51c 100644 --- a/stdlib/public/core/DictionaryStorage.swift +++ b/stdlib/public/core/DictionaryStorage.swift @@ -196,6 +196,35 @@ extension __RawDictionaryStorage { return Builtin.bridgeFromRawPointer( Builtin.addressof(&_swiftEmptyDictionarySingleton)) } + + @_alwaysEmitIntoClient + @inline(__always) + internal final func uncheckedKey(at bucket: _HashTable.Bucket) -> Key { + defer { _fixLifetime(self) } + _internalInvariant(_hashTable.isOccupied(bucket)) + let keys = _rawKeys.assumingMemoryBound(to: Key.self) + return keys[bucket.offset] + } + + @_alwaysEmitIntoClient + @inline(never) + internal final func find(_ key: Key) -> (bucket: _HashTable.Bucket, found: Bool) { + return find(key, hashValue: key._rawHashValue(seed: _seed)) + } + + @_alwaysEmitIntoClient + @inline(never) + internal final func find(_ key: Key, hashValue: Int) -> (bucket: _HashTable.Bucket, found: Bool) { + let hashTable = _hashTable + var bucket = hashTable.idealBucket(forHashValue: hashValue) + while hashTable._isOccupied(bucket) { + if uncheckedKey(at: bucket) == key { + return (bucket, true) + } + bucket = hashTable.bucket(wrappedAfter: bucket) + } + return (bucket, false) + } } @usableFromInline diff --git a/stdlib/public/core/NativeDictionary.swift b/stdlib/public/core/NativeDictionary.swift index 4dcbd68ce642d..6aa6a45a03dbc 100644 --- a/stdlib/public/core/NativeDictionary.swift +++ b/stdlib/public/core/NativeDictionary.swift @@ -161,7 +161,7 @@ extension _NativeDictionary { // Low-level lookup operations @inlinable @inline(__always) internal func find(_ key: Key) -> (bucket: Bucket, found: Bool) { - return find(key, hashValue: self.hashValue(for: key)) + return _storage.find(key) } /// Search for a given element, assuming it has the specified hash value. @@ -174,15 +174,7 @@ extension _NativeDictionary { // Low-level lookup operations _ key: Key, hashValue: Int ) -> (bucket: Bucket, found: Bool) { - let hashTable = self.hashTable - var bucket = hashTable.idealBucket(forHashValue: hashValue) - while hashTable._isOccupied(bucket) { - if uncheckedKey(at: bucket) == key { - return (bucket, true) - } - bucket = hashTable.bucket(wrappedAfter: bucket) - } - return (bucket, false) + return _storage.find(key, hashValue: hashValue) } }