mirror of
https://github.com/metabolist/metatext.git
synced 2024-11-25 17:50:59 +00:00
Add more hashers
This commit is contained in:
parent
fc2aa33fae
commit
94c41facd0
2 changed files with 29 additions and 5 deletions
|
@ -4,33 +4,47 @@ import Foundation
|
||||||
|
|
||||||
public enum DeterministicHasher: String, Codable {
|
public enum DeterministicHasher: String, Codable {
|
||||||
case djb2
|
case djb2
|
||||||
|
case djb2a
|
||||||
case sdbm
|
case sdbm
|
||||||
|
case fnv1
|
||||||
|
case fnv1a
|
||||||
}
|
}
|
||||||
|
|
||||||
extension DeterministicHasher {
|
extension DeterministicHasher {
|
||||||
func apply(_ hashable: DeterministicallyHashable) -> Int {
|
func apply(_ hashable: DeterministicallyHashable) -> Int {
|
||||||
Array(hashable.hashableData)
|
Array(hashable.hashableData)
|
||||||
.map(Int.init)
|
.map(Int.init)
|
||||||
.reduce(initial, then)
|
.reduce(offsetBasis, hash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// http://www.cse.yorku.ca/~oz/hash.html
|
// http://www.cse.yorku.ca/~oz/hash.html
|
||||||
|
// http://www.isthe.com/chongo/tech/comp/fnv/
|
||||||
|
|
||||||
private extension DeterministicHasher {
|
private extension DeterministicHasher {
|
||||||
var initial: Int {
|
static let fnvPrime = 16777619
|
||||||
|
static let u32mod = 2 << 31
|
||||||
|
|
||||||
|
var offsetBasis: Int {
|
||||||
switch self {
|
switch self {
|
||||||
case .djb2: return 5381
|
case .djb2, .djb2a: return 5381
|
||||||
case .sdbm: return 0
|
case .sdbm: return 0
|
||||||
|
case .fnv1, .fnv1a: return 2166136261
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func then(result: Int, next: Int) -> Int {
|
func hash(result: Int, next: Int) -> Int {
|
||||||
switch self {
|
switch self {
|
||||||
case .djb2:
|
case .djb2:
|
||||||
return (result << 5) &+ result &+ next
|
return (result << 5) &+ result &+ next
|
||||||
|
case .djb2a:
|
||||||
|
return ((result << 5) &+ result ^ next) % Self.u32mod
|
||||||
case .sdbm:
|
case .sdbm:
|
||||||
return next &+ (result << 6) &+ (result << 16) - result
|
return next &+ (result << 6) &+ (result << 16) - result
|
||||||
|
case .fnv1:
|
||||||
|
return (result * Self.fnvPrime % Self.u32mod) ^ next
|
||||||
|
case .fnv1a:
|
||||||
|
return (result ^ next) * Self.fnvPrime % Self.u32mod
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,19 @@
|
||||||
|
// Copyright © 2020 Metabolist. All rights reserved.
|
||||||
|
|
||||||
@testable import CodableBloomFilter
|
@testable import CodableBloomFilter
|
||||||
import XCTest
|
import XCTest
|
||||||
|
|
||||||
final class CodableBloomFilterTests: XCTestCase {
|
final class CodableBloomFilterTests: XCTestCase {
|
||||||
|
func testHashers() {
|
||||||
|
XCTAssertEqual(DeterministicHasher.djb2.apply("hash"), 6385287881)
|
||||||
|
XCTAssertEqual(DeterministicHasher.djb2a.apply("hash"), 2087809207)
|
||||||
|
XCTAssertEqual(DeterministicHasher.sdbm.apply("hash"), 29358318056884782)
|
||||||
|
XCTAssertEqual(DeterministicHasher.fnv1.apply("hash"), 0xd7918815)
|
||||||
|
XCTAssertEqual(DeterministicHasher.fnv1a.apply("hash"), 0xcec577d1)
|
||||||
|
}
|
||||||
|
|
||||||
func testContains() {
|
func testContains() {
|
||||||
var sut = BloomFilter<String>(hashers: [.djb2, .sdbm], byteCount: 128)
|
var sut = BloomFilter<String>(hashers: [.djb2, .sdbm, .fnv1, .fnv1a], byteCount: 128)
|
||||||
|
|
||||||
sut.insert("lol")
|
sut.insert("lol")
|
||||||
sut.insert("ok")
|
sut.insert("ok")
|
||||||
|
|
Loading…
Reference in a new issue