-
Notifications
You must be signed in to change notification settings - Fork 14
/
hashable-2.sml
81 lines (61 loc) · 1.71 KB
/
hashable-2.sml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
structure IntInfHashable
:> HASHABLE where type t = IntInf.int
=
struct
type t = IntInf.int
val eq : IntInf.int * IntInf.int -> bool = op =
val wordSize = Word.fromInt Word.wordSize
val mask = IntInf.<< (1, wordSize) - 1
fun hashloop n acc =
if n = 0 then
acc
else
hashloop
(IntInf.~>> (n, wordSize))
(JenkinsHash.hashInc acc (ConvertWord.intInfToWord (IntInf.andb (n, mask))))
fun hash n =
if n >= 0 then
hashloop n 0w1
else
hashloop (IntInf.~ n) 0w2
end
structure Word8Hashable
:> HASHABLE where type t = Word8.word
=
struct
type t = Word8.word
val eq : Word8.word * Word8.word -> bool = op =
val hash = ConvertWord.word8ToWord
end
structure BytestringHashable
:> HASHABLE where type t = Bytestring.string
=
struct
type t = Bytestring.string
val eq = Bytestring.eq
fun hash str =
let
val len = Bytestring.size str
fun loop i h =
if i >= len then
h
else
loop (i+1) (JenkinsHash.hashInc h (ConvertWord.word8ToWord (Bytestring.sub (str, i))))
in
loop 0 0w0
end
end
functor SetHashable (structure Set : SET
structure Elem : HASHABLE
sharing type Set.elem = Elem.t)
:> HASHABLE where type t = Set.set
=
struct
type t = Set.set
val eq = Set.eq
fun hash set =
Set.foldl
(fn (elem, acc) => JenkinsHash.hashInc acc (Elem.hash elem))
0w0
set
end