1- use std:: io:: Read ;
1+ use std:: io:: { BufRead , Read } ;
22
33pub const RAPID_SEED : u64 = 0xbdd8_9aa9_8270_4029 ;
44pub const RAPID_SECRET : [ u64 ; 3 ] = [
@@ -47,6 +47,7 @@ pub fn rapidhash(key: &[u8], seed: u64, secret: &[u64; 3]) -> u64 {
4747 let mut a;
4848 let mut b;
4949
50+
5051 if len <= 16 {
5152 if len >= 4 {
5253 let delta = ( ( len & 24 ) >> ( len >> 3 ) ) as usize ;
@@ -84,8 +85,10 @@ pub fn rapidhash(key: &[u8], seed: u64, secret: &[u64; 3]) -> u64 {
8485 ) ;
8586 p = & p[ 48 ..] ;
8687 i -= 48 ;
88+
8789 }
8890 seed ^= see1 ^ see2;
91+
8992 }
9093 if i > 16 {
9194 seed = rapid_mix (
@@ -99,26 +102,30 @@ pub fn rapidhash(key: &[u8], seed: u64, secret: &[u64; 3]) -> u64 {
99102 ) ;
100103 }
101104 }
105+
102106 a = rapid_read64 ( & key[ len - 16 ..] ) ;
103107 b = rapid_read64 ( & key[ len - 8 ..] ) ;
108+
104109 }
105110
106111 a ^= secret[ 1 ] ;
107112 b ^= seed;
113+
108114 rapid_mum ( & mut a, & mut b) ;
109115 rapid_mix ( a ^ secret[ 0 ] ^ len as u64 , b ^ secret[ 1 ] )
110116}
111117
112118// reference: https://github.com/hoxxep/rapidhash/blob/master/src/rapid_file.rs
113119pub fn rapidhash_file ( filename : String , seed : u64 , secret : & [ u64 ; 3 ] ) -> u64 {
114- let f = std:: fs:: File :: open ( filename) . expect ( "Can't open file. " ) ;
120+ let f = std:: fs:: File :: open ( filename) . expect ( "failed " ) ;
115121 let len = f. metadata ( ) . unwrap ( ) . len ( ) as usize ;
116122 let mut reader = std:: io:: BufReader :: new ( & f) ;
117123 let mut seed = seed ^ rapid_mix ( seed ^ secret[ 0 ] , secret[ 1 ] ) ^ len as u64 ;
118124
119125 let mut a;
120126 let mut b;
121127
128+
122129 if len <= 16 {
123130 let mut key = [ 0u8 ; 48 ] ;
124131 reader. read_exact ( & mut key[ ..len] ) . unwrap ( ) ;
@@ -138,14 +145,17 @@ pub fn rapidhash_file(filename: String, seed: u64, secret: &[u64; 3]) -> u64 {
138145 b = 0 ;
139146 }
140147 } else {
141- let mut tails = [ 0u8 ; 48 * 2 ] ;
142- let ( p, last) = tails. split_at_mut ( 48 ) ;
148+ let buffer_size = 255984 ; // ~ 256KB
149+ assert ! ( buffer_size % 48 == 0 ) ;
150+ let mut buffer = vec ! [ 0u8 ; buffer_size] ;
143151 let mut i = len;
152+ let mut offset = 48 ;
153+ reader. read_exact ( & mut buffer[ 48 ..std:: cmp:: min ( 48 +i, buffer_size) ] ) . unwrap ( ) ;
144154 if i > 48 {
145155 let mut see1 = seed;
146156 let mut see2 = seed;
147157 while i >= 48 {
148- reader . read_exact ( p ) . unwrap ( ) ;
158+ let p : & [ u8 ] = & buffer [ offset.. ] ;
149159 seed = rapid_mix (
150160 rapid_read64 ( & p[ 0 ..] ) ^ secret[ 0 ] ,
151161 rapid_read64 ( & p[ 8 ..] ) ^ seed,
@@ -159,28 +169,47 @@ pub fn rapidhash_file(filename: String, seed: u64, secret: &[u64; 3]) -> u64 {
159169 rapid_read64 ( & p[ 40 ..] ) ^ see2,
160170 ) ;
161171 i -= 48 ;
172+ offset += 48 ;
173+
174+ if offset == buffer_size {
175+ let ( head, t) = buffer. split_at_mut ( 48 ) ;
176+ head. copy_from_slice ( & t[ t. len ( ) -48 ..] ) ;
177+ reader. read_exact ( & mut buffer[ 48 ..std:: cmp:: min ( 48 +i, buffer_size) ] ) . unwrap ( ) ;
178+ offset = 48 ;
179+ }
180+
181+
162182 }
163183 seed ^= see1 ^ see2;
184+
164185 }
165- reader. read_exact ( & mut last[ ..i] ) . unwrap ( ) ;
186+ //reader.read_exact(&mut last[..i]).unwrap();
187+ let p = & buffer[ offset..offset+48 ] ;
166188 if i > 16 {
167189 seed = rapid_mix (
168- rapid_read64 ( & last [ 0 ..] ) ^ secret[ 2 ] ,
169- rapid_read64 ( & last [ 8 ..] ) ^ seed ^ secret[ 1 ] ,
190+ rapid_read64 ( & p [ 0 ..] ) ^ secret[ 2 ] ,
191+ rapid_read64 ( & p [ 8 ..] ) ^ seed ^ secret[ 1 ] ,
170192 ) ;
171193 if i > 32 {
172194 seed = rapid_mix (
173- rapid_read64 ( & last [ 16 ..] ) ^ secret[ 2 ] ,
174- rapid_read64 ( & last [ 24 ..] ) ^ seed,
195+ rapid_read64 ( & p [ 16 ..] ) ^ secret[ 2 ] ,
196+ rapid_read64 ( & p [ 24 ..] ) ^ seed,
175197 ) ;
176198 }
177199 }
200+
178201 let end = 48 + i;
202+
203+ assert ! ( i % 48 == len % 48 ) ;
204+
205+ let tails = & buffer[ offset-48 ..offset+48 ] ;
179206 a = rapid_read64 ( & tails[ end - 16 ..] ) ;
180207 b = rapid_read64 ( & tails[ end - 8 ..] ) ;
208+
181209 }
182210 a ^= secret[ 1 ] ;
183211 b ^= seed;
212+
184213 rapid_mum ( & mut a, & mut b) ;
185214 rapid_mix ( a ^ secret[ 0 ] ^ len as u64 , b ^ secret[ 1 ] )
186215}
0 commit comments