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 ] = [
@@ -46,7 +46,6 @@ pub fn rapidhash(key: &[u8], seed: u64, secret: &[u64; 3]) -> u64 {
4646 let mut seed = seed ^ rapid_mix ( seed ^ secret[ 0 ] , secret[ 1 ] ) ^ len as u64 ;
4747 let mut a;
4848 let mut b;
49-
5049 if len <= 16 {
5150 if len >= 4 {
5251 let delta = ( ( len & 24 ) >> ( len >> 3 ) ) as usize ;
@@ -118,7 +117,6 @@ pub fn rapidhash_file(filename: String, seed: u64, secret: &[u64; 3]) -> u64 {
118117
119118 let mut a;
120119 let mut b;
121-
122120 if len <= 16 {
123121 let mut key = [ 0u8 ; 48 ] ;
124122 reader. read_exact ( & mut key[ ..len] ) . unwrap ( ) ;
@@ -138,14 +136,17 @@ pub fn rapidhash_file(filename: String, seed: u64, secret: &[u64; 3]) -> u64 {
138136 b = 0 ;
139137 }
140138 } else {
141- let mut tails = [ 0u8 ; 48 * 2 ] ;
142- let ( p, last) = tails. split_at_mut ( 48 ) ;
139+ let buffer_size = 255984 ; // ~ 256KB
140+ assert ! ( buffer_size % 48 == 0 ) ;
141+ let mut buffer = vec ! [ 0u8 ; buffer_size] ;
143142 let mut i = len;
143+ let mut offset = 48 ;
144+ reader. read_exact ( & mut buffer[ 48 ..std:: cmp:: min ( 48 +i, buffer_size) ] ) . unwrap ( ) ;
144145 if i > 48 {
145146 let mut see1 = seed;
146147 let mut see2 = seed;
147148 while i >= 48 {
148- reader . read_exact ( p ) . unwrap ( ) ;
149+ let p : & [ u8 ] = & buffer [ offset.. ] ;
149150 seed = rapid_mix (
150151 rapid_read64 ( & p[ 0 ..] ) ^ secret[ 0 ] ,
151152 rapid_read64 ( & p[ 8 ..] ) ^ seed,
@@ -159,23 +160,32 @@ pub fn rapidhash_file(filename: String, seed: u64, secret: &[u64; 3]) -> u64 {
159160 rapid_read64 ( & p[ 40 ..] ) ^ see2,
160161 ) ;
161162 i -= 48 ;
163+ offset += 48 ;
164+
165+ if offset == buffer_size {
166+ let ( head, t) = buffer. split_at_mut ( 48 ) ;
167+ head. copy_from_slice ( & t[ t. len ( ) -48 ..] ) ;
168+ reader. read_exact ( & mut buffer[ 48 ..std:: cmp:: min ( 48 +i, buffer_size) ] ) . unwrap ( ) ;
169+ offset = 48 ;
170+ }
162171 }
163172 seed ^= see1 ^ see2;
164173 }
165- reader . read_exact ( & mut last [ ..i ] ) . unwrap ( ) ;
174+ let p = & buffer [ offset..offset+ 48 ] ;
166175 if i > 16 {
167176 seed = rapid_mix (
168- rapid_read64 ( & last [ 0 ..] ) ^ secret[ 2 ] ,
169- rapid_read64 ( & last [ 8 ..] ) ^ seed ^ secret[ 1 ] ,
177+ rapid_read64 ( & p [ 0 ..] ) ^ secret[ 2 ] ,
178+ rapid_read64 ( & p [ 8 ..] ) ^ seed ^ secret[ 1 ] ,
170179 ) ;
171180 if i > 32 {
172181 seed = rapid_mix (
173- rapid_read64 ( & last [ 16 ..] ) ^ secret[ 2 ] ,
174- rapid_read64 ( & last [ 24 ..] ) ^ seed,
182+ rapid_read64 ( & p [ 16 ..] ) ^ secret[ 2 ] ,
183+ rapid_read64 ( & p [ 24 ..] ) ^ seed,
175184 ) ;
176185 }
177186 }
178187 let end = 48 + i;
188+ let tails = & buffer[ offset-48 ..offset+48 ] ;
179189 a = rapid_read64 ( & tails[ end - 16 ..] ) ;
180190 b = rapid_read64 ( & tails[ end - 8 ..] ) ;
181191 }
0 commit comments