Skip to content

Commit a8bca08

Browse files
committed
[stdlib] Switch Dictionary and Set to use resilient hashing.
This switches the primary hashing interface from hashValue to _hash(into:).
1 parent ecc5d83 commit a8bca08

File tree

3 files changed

+1
-48
lines changed

3 files changed

+1
-48
lines changed

stdlib/public/core/HashedCollections.swift.gyb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3984,7 +3984,7 @@ extension _Native${Self}Buffer
39843984
@_versioned
39853985
@inline(__always) // For performance reasons.
39863986
internal func _bucket(_ k: Key) -> Int {
3987-
return _squeezeHashValue(k.hashValue, bucketCount)
3987+
return _hashValue(for: k) & _bucketMask
39883988
}
39893989

39903990
@_inlineable // FIXME(sil-serialize-all)

stdlib/public/core/Hashing.swift

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -168,35 +168,6 @@ func _mixInt(_ value: Int) -> Int {
168168
#endif
169169
}
170170

171-
/// Given a hash value, returns an integer value in the range of
172-
/// 0..<`upperBound` that corresponds to a hash value.
173-
///
174-
/// The `upperBound` must be positive and a power of 2.
175-
///
176-
/// This function is superior to computing the remainder of `hashValue` by
177-
/// the range length. Some types have bad hash functions; sometimes simple
178-
/// patterns in data sets create patterns in hash values and applying the
179-
/// remainder operation just throws away even more information and invites
180-
/// even more hash collisions. This effect is especially bad because the
181-
/// range is a power of two, which means to throws away high bits of the hash
182-
/// (which would not be a problem if the hash was known to be good). This
183-
/// function mixes the bits in the hash value to compensate for such cases.
184-
///
185-
/// Of course, this function is a compressing function, and applying it to a
186-
/// hash value does not change anything fundamentally: collisions are still
187-
/// possible, and it does not prevent malicious users from constructing data
188-
/// sets that will exhibit pathological collisions.
189-
@_inlineable // FIXME(sil-serialize-all)
190-
public // @testable
191-
func _squeezeHashValue(_ hashValue: Int, _ upperBound: Int) -> Int {
192-
_sanityCheck(_isPowerOf2(upperBound))
193-
let mixedHashValue = _mixInt(hashValue)
194-
195-
// As `upperBound` is a power of two we can do a bitwise-and to calculate
196-
// mixedHashValue % upperBound.
197-
return mixedHashValue & (upperBound &- 1)
198-
}
199-
200171
/// Returns a new value that combines the two given hash values.
201172
///
202173
/// Combining is performed using [a hash function][ref] described by T.C. Hoad

validation-test/stdlib/Hashing.swift

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -70,24 +70,6 @@ HashingTestSuite.test("_mixInt/GoldenValues") {
7070
#endif
7171
}
7272

73-
HashingTestSuite.test("_squeezeHashValue/Int") {
74-
// Check that the function can return values that cover the whole range.
75-
func checkRange(_ r: Int) {
76-
var results = Set<Int>()
77-
for _ in 0..<(14 * r) {
78-
let v = _squeezeHashValue(randInt(), r)
79-
expectTrue(v < r)
80-
results.insert(v)
81-
}
82-
expectEqual(r, results.count)
83-
}
84-
checkRange(1)
85-
checkRange(2)
86-
checkRange(4)
87-
checkRange(8)
88-
checkRange(16)
89-
}
90-
9173
HashingTestSuite.test("String/hashValue/topBitsSet") {
9274
#if _runtime(_ObjC)
9375
#if arch(x86_64) || arch(arm64)

0 commit comments

Comments
 (0)