Do all hashing math in UInt32

This commit is contained in:
Justin Mazzocchi 2020-09-06 16:56:21 -07:00
parent 9e8b91e23b
commit bb44676a73
No known key found for this signature in database
GPG Key ID: E223E6937AAFB01C
2 changed files with 14 additions and 14 deletions

View File

@ -12,9 +12,9 @@ public enum DeterministicHasher: String, Codable {
extension DeterministicHasher { extension DeterministicHasher {
func apply(_ hashable: DeterministicallyHashable) -> Int { func apply(_ hashable: DeterministicallyHashable) -> Int {
Array(hashable.hashableData) Int(Array(hashable.hashableData)
.map(Int.init) .map(UInt32.init)
.reduce(offsetBasis, hash) .reduce(offsetBasis, hash))
} }
} }
@ -22,10 +22,9 @@ extension DeterministicHasher {
// http://www.isthe.com/chongo/tech/comp/fnv/ // http://www.isthe.com/chongo/tech/comp/fnv/
private extension DeterministicHasher { private extension DeterministicHasher {
static let fnvPrime = 16777619 static let fnvPrime: UInt32 = 16777619
static let u32mod = 2 << 31
var offsetBasis: Int { var offsetBasis: UInt32 {
switch self { switch self {
case .djb2, .djb2a: return 5381 case .djb2, .djb2a: return 5381
case .sdbm: return 0 case .sdbm: return 0
@ -33,18 +32,18 @@ private extension DeterministicHasher {
} }
} }
func hash(result: Int, next: Int) -> Int { func hash(result: UInt32, next: UInt32) -> UInt32 {
switch self { switch self {
case .djb2: case .djb2:
return (result << 5) &+ result &+ next return (result << 5) &+ result &+ next
case .djb2a: case .djb2a:
return ((result << 5) &+ result ^ next) % Self.u32mod return (result << 5) &+ result ^ next
case .sdbm: case .sdbm:
return next &+ (result << 6) &+ (result << 16) &- result return next &+ (result << 6) &+ (result << 16) &- result
case .fnv1: case .fnv1:
return (result * Self.fnvPrime % Self.u32mod) ^ next return (result &* Self.fnvPrime) ^ next
case .fnv1a: case .fnv1a:
return (result ^ next) * Self.fnvPrime % Self.u32mod return (result ^ next) &* Self.fnvPrime
} }
} }
} }

View File

@ -4,12 +4,13 @@
import XCTest import XCTest
final class CodableBloomFilterTests: XCTestCase { final class CodableBloomFilterTests: XCTestCase {
func testHashers() { func testHashers() {
XCTAssertEqual(DeterministicHasher.djb2.apply("hash"), 6385287881) XCTAssertEqual(DeterministicHasher.djb2.apply("hash"), 2090320585)
XCTAssertEqual(DeterministicHasher.djb2a.apply("hash"), 2087809207) XCTAssertEqual(DeterministicHasher.djb2a.apply("hash"), 2087809207)
XCTAssertEqual(DeterministicHasher.sdbm.apply("hash"), 29358318056884782) XCTAssertEqual(DeterministicHasher.sdbm.apply("hash"), 385600046)
XCTAssertEqual(DeterministicHasher.fnv1.apply("hash"), 0xd7918815) XCTAssertEqual(DeterministicHasher.fnv1.apply("hash"), 3616638997)
XCTAssertEqual(DeterministicHasher.fnv1a.apply("hash"), 0xcec577d1) XCTAssertEqual(DeterministicHasher.fnv1a.apply("hash"), 3469047761)
} }
func testContains() { func testContains() {