simplify CCHash

- remove functor
- use `Hashtbl.seeded_hash` to combine values
This commit is contained in:
Simon Cruanes 2016-11-03 22:16:48 +01:00
parent 2c00983262
commit 192f315f53
2 changed files with 55 additions and 202 deletions

View file

@ -9,79 +9,27 @@ type 'a sequence = ('a -> unit) -> unit
type 'a gen = unit -> 'a option type 'a gen = unit -> 'a option
type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist] type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist]
let _r = 47 type state = int
let _m = 0xc6a4a7935bd1e995L
let init = _m
(* combine key [k] with the current state [s] *)
let combine_murmur_ s k =
let k = Int64.mul _m k in
let k = Int64.logxor k (Int64.shift_right k _r) in
let k = Int64.mul _m k in
let s = Int64.logxor s k in
let s = Int64.mul _m s in
s
let finish s =
let s = Int64.logxor s (Int64.shift_right s _r) in
let s = Int64.mul s _m in
let s = Int64.logxor s (Int64.shift_right s _r) in
(Int64.to_int s) land max_int
let apply f x = finish (f x init)
(** {2 Combinators} *)
(** {2 Generic Hashing} *)
module type HASH = sig
type state
val int : int -> state -> state
val bool : bool -> state -> state
val char : char -> state -> state
val int32 : int32 -> state -> state
val int64 : int64 -> state -> state
val nativeint : nativeint -> state -> state
val slice : string -> int -> int -> state -> state
(** [slice s i len state] hashes the slice [[i, ... i+len)] of [s]
into [state] *)
end
module type S = sig
include HASH
type 'a hash_fun = 'a -> state -> state type 'a hash_fun = 'a -> state -> state
val string : string hash_fun let combine f x s = Hashtbl.seeded_hash s (f x)
val list : 'a hash_fun -> 'a list hash_fun let combine2 a b = Hashtbl.seeded_hash a b
val array : 'a hash_fun -> 'a array hash_fun let init : state = 0
let finish i = i
val opt : 'a hash_fun -> 'a option hash_fun let apply f x = f x init
val pair : 'a hash_fun -> 'b hash_fun -> ('a * 'b) hash_fun
val triple : 'a hash_fun -> 'b hash_fun -> 'c hash_fun -> ('a * 'b * 'c) hash_fun
val if_ : bool -> 'a hash_fun -> 'a hash_fun -> 'a hash_fun (** {2 Combinators} *)
(** Decide which hash function to use depending on the boolean *)
(** {2 Iterators} *) let int i s = combine2 s (Int64.of_int i)
let bool x s = combine2 s (if x then 1L else 2L)
val seq : 'a hash_fun -> 'a sequence hash_fun let char x s = combine2 s (Int64.of_int (Char.code x))
val gen : 'a hash_fun -> 'a gen hash_fun let int32 x s = combine2 s (Int64.of_int32 x)
val klist : 'a hash_fun -> 'a klist hash_fun let int64 x s = combine2 s x
end let nativeint x s = combine2 s (Int64.of_nativeint x)
module Base = struct
type state = int64
let int i s = combine_murmur_ s (Int64.of_int i)
let bool x s = combine_murmur_ s (if x then 1L else 2L)
let char x s = combine_murmur_ s (Int64.of_int (Char.code x))
let int32 x s = combine_murmur_ s (Int64.of_int32 x)
let int64 x s = combine_murmur_ s x
let nativeint x s = combine_murmur_ s (Int64.of_nativeint x)
let slice x i len s = let slice x i len s =
let j=i+len in let j=i+len in
@ -89,12 +37,6 @@ module Base = struct
if i=j then s else aux (i+1) (char x.[i] s) if i=j then s else aux (i+1) (char x.[i] s)
in in
aux i s aux i s
end
module Make(H : HASH) : S with type state = H.state = struct
include H
type 'a hash_fun = 'a -> state -> state
let rec list f l s = match l with let rec list f l s = match l with
| [] -> s | [] -> s
@ -125,19 +67,3 @@ module Make(H : HASH) : S with type state = H.state = struct
let rec klist f l s = match l () with let rec klist f l s = match l () with
| `Nil -> s | `Nil -> s
| `Cons (x,l') -> klist f l' (f x s) | `Cons (x,l') -> klist f l' (f x s)
end
include Make(Base)
(* deprecated aliases *)
let int_ = int
let bool_ = bool
let char_ = char
let int32_ = int32
let int64_ = int64
let nativeint_ = nativeint
let string_ = string
let list_ = list
let array_ = array

View file

@ -9,15 +9,11 @@ type t = int
(** A hash value is a positive integer *) (** A hash value is a positive integer *)
type state type state
(** State required by the hash function.
@since 0.16 the state is abstract, for more flexibility *)
type 'a hash_fun = 'a -> state -> state type 'a hash_fun = 'a -> state -> state
(** Hash function for values of type ['a], merging a fingerprint of the (** Hash function for values of type ['a], merging a fingerprint of the
value into the state of type [t] *) value into the state of type [t] *)
(** {2 Applying Hash} *)
val init : state val init : state
(** Initial value *) (** Initial value *)
@ -28,41 +24,23 @@ val apply : 'a hash_fun -> 'a -> int
(** Apply a hash function to a value. (** Apply a hash function to a value.
[apply f x] is the same as [finish (f x init)] *) [apply f x] is the same as [finish (f x init)] *)
(** {2 Basic Combinators} val int : int hash_fun
val bool : bool hash_fun
val char : char hash_fun
val int32 : int32 hash_fun
val int64 : int64 hash_fun
val nativeint : nativeint hash_fun
val slice : string -> int -> int hash_fun
(** [slice s i len state] hashes the slice [i, ... i+len-1] of [s]
into [state] *)
Those combinators have been renamed in 0.13, so as to val combine : ('a -> int) -> 'a hash_fun
remove the trailing "_".
They are now defined by the application of {!Make}
*) val string : string hash_fun
val bool_ : bool hash_fun val list : 'a hash_fun -> 'a list hash_fun
(** @deprecated use {!bool} *)
val char_ : char hash_fun val array : 'a hash_fun -> 'a array hash_fun
(** @deprecated use {!char} *)
val int_ : int hash_fun
(** @deprecated use {!int} *)
val string_ : string hash_fun
(** @deprecated use {!string} *)
val int32_ : int32 hash_fun
(** @deprecated use {!int32} *)
val int64_ : int64 hash_fun
(** @deprecated use {!int64} *)
val nativeint_ : nativeint hash_fun
(** @deprecated use {!nativeint} *)
val list_ : 'a hash_fun -> 'a list hash_fun
(** Hash a list. Each element is hashed using [f].
@deprecated use {!list} *)
val array_ : 'a hash_fun -> 'a array hash_fun
(** @deprecated use {!array} *)
val opt : 'a hash_fun -> 'a option hash_fun val opt : 'a hash_fun -> 'a option hash_fun
val pair : 'a hash_fun -> 'b hash_fun -> ('a * 'b) hash_fun val pair : 'a hash_fun -> 'b hash_fun -> ('a * 'b) hash_fun
@ -80,54 +58,3 @@ type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist]
val seq : 'a hash_fun -> 'a sequence hash_fun val seq : 'a hash_fun -> 'a sequence hash_fun
val gen : 'a hash_fun -> 'a gen hash_fun val gen : 'a hash_fun -> 'a gen hash_fun
val klist : 'a hash_fun -> 'a klist hash_fun val klist : 'a hash_fun -> 'a klist hash_fun
(** {2 Generic Hashing}
Parametrize over the state, and some primitives to hash basic types.
This can for instance be used for cryptographic hashing or
checksums such as MD5.
@since 0.13 *)
module type HASH = sig
type state
val int : int -> state -> state
val bool : bool -> state -> state
val char : char -> state -> state
val int32 : int32 -> state -> state
val int64 : int64 -> state -> state
val nativeint : nativeint -> state -> state
val slice : string -> int -> int -> state -> state
(** [slice s i len state] hashes the slice [i, ... i+len-1] of [s]
into [state] *)
end
module type S = sig
include HASH
type 'a hash_fun = 'a -> state -> state
val string : string hash_fun
val list : 'a hash_fun -> 'a list hash_fun
val array : 'a hash_fun -> 'a array hash_fun
val opt : 'a hash_fun -> 'a option hash_fun
val pair : 'a hash_fun -> 'b hash_fun -> ('a * 'b) hash_fun
val triple : 'a hash_fun -> 'b hash_fun -> 'c hash_fun -> ('a * 'b * 'c) hash_fun
val if_ : bool -> 'a hash_fun -> 'a hash_fun -> 'a hash_fun
(** Decide which hash function to use depending on the boolean *)
(** {2 Iterators} *)
val seq : 'a hash_fun -> 'a sequence hash_fun
val gen : 'a hash_fun -> 'a gen hash_fun
val klist : 'a hash_fun -> 'a klist hash_fun
end
module Make(H : HASH) : S with type state = H.state
include S with type state := state and type 'a hash_fun := 'a hash_fun