Skip to content

Commit 5359ee3

Browse files
committed
---
yaml --- r: 32255 b: refs/heads/dist-snap c: a961930 h: refs/heads/master i: 32253: 73c27c4 32251: 80af738 32247: 347096d 32239: 5b4dcfd 32223: a5e0cb3 32191: 692895e 32127: 9020d16 31999: db3dcb3 31743: 1ceb768 v: v3
1 parent cb99e1a commit 5359ee3

File tree

4 files changed

+409
-35
lines changed

4 files changed

+409
-35
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: d0c6ce338884ee21843f4b40bf6bf18d222ce5df
99
refs/heads/incoming: d9317a174e434d4c99fc1a37fd7dc0d2f5328d37
10-
refs/heads/dist-snap: ab53819a2cbbfbc2df7a3aea4e9a0b52dfb830dc
10+
refs/heads/dist-snap: a9619306a512ded537a84a45c7717f32f468d31b
1111
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1212
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/dist-snap/src/libcore/hash.rs

Lines changed: 102 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import io::Writer;
1717
import io::WriterUtil;
18+
import to_bytes::IterBytes;
1819

1920
export Streaming, State;
2021
export default_state;
@@ -33,6 +34,21 @@ export hash_u16;
3334
export hash_u8;
3435
export hash_uint;
3536

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+
3652
/// Streaming hash-functions should implement this.
3753
trait Streaming {
3854
fn input((&[const u8]));
@@ -43,38 +59,97 @@ trait Streaming {
4359
fn reset();
4460
}
4561

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+
}
5073
}
5174

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+
}
5486
}
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()
62130
}
63131
}
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+
}
64139
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)
66141
}
67142
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)
69144
}
70145
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)
72147
}
73148
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)
75150
}
76151
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)
78153
}
79154

80155
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) }
89164
// Implement State as SipState
90165

91166
type State = SipState;
167+
168+
#[inline(always)]
92169
fn State(k0: u64, k1: u64) -> State {
93170
SipState(k0, k1)
94171
}
95172

173+
#[inline(always)]
96174
fn default_state() -> State {
97175
State(0,0)
98176
}
@@ -109,6 +187,7 @@ struct SipState {
109187
mut ntail: uint; // how many bytes in tail are valid
110188
}
111189

190+
#[inline(always)]
112191
fn SipState(key0: u64, key1: u64) -> SipState {
113192
let state = SipState {
114193
k0 : key0,
@@ -129,6 +208,7 @@ fn SipState(key0: u64, key1: u64) -> SipState {
129208
impl &SipState : io::Writer {
130209

131210
// Methods for io::writer
211+
#[inline(always)]
132212
fn write(msg: &[const u8]) {
133213

134214
macro_rules! u8to64_le (
@@ -235,10 +315,12 @@ impl &SipState : io::Writer {
235315

236316
impl &SipState : Streaming {
237317

318+
#[inline(always)]
238319
fn input(buf: &[const u8]) {
239320
self.write(buf);
240321
}
241322

323+
#[inline(always)]
242324
fn result_u64() -> u64 {
243325
let mut v0 = self.v0;
244326
let mut v1 = self.v1;
@@ -269,7 +351,6 @@ impl &SipState : Streaming {
269351
return (v0 ^ v1 ^ v2 ^ v3);
270352
}
271353

272-
273354
fn result_bytes() -> ~[u8] {
274355
let h = self.result_u64();
275356
~[(h >> 0) as u8,
@@ -290,6 +371,7 @@ impl &SipState : Streaming {
290371
return s;
291372
}
292373

374+
#[inline(always)]
293375
fn reset() {
294376
self.length = 0;
295377
self.v0 = self.k0 ^ 0x736f6d6570736575;
@@ -385,7 +467,7 @@ fn test_siphash() {
385467
while t < 64 {
386468
debug!("siphash test %?", t);
387469
let vec = u8to64_le!(vecs[t], 0);
388-
let out = hash_bytes_keyed(buf, k0, k1);
470+
let out = buf.hash_keyed(k0, k1);
389471
debug!("got %?, expected %?", out, vec);
390472
assert vec == out;
391473

0 commit comments

Comments
 (0)