15
15
16
16
import io:: Writer ;
17
17
import io:: WriterUtil ;
18
+ import to_bytes:: IterBytes ;
18
19
19
20
export Streaming , State ;
20
21
export default_state;
@@ -33,6 +34,21 @@ export hash_u16;
33
34
export hash_u8;
34
35
export hash_uint;
35
36
37
+ /// Types that can meaningfully be hashed should implement this.
38
+ trait Hash {
39
+ pure fn hash_keyed ( k0 : u64 , k1 : u64 ) -> u64 ;
40
+ }
41
+
42
+ // When we have default methods, won't need this.
43
+ trait HashUtil {
44
+ pure fn hash ( ) -> u64 ;
45
+ }
46
+
47
+ impl < A : Hash > A : HashUtil {
48
+ #[ inline( always) ]
49
+ pure fn hash ( ) -> u64 { self . hash_keyed ( 0 , 0 ) }
50
+ }
51
+
36
52
/// Streaming hash-functions should implement this.
37
53
trait Streaming {
38
54
fn input ( ( & [ const u8 ] ) ) ;
@@ -43,38 +59,97 @@ trait Streaming {
43
59
fn reset ( ) ;
44
60
}
45
61
46
- fn keyed ( k0 : u64 , k1 : u64 , f : fn ( s : & State ) ) -> u64 {
47
- let s = & State ( k0, k1) ;
48
- f ( s) ;
49
- s. result_u64 ( )
62
+ impl < A : IterBytes > A : Hash {
63
+ #[ inline( always) ]
64
+ pure fn hash_keyed ( k0 : u64 , k1 : u64 ) -> u64 {
65
+ unchecked {
66
+ let s = & State ( k0, k1) ;
67
+ for self . iter_le_bytes |bytes| {
68
+ s. input ( bytes) ;
69
+ }
70
+ s. result_u64 ( )
71
+ }
72
+ }
50
73
}
51
74
52
- pure fn hash_bytes_keyed ( buf : & [ const u8 ] , k0 : u64 , k1 : u64 ) -> u64 {
53
- unchecked { keyed( k0, k1, |s| s. input ( buf) ) }
75
+ // implementations
76
+
77
+ pure fn hash_keyed_2 < A : IterBytes ,
78
+ B : IterBytes > ( a : & A , b : & B ,
79
+ k0 : u64 , k1 : u64 ) -> u64 {
80
+ unchecked {
81
+ let s = & State ( k0, k1) ;
82
+ for a. iter_le_bytes |bytes| { s. input ( bytes) ; }
83
+ for b. iter_le_bytes |bytes| { s. input ( bytes) ; }
84
+ s. result_u64 ( )
85
+ }
54
86
}
55
- pure fn hash_str_keyed ( s: & str, k0: u64, k1: u64) -> u64 {
56
- unsafe {
57
- do str:: as_buf ( s) |buf, len| {
58
- do vec:: unsafe:: form_slice ( buf, len) |slice| {
59
- hash_bytes_keyed ( slice, k0, k1)
60
- }
61
- }
87
+
88
+ pure fn hash_keyed_3<A : IterBytes ,
89
+ B : IterBytes ,
90
+ C : IterBytes >( a: & A , b: & B , c: & C ,
91
+ k0: u64, k1: u64) -> u64 {
92
+ unchecked {
93
+ let s = & State ( k0, k1) ;
94
+ for a. iter_le_bytes |bytes| { s. input ( bytes) ; }
95
+ for b. iter_le_bytes |bytes| { s. input ( bytes) ; }
96
+ for c. iter_le_bytes |bytes| { s. input ( bytes) ; }
97
+ s. result_u64 ( )
98
+ }
99
+ }
100
+
101
+ pure fn hash_keyed_4 < A : IterBytes ,
102
+ B : IterBytes ,
103
+ C : IterBytes ,
104
+ D : IterBytes > ( a : & A , b : & B , c : & C , d : & D ,
105
+ k0 : u64 , k1 : u64 ) -> u64 {
106
+ unchecked {
107
+ let s = & State ( k0, k1) ;
108
+ for a. iter_le_bytes |bytes| { s. input ( bytes) ; }
109
+ for b. iter_le_bytes |bytes| { s. input ( bytes) ; }
110
+ for c. iter_le_bytes |bytes| { s. input ( bytes) ; }
111
+ for d. iter_le_bytes |bytes| { s. input ( bytes) ; }
112
+ s. result_u64 ( )
113
+ }
114
+ }
115
+
116
+ pure fn hash_keyed_5<A : IterBytes ,
117
+ B : IterBytes ,
118
+ C : IterBytes ,
119
+ D : IterBytes ,
120
+ E : IterBytes >( a: & A , b: & B , c: & C , d: & D , e: & E ,
121
+ k0: u64, k1: u64) -> u64 {
122
+ unchecked {
123
+ let s = & State ( k0, k1) ;
124
+ for a. iter_le_bytes |bytes| { s. input ( bytes) ; }
125
+ for b. iter_le_bytes |bytes| { s. input ( bytes) ; }
126
+ for c. iter_le_bytes |bytes| { s. input ( bytes) ; }
127
+ for d. iter_le_bytes |bytes| { s. input ( bytes) ; }
128
+ for e. iter_le_bytes |bytes| { s. input ( bytes) ; }
129
+ s. result_u64 ( )
62
130
}
63
131
}
132
+
133
+ pure fn hash_bytes_keyed ( val : & [ const u8 ] , k0 : u64 , k1 : u64 ) -> u64 {
134
+ val. hash_keyed ( k0, k1)
135
+ }
136
+ pure fn hash_str_keyed ( val : & str , k0 : u64 , k1 : u64 ) -> u64 {
137
+ val. hash_keyed ( k0, k1)
138
+ }
64
139
pure fn hash_u64_keyed ( val : u64 , k0 : u64 , k1 : u64 ) -> u64 {
65
- unchecked { keyed ( k0, k1, |s| s . write_le_u64 ( val ) ) }
140
+ val . hash_keyed ( k0, k1)
66
141
}
67
142
pure fn hash_u32_keyed ( val : u32 , k0 : u64 , k1 : u64 ) -> u64 {
68
- unchecked { keyed ( k0, k1, |s| s . write_le_u32 ( val ) ) }
143
+ val . hash_keyed ( k0, k1)
69
144
}
70
145
pure fn hash_u16_keyed ( val : u16 , k0 : u64 , k1 : u64 ) -> u64 {
71
- unchecked { keyed ( k0, k1, |s| s . write_le_u16 ( val ) ) }
146
+ val . hash_keyed ( k0, k1)
72
147
}
73
148
pure fn hash_u8_keyed ( val : u8 , k0 : u64 , k1 : u64 ) -> u64 {
74
- unchecked { keyed ( k0, k1, |s| s . write_u8 ( val ) ) }
149
+ val . hash_keyed ( k0, k1)
75
150
}
76
151
pure fn hash_uint_keyed ( val : uint , k0 : u64 , k1 : u64 ) -> u64 {
77
- unchecked { keyed ( k0, k1, |s| s . write_le_uint ( val ) ) }
152
+ val . hash_keyed ( k0, k1)
78
153
}
79
154
80
155
pure fn hash_bytes ( val : & [ const u8 ] ) -> u64 { hash_bytes_keyed ( val, 0 , 0 ) }
@@ -89,10 +164,13 @@ pure fn hash_uint(val: uint) -> u64 { hash_uint_keyed(val, 0, 0) }
89
164
// Implement State as SipState
90
165
91
166
type State = SipState ;
167
+
168
+ #[ inline( always) ]
92
169
fn State ( k0 : u64 , k1 : u64 ) -> State {
93
170
SipState ( k0, k1)
94
171
}
95
172
173
+ #[ inline( always) ]
96
174
fn default_state ( ) -> State {
97
175
State ( 0 , 0 )
98
176
}
@@ -109,6 +187,7 @@ struct SipState {
109
187
mut ntail: uint; // how many bytes in tail are valid
110
188
}
111
189
190
+ #[ inline( always) ]
112
191
fn SipState ( key0 : u64 , key1 : u64 ) -> SipState {
113
192
let state = SipState {
114
193
k0 : key0,
@@ -129,6 +208,7 @@ fn SipState(key0: u64, key1: u64) -> SipState {
129
208
impl & SipState : io:: Writer {
130
209
131
210
// Methods for io::writer
211
+ #[ inline( always) ]
132
212
fn write ( msg : & [ const u8 ] ) {
133
213
134
214
macro_rules! u8to64_le (
@@ -235,10 +315,12 @@ impl &SipState : io::Writer {
235
315
236
316
impl & SipState : Streaming {
237
317
318
+ #[ inline( always) ]
238
319
fn input ( buf : & [ const u8 ] ) {
239
320
self . write ( buf) ;
240
321
}
241
322
323
+ #[ inline( always) ]
242
324
fn result_u64 ( ) -> u64 {
243
325
let mut v0 = self . v0 ;
244
326
let mut v1 = self . v1 ;
@@ -269,7 +351,6 @@ impl &SipState : Streaming {
269
351
return ( v0 ^ v1 ^ v2 ^ v3) ;
270
352
}
271
353
272
-
273
354
fn result_bytes ( ) -> ~[ u8 ] {
274
355
let h = self . result_u64 ( ) ;
275
356
~[ ( h >> 0 ) as u8 ,
@@ -290,6 +371,7 @@ impl &SipState : Streaming {
290
371
return s;
291
372
}
292
373
374
+ #[ inline( always) ]
293
375
fn reset ( ) {
294
376
self . length = 0 ;
295
377
self . v0 = self . k0 ^ 0x736f6d6570736575 ;
@@ -385,7 +467,7 @@ fn test_siphash() {
385
467
while t < 64 {
386
468
debug ! ( "siphash test %?" , t) ;
387
469
let vec = u8to64_le ! ( vecs[ t] , 0 ) ;
388
- let out = hash_bytes_keyed ( buf, k0, k1) ;
470
+ let out = buf. hash_keyed ( k0, k1) ;
389
471
debug ! ( "got %?, expected %?" , out, vec) ;
390
472
assert vec == out;
391
473
0 commit comments