blob: dc80d105370a9b2b68449a5ba79371110968eeef [file] [log] [blame]
// 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()