Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Hash functions #507

Open
wants to merge 2 commits into from

1 participant

@c-cube
Owner

Early draft for #492, as simple as possible (and even more). I just implemented hash functions for a few modules, but it should be easy to do so for other structures (e.g. BatLazyList or Tuple2, Tuple3...).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
7 src/batArray.ml
@@ -513,6 +513,13 @@ let compare cmp a b =
compare (fun x y -> -(Pervasives.compare x y)) [|2;1|] [|1;2|] = -1
*)
+let hash h_elem a =
+ let h = ref 0 in
+ for i = 0 to length a - 1 do
+ h := BatHash.sdbm !h (h_elem (unsafe_get a i));
+ done;
+ !h land max_int
+
let print ?(first="[|") ?(last="|]") ?(sep="; ") print_a out t =
match length t with
| 0 ->
View
3  src/batArray.mli
@@ -517,6 +517,9 @@ val ord : 'a BatOrd.ord -> 'a array BatOrd.ord
lexicographically for arrays of the same size. This is a
different ordering than [compare], but is often faster. *)
+val hash : 'a BatHash.hash -> 'a array BatHash.hash
+(** Hash array by its elements, from left to right *)
+
val equal : 'a BatOrd.eq -> 'a array BatOrd.eq
(** Hoist a equality test for elements to arrays. Arrays are only
equal if their lengths are the same and corresponding elements
View
31 src/batHash.ml
@@ -0,0 +1,31 @@
+(*
+ * Interfaces - Common interfaces for data structures
+ * Copyright (C) 2008 David Teller, LIFO, Universite d'Orleans
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version,
+ * with the special exception on linking described in file LICENSE.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *)
+
+(** Hash mixing functions.
+ See http://burtleburtle.net/bob/hash/integer.html and
+ http://www.cse.yorku.ca/~oz/hash.html for more details *)
+
+type 'a hash = 'a -> int
+
+type mix_int = int -> int -> int
+
+(** SDBM simple hash (see for instance http://www.cse.yorku.ca/~oz/hash.html) *)
+let sdbm hash i = (hash * 65599 + i) land max_int
+
View
38 src/batHash.mli
@@ -0,0 +1,38 @@
+(*
+ * Interfaces - Common interfaces for data structures
+ * Copyright (C) 2008 David Teller, LIFO, Universite d'Orleans
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version,
+ * with the special exception on linking described in file LICENSE.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *)
+
+(** Hashing *)
+
+(** Simple and efficient hash functions for use in Hashtbl. Not designed
+ for cryptographic hashing. *)
+
+type 'a hash = 'a -> int
+(** A function that maps values of type [t] to {b positive} integers.
+ It must be compatible with equality, that is, if equality is defined
+ on [t] (say a function [eq : t -> t -> bool], then for use in
+ a Hash table it is required that whenever, for [a:t] and [b:t],
+ [eq a b] holds, then [hash a = hash b] must also hold. *)
+
+type mix_int = int -> int -> int
+(** [mix_int] describes functions to combine (positive) integers together,
+ in the present context to mix hash values together (say, when hashing
+ a list) *)
+
+val sdbm : mix_int
View
5 src/batInt.ml
@@ -201,6 +201,11 @@ let popcount_sparse x =
(Q.int) (fun x -> popcount x = popcount_sparse x)
*)
+let hash i = i land max_int
+(*$Q hash
+ (Q.int) (fun x -> hash x >= 0)
+*)
+
module BaseSafeInt = struct
include BaseInt
View
2  src/batInt.mli
@@ -216,6 +216,8 @@ val equal : t -> t -> bool
val ord : t -> t -> BatOrd.order
+val hash : t BatHash.hash
+
(**
Safe operations on integers.
View
5 src/batInterfaces.ml
@@ -29,6 +29,11 @@ sig
val compare : t -> t -> int
end
+module type Hashable = sig
+ type t
+ val hash : t -> int
+end
+
module type Monad = sig
type 'a m
val bind : 'a m -> ('a -> 'b m) -> 'b m
View
3  src/batList.ml
@@ -1262,6 +1262,9 @@ let rec compare comp_elt l1 l2 =
| [] -> 1
| hd2::tl2 -> bin_comp comp_elt hd1 hd2 (compare comp_elt) tl1 tl2)
+let hash h_elem l =
+ fold_left (fun h x -> BatHash.sdbm h (h_elem x)) 0 l
+
module Eq (T : Eq) = struct
type t = T.t list
let eq = eq T.eq
View
1  src/batList.mli
@@ -731,6 +731,7 @@ open BatOrd
val eq : 'a eq -> 'a list eq
val ord : 'a ord -> 'a list ord
val compare : 'a comp -> 'a list comp
+val hash : 'a BatHash.hash -> 'a list BatHash.hash
(** Comparison and equality for lists based on element comparison and
equality *)
View
13 src/batSet.ml
@@ -421,6 +421,16 @@ module Concrete = struct
c in
compare_aux (cons_iter s1 E) (cons_iter s2 E)
+ let hash h_elem s =
+ let rec hash_aux h s = match s with
+ | Empty -> h
+ | Node(l, v, r, _) ->
+ let h = hash_aux h l in
+ let h = BatHash.sdbm h (h_elem v) in
+ hash_aux h r
+ in
+ hash_aux 0 s
+
let equal cmp s1 s2 = compare cmp s1 s2 = 0
let rec subset cmp s1 s2 =
@@ -455,6 +465,7 @@ sig
val diff: t -> t -> t
val sym_diff: t -> t -> t
val compare: t -> t -> int
+ val hash : elt BatHash.hash -> t BatHash.hash
val equal: t -> t -> bool
val subset: t -> t -> bool
val disjoint: t -> t -> bool
@@ -574,6 +585,7 @@ struct
t_of_impl (Concrete.sym_diff Ord.compare (impl_of_t s1) (impl_of_t s2))
let compare t1 t2 = Concrete.compare Ord.compare (impl_of_t t1) (impl_of_t t2)
+ let hash h_elem s = Concrete.hash h_elem (impl_of_t s)
let equal t1 t2 = Concrete.equal Ord.compare (impl_of_t t1) (impl_of_t t2)
let subset t1 t2 = Concrete.subset Ord.compare (impl_of_t t1) (impl_of_t t2)
let disjoint t1 t2 = Concrete.disjoint Ord.compare (impl_of_t t1) (impl_of_t t2)
@@ -694,6 +706,7 @@ module PSet = struct (*$< PSet *)
let intersect s1 s2 =
{ s1 with set = Concrete.inter s1.cmp s1.set s2.set }
let compare s1 s2 = Concrete.compare s1.cmp s1.set s2.set
+ let hash h_elem s = Concrete.hash h_elem s.set
let equal s1 s2 = Concrete.equal s1.cmp s1.set s2.set
let subset s1 s2 = Concrete.subset s1.cmp s1.set s2.set
let disjoint s1 s2 = Concrete.disjoint s1.cmp s1.set s2.set
View
6 src/batSet.mli
@@ -101,6 +101,9 @@ sig
(** Total ordering between sets. Can be used as the ordering function
for doing sets of sets. *)
+ val hash : elt BatHash.hash -> t BatHash.hash
+ (** Hash the set by hashing its elements *)
+
val equal: t -> t -> bool
(** [equal s1 s2] tests whether the sets [s1] and [s2] are
equal, that is, contain equal elements. *)
@@ -606,6 +609,9 @@ module PSet : sig
(** Total ordering between sets. Can be used as the ordering function
for doing sets of sets. *)
+ val hash : 'a BatHash.hash -> 'a t BatHash.hash
+ (** Hash polymorphic set by hashing its elements *)
+
val equal: 'a t -> 'a t -> bool
(** [equal s1 s2] tests whether the sets [s1] and [s2] are
equal, that is, contain equal elements. *)
View
11 src/batString.ml
@@ -30,6 +30,17 @@ let compare = String.compare
let equal a b = String.compare a b = 0
let ord = BatOrd.ord String.compare
+external old_hash_param :
+ int -> int -> 'a -> int = "caml_hash_univ_param" "noalloc"
+
+let hash s = old_hash_param 10 100 s
+
+let hash_sdbm s =
+ let h = ref 0 in
+ for i = 0 to length s - 1 do
+ h := BatHash.sdbm !h (Char.code s.[i])
+ done;
+ !h
let init len f =
let s = create len in
View
6 src/batString.mli
@@ -704,6 +704,12 @@ val equal : t -> t -> bool
val ord : t -> t -> BatOrd.order
(** Ordering function for strings, see {!BatOrd} *)
+val hash : t BatHash.hash
+(** The standard polymorphic hash function *)
+
+val hash_sdbm : t BatHash.hash
+(** Reimplementation of Hash *)
+
val compare: t -> t -> int
(** The comparison function for strings, with the same specification as
{!Pervasives.compare}. Along with the type [t], this function [compare]
View
1  src/batteries.mllib
@@ -15,6 +15,7 @@ BatInnerPervasives
BatFormat
BatGc
BatGenlex
+ BatHash
BatHashcons
BatHashtbl
BatHeap
Something went wrong with that request. Please try again.