88// option. This file may not be copied, modified, or distributed
99// except according to those terms.
1010
11+ // ignore-android see #10393 #13206
1112// ignore-pretty
1213
14+ use std:: ascii:: OwnedStrAsciiExt ;
1315use std:: str;
1416use std:: slice;
1517
@@ -39,16 +41,16 @@ impl Code {
3941 Code ( ( self . hash ( ) << 2 ) + ( pack_symbol ( c) as u64 ) )
4042 }
4143
42- fn rotate ( & self , c : u8 , frame : i32 ) -> Code {
43- Code ( self . push_char ( c) . hash ( ) & ( ( 1u64 << ( 2 * ( frame as u64 ) ) ) - 1 ) )
44+ fn rotate ( & self , c : u8 , frame : uint ) -> Code {
45+ Code ( self . push_char ( c) . hash ( ) & ( ( 1u64 << ( 2 * frame) ) - 1 ) )
4446 }
4547
4648 fn pack ( string : & str ) -> Code {
4749 string. bytes ( ) . fold ( Code ( 0u64 ) , |a, b| a. push_char ( b) )
4850 }
4951
5052 // FIXME: Inefficient.
51- fn unpack ( & self , frame : i32 ) -> ~str {
53+ fn unpack ( & self , frame : uint ) -> ~str {
5254 let mut key = self . hash ( ) ;
5355 let mut result = Vec :: new ( ) ;
5456 for _ in range ( 0 , frame) {
@@ -86,12 +88,12 @@ impl TableCallback for PrintCallback {
8688
8789struct Entry {
8890 code : Code ,
89- count : i32 ,
91+ count : uint ,
9092 next : Option < ~Entry > ,
9193}
9294
9395struct Table {
94- count : i32 ,
96+ count : uint ,
9597 items : Vec < Option < ~Entry > > }
9698
9799struct Items < ' a > {
@@ -190,10 +192,10 @@ impl<'a> Iterator<&'a Entry> for Items<'a> {
190192
191193fn pack_symbol ( c : u8 ) -> u8 {
192194 match c as char {
193- 'a' | ' A' => 0 ,
194- 'c' | ' C' => 1 ,
195- 'g' | ' G' => 2 ,
196- 't' | ' T' => 3 ,
195+ 'A' => 0 ,
196+ 'C' => 1 ,
197+ 'G' => 2 ,
198+ 'T' => 3 ,
197199 _ => fail ! ( "{}" , c as char ) ,
198200 }
199201}
@@ -202,67 +204,67 @@ fn unpack_symbol(c: u8) -> u8 {
202204 TABLE [ c]
203205}
204206
205- fn next_char < ' a > ( mut buf : & ' a [ u8 ] ) -> & ' a [ u8 ] {
206- loop {
207- buf = buf. slice ( 1 , buf. len ( ) ) ;
208- if buf. len ( ) == 0 {
209- break ;
210- }
211- if buf[ 0 ] != ( ' ' as u8 ) && buf[ 0 ] != ( '\t' as u8 ) &&
212- buf[ 0 ] != ( '\n' as u8 ) && buf[ 0 ] != 0 {
213- break ;
214- }
215- }
216- buf
217- }
218-
219207fn generate_frequencies ( frequencies : & mut Table ,
220208 mut input : & [ u8 ] ,
221- frame : i32 ) {
209+ frame : uint ) {
210+ if input. len ( ) < frame { return ; }
222211 let mut code = Code ( 0 ) ;
223212
224213 // Pull first frame.
225214 for _ in range ( 0 , frame) {
226215 code = code. push_char ( input[ 0 ] ) ;
227- input = next_char ( input) ;
216+ input = input. slice_from ( 1 ) ;
228217 }
229218 frequencies. lookup ( code, BumpCallback ) ;
230219
231220 while input. len ( ) != 0 && input[ 0 ] != ( '>' as u8 ) {
232221 code = code. rotate ( input[ 0 ] , frame) ;
233222 frequencies. lookup ( code, BumpCallback ) ;
234- input = next_char ( input) ;
223+ input = input. slice_from ( 1 ) ;
235224 }
236225}
237226
238- fn print_frequencies ( frequencies : & Table , frame : i32 ) {
227+ fn print_frequencies ( frequencies : & Table , frame : uint ) {
239228 let mut vector = Vec :: new ( ) ;
240229 for entry in frequencies. iter ( ) {
241- vector. push ( ( entry. code , entry. count ) ) ;
230+ vector. push ( ( entry. count , entry. code ) ) ;
242231 }
243232 vector. as_mut_slice ( ) . sort ( ) ;
244233
245234 let mut total_count = 0 ;
246- for & ( _ , count ) in vector. iter ( ) {
235+ for & ( count , _ ) in vector. iter ( ) {
247236 total_count += count;
248237 }
249238
250- for & ( key , count ) in vector. iter ( ) {
239+ for & ( count , key ) in vector. iter ( ) . rev ( ) {
251240 println ! ( "{} {:.3f}" ,
252241 key. unpack( frame) ,
253242 ( count as f32 * 100.0 ) / ( total_count as f32 ) ) ;
254243 }
244+ println ! ( "" ) ;
255245}
256246
257247fn print_occurrences ( frequencies : & mut Table , occurrence : & ' static str ) {
258248 frequencies. lookup ( Code :: pack ( occurrence) , PrintCallback ( occurrence) )
259249}
260250
251+ fn get_sequence < R : Buffer > ( r : & mut R , key : & str ) -> ~[ u8 ] {
252+ let mut res = ~"";
253+ for l in r. lines ( ) . map ( |l| l. ok ( ) . unwrap ( ) )
254+ . skip_while ( |l| key != l. slice_to ( key. len ( ) ) ) . skip ( 1 )
255+ {
256+ res. push_str ( l. trim ( ) ) ;
257+ }
258+ res. into_ascii_upper ( ) . into_bytes ( )
259+ }
260+
261261fn main ( ) {
262- let input = include_str ! ( "shootout-k-nucleotide.data" ) ;
263- let pos = input. find_str ( ">THREE" ) . unwrap ( ) ;
264- let pos2 = pos + input. slice_from ( pos) . find_str ( "\n " ) . unwrap ( ) ;
265- let input = input. slice_from ( pos2 + 1 ) . as_bytes ( ) ;
262+ let input = if std:: os:: getenv ( "RUST_BENCH" ) . is_some ( ) {
263+ let fd = std:: io:: File :: open ( & Path :: new ( "shootout-k-nucleotide.data" ) ) ;
264+ get_sequence ( & mut std:: io:: BufferedReader :: new ( fd) , ">THREE" )
265+ } else {
266+ get_sequence ( & mut std:: io:: stdin ( ) , ">THREE" )
267+ } ;
266268
267269 let mut frequencies = Table :: new ( ) ;
268270 generate_frequencies ( & mut frequencies, input, 1 ) ;
@@ -276,7 +278,7 @@ fn main() {
276278 frequencies = Table :: new ( ) ;
277279 generate_frequencies ( & mut frequencies,
278280 input,
279- occurrence. len ( ) as i32 ) ;
281+ occurrence. len ( ) ) ;
280282 print_occurrences ( & mut frequencies, * occurrence) ;
281283 }
282284}
0 commit comments