| // RUN: %target-run-stdlib-swift |
| // REQUIRES: executable_test |
| |
| import Swift |
| import SwiftPrivate |
| import StdlibUnittest |
| |
| |
| var HashingTestSuite = TestSuite("Hashing") |
| |
| func checkHash( |
| for value: UInt64, |
| withSeed seed: UInt, |
| expected: UInt64, |
| file: String = #file, line: UInt = #line |
| ) { |
| var hasher = Hasher(_seed: Int(bitPattern: seed)) |
| hasher._combine(value) |
| let hash = hasher.finalize() |
| expectEqual( |
| hash, Int(truncatingIfNeeded: expected), |
| file: file, line: line) |
| } |
| |
| HashingTestSuite.test("Hasher/CustomKeys") { |
| // This assumes Hasher implements SipHash-1-3 and hashing is deterministic. |
| expectTrue(Hasher._isDeterministic) |
| |
| checkHash(for: 0, withSeed: 0, expected: 0xbd60acb658c79e45) |
| checkHash(for: 1, withSeed: 0, expected: 0x1e9f734161d62dd9) |
| checkHash(for: .max, withSeed: 0, expected: 0x2f205be2fec8e38d) |
| |
| checkHash(for: 0, withSeed: 1, expected: 0x9c44b7c8df2ca74b) |
| checkHash(for: 1, withSeed: 1, expected: 0xacb556b13007504a) |
| checkHash(for: .max, withSeed: 1, expected: 0x404afd8eb2c4b22a) |
| |
| checkHash(for: 0, withSeed: 0xFFFFFFFF, expected: 0x47329159fe988221) |
| checkHash(for: 1, withSeed: 0xFFFFFFFF, expected: 0xd7da861471fc35dc) |
| checkHash(for: .max, withSeed: 0xFFFFFFFF, expected: 0xf6e3047fc114dbc0) |
| |
| #if !(arch(i386) || arch(arm)) |
| checkHash(for: 0, withSeed: 0xFFFFFFFF_FFFFFFFF, expected: 0x8d0ea5ad8d6a55c7) |
| checkHash(for: 1, withSeed: 0xFFFFFFFF_FFFFFFFF, expected: 0x2899f60d6b5bc847) |
| checkHash(for: .max, withSeed: 0xFFFFFFFF_FFFFFFFF, expected: 0xc4d7726fff5e65a0) |
| #endif |
| } |
| |
| HashingTestSuite.test("Hasher/DefaultKey") { |
| let value: UInt64 = 0x0102030405060708 |
| |
| let defaultHash = _hashValue(for: value) |
| |
| let rawHash = value._rawHashValue(seed: 0) |
| expectEqual(rawHash, defaultHash) |
| |
| let oneShotHash = Hasher._hash(seed: 0, value) |
| expectEqual(oneShotHash, defaultHash) |
| |
| var defaultHasher = Hasher() |
| defaultHasher._combine(value) |
| expectEqual(defaultHasher.finalize(), defaultHash) |
| |
| var customHasher = Hasher(_seed: 0) |
| customHasher._combine(value) |
| expectEqual(customHasher.finalize(), defaultHash) |
| } |
| |
| HashingTestSuite.test("Hashing/TopLevelHashing/UInt64") { |
| func checkTopLevelHash( |
| for value: UInt64, |
| seed: Int, |
| file: String = #file, |
| line: UInt = #line) { |
| var hasher = Hasher(_seed: seed) |
| hasher._combine(value) |
| let expected = hasher.finalize() |
| let actual = Hasher._hash(seed: seed, value) |
| expectEqual(actual, expected, file: file, line: line) |
| } |
| checkTopLevelHash(for: 0, seed: 0) |
| checkTopLevelHash(for: 1, seed: 0) |
| checkTopLevelHash(for: 0, seed: 1) |
| checkTopLevelHash(for: 1, seed: 1) |
| checkTopLevelHash(for: 0x0102030405060708, seed: 1) |
| checkTopLevelHash(for: 0x0102030405060708, seed: Int.max) |
| checkTopLevelHash(for: UInt64.max, seed: 1) |
| checkTopLevelHash(for: UInt64.max, seed: Int.max) |
| } |
| |
| HashingTestSuite.test("Hashing/TopLevelHashing/UInt") { |
| func checkTopLevelHash( |
| for value: UInt, |
| seed: Int, |
| file: String = #file, |
| line: UInt = #line) { |
| var hasher = Hasher(_seed: seed) |
| hasher._combine(value) |
| let expected = hasher.finalize() |
| let actual = Hasher._hash(seed: seed, value) |
| expectEqual(actual, expected, file: file, line: line) |
| } |
| checkTopLevelHash(for: 0, seed: 0) |
| checkTopLevelHash(for: 1, seed: 0) |
| checkTopLevelHash(for: 0, seed: 1) |
| checkTopLevelHash(for: 1, seed: 1) |
| checkTopLevelHash( |
| for: UInt(truncatingIfNeeded: 0x0102030405060708 as UInt64), |
| seed: 1) |
| checkTopLevelHash( |
| for: UInt(truncatingIfNeeded: 0x0102030405060708 as UInt64), |
| seed: Int(truncatingIfNeeded: 0x8877665544332211 as UInt64)) |
| checkTopLevelHash(for: UInt.max, seed: 1) |
| checkTopLevelHash(for: UInt.max, seed: Int.max) |
| } |
| |
| HashingTestSuite.test("Hashing/TopLevelHashing/PartialUInt64") { |
| func checkTopLevelHash( |
| for value: UInt64, |
| count: Int, |
| seed: Int, |
| file: String = #file, |
| line: UInt = #line) { |
| var hasher = Hasher(_seed: seed) |
| hasher._combine(bytes: value, count: count) |
| let expected = hasher.finalize() |
| let actual = Hasher._hash(seed: seed, bytes: value, count: count) |
| expectEqual( |
| actual, |
| expected, |
| "seed: \(seed), value: \(value), count: \(count)", |
| file: file, |
| line: line) |
| } |
| for seed: Int in [ |
| 0, |
| 1, |
| 2, |
| Int(truncatingIfNeeded: 0x1827364554637281 as UInt64), |
| Int(truncatingIfNeeded: 0xf9e8d7c6b5a49382 as UInt64) |
| ] { |
| for count in 1 ..< 8 { |
| checkTopLevelHash(for: 0, count: count, seed: seed) |
| } |
| checkTopLevelHash(for: 0x01, count: 1, seed: seed) |
| checkTopLevelHash(for: 0x0102, count: 2, seed: seed) |
| checkTopLevelHash(for: 0x010203, count: 3, seed: seed) |
| checkTopLevelHash(for: 0x01020304, count: 4, seed: seed) |
| checkTopLevelHash(for: 0x0102030405, count: 5, seed: seed) |
| checkTopLevelHash(for: 0x010203040506, count: 6, seed: seed) |
| checkTopLevelHash(for: 0x01020304050607, count: 7, seed: seed) |
| } |
| } |
| |
| HashingTestSuite.test("Hashing/TopLevelHashing/UnsafeRawBufferPointer") { |
| func checkTopLevelHash( |
| for buffer: [UInt8], |
| seed: Int, |
| file: String = #file, |
| line: UInt = #line) { |
| var hasher = Hasher(_seed: seed) |
| buffer.withUnsafeBytes { buffer in |
| hasher.combine(bytes: buffer) |
| } |
| let expected = hasher.finalize() |
| let actual = buffer.withUnsafeBytes { buffer in |
| Hasher._hash(seed: seed, bytes: buffer) |
| } |
| expectEqual( |
| actual, |
| expected, |
| "seed: \(seed), buffer: \(buffer)", |
| file: file, |
| line: line) |
| } |
| for seed: Int in [ |
| 0, |
| 1, |
| 2, |
| Int(truncatingIfNeeded: 0x1827364554637281 as UInt64), |
| Int(truncatingIfNeeded: 0xf9e8d7c6b5a49382 as UInt64) |
| ] { |
| var zeros: [UInt8] = [] |
| var integers: [UInt8] = [] |
| for i: UInt8 in 0 ..< 20 { |
| zeros.append(0) |
| checkTopLevelHash(for: zeros, seed: seed) |
| integers.append(i) |
| checkTopLevelHash(for: integers, seed: seed) |
| } |
| } |
| } |
| |
| runAllTests() |