blob: daa8e66fc5e48c57acf58ada4028412f8e3437c2 [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: (UInt64, UInt64),
expected: UInt64,
file: String = #file, line: UInt = #line
) {
var hasher = Hasher(_seed: 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.
checkHash(for: 0, withSeed: (0, 0), expected: 0xbd60acb658c79e45)
checkHash(for: 0, withSeed: (0, 1), expected: 0x1ce32b0b44e61175)
checkHash(for: 0, withSeed: (1, 0), expected: 0x9c44b7c8df2ca74b)
checkHash(for: 0, withSeed: (1, 1), expected: 0x9653ca0a3b455506)
checkHash(for: 0, withSeed: (.max, .max), expected: 0x3ab336a4895e4d36)
checkHash(for: 1, withSeed: (0, 0), expected: 0x1e9f734161d62dd9)
checkHash(for: 1, withSeed: (0, 1), expected: 0xb6fcf32d09f76cba)
checkHash(for: 1, withSeed: (1, 0), expected: 0xacb556b13007504a)
checkHash(for: 1, withSeed: (1, 1), expected: 0x7defec680db51d24)
checkHash(for: 1, withSeed: (.max, .max), expected: 0x212798441870ef6b)
checkHash(for: .max, withSeed: (0, 0), expected: 0x2f205be2fec8e38d)
checkHash(for: .max, withSeed: (0, 1), expected: 0x3ff7fa33381ecf7b)
checkHash(for: .max, withSeed: (1, 0), expected: 0x404afd8eb2c4b22a)
checkHash(for: .max, withSeed: (1, 1), expected: 0x855642d657c1bd46)
checkHash(for: .max, withSeed: (.max, .max), expected: 0x5b16b7a8181980c2)
}
HashingTestSuite.test("Hasher/DefaultKey") {
let value: UInt64 = 0x0102030405060708
let defaultHash = _hashValue(for: value)
let rawHash = value._rawHashValue(seed: Hasher._seed)
expectEqual(rawHash, defaultHash)
let oneShotHash = Hasher._hash(seed: Hasher._seed, value)
expectEqual(oneShotHash, defaultHash)
var defaultHasher = Hasher()
defaultHasher._combine(value)
expectEqual(defaultHasher.finalize(), defaultHash)
var customHasher = Hasher(_seed: Hasher._seed)
customHasher._combine(value)
expectEqual(customHasher.finalize(), defaultHash)
}
HashingTestSuite.test("Hashing/TopLevelHashing/UInt64") {
func checkTopLevelHash(
for value: UInt64,
seed: (UInt64, UInt64),
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, 0))
checkTopLevelHash(for: 1, seed: (0, 0))
checkTopLevelHash(for: 1, seed: (1, 0))
checkTopLevelHash(for: 1, seed: (1, 1))
checkTopLevelHash(for: 0x0102030405060708, seed: (1, 1))
checkTopLevelHash(
for: 0x0102030405060708,
seed: (0x0807060504030201, 0x090a0b0c0d0e0f))
checkTopLevelHash(for: UInt64.max, seed: (1, 1))
checkTopLevelHash(for: UInt64.max, seed: (UInt64.max, UInt64.max))
}
HashingTestSuite.test("Hashing/TopLevelHashing/UInt") {
func checkTopLevelHash(
for value: UInt,
seed: (UInt64, UInt64),
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, 0))
checkTopLevelHash(for: 1, seed: (0, 0))
checkTopLevelHash(for: 1, seed: (1, 0))
checkTopLevelHash(for: 1, seed: (1, 1))
checkTopLevelHash(
for: UInt(truncatingIfNeeded: 0x0102030405060708 as UInt64),
seed: (1, 1))
checkTopLevelHash(
for: UInt(truncatingIfNeeded: 0x0102030405060708 as UInt64),
seed: (0x8877665544332211, 0x1122334455667788))
checkTopLevelHash(for: UInt.max, seed: (1, 1))
checkTopLevelHash(for: UInt.max, seed: (UInt64.max, UInt64.max))
}
HashingTestSuite.test("Hashing/TopLevelHashing/PartialUInt64") {
func checkTopLevelHash(
for value: UInt64,
count: Int,
seed: (UInt64, UInt64),
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: (UInt64, UInt64) in [
(0, 0),
(1, 0),
(1, 1),
(0x1827364554637281, 0xf9e8d7c6b5a49382)
] {
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: (UInt64, UInt64),
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: (UInt64, UInt64) in [
(0, 0),
(1, 0),
(1, 1),
(0x1827364554637281, 0xf9e8d7c6b5a49382)
] {
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()