-
Notifications
You must be signed in to change notification settings - Fork 0
/
rayon_basic.rs
56 lines (54 loc) · 1.82 KB
/
rayon_basic.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
use clap::Parser;
use count_cat::ThreeFileArgs;
use noodles_bgzf as bgzf;
use noodles_bgzf::io::Seek;
use noodles_fasta as fasta;
use noodles_fasta::fai::Record as FaiRecord;
use rayon::prelude::*;
use std::fs::File;
use std::io::{self, BufReader};
use std::path::PathBuf;
fn cat_count(
fai_rec: &FaiRecord,
bgzf_index: &bgzf::gzi::Index,
input_path: &PathBuf,
) -> Result<usize, io::Error> {
let mut buf: Vec<u8> = Vec::new();
let mut bgzf_reader = bgzf::Reader::new(File::open(input_path)?);
bgzf_reader.seek_with_index(bgzf_index, io::SeekFrom::Start(fai_rec.offset()))?;
let mut fasta_reader = fasta::io::Reader::new(BufReader::new(bgzf_reader));
fasta_reader.read_sequence(&mut buf)?;
buf.iter_mut().for_each(|b| *b = b.to_ascii_uppercase());
Ok(buf
.as_slice()
.windows(3)
.filter(|&win| win == b"CAT")
.count())
}
fn main() -> io::Result<()> {
let opts = ThreeFileArgs::parse();
let fai_file = File::open(&opts.fai_path)?;
let bgzf_index = bgzf::gzi::read(&opts.gzi_path)?;
let mut index = fasta::fai::Reader::new(BufReader::new(fai_file));
let index_records = index.read_index()?;
let input_path = opts.input_path;
let cat_counted = index_records
.par_iter()
.map(|fai_rec| cat_count(&fai_rec, &bgzf_index, &input_path))
.try_fold(
|| 0 as usize, // Initial accumulator for each thread
|acc, res| match res {
Ok(value) => Ok(acc + value),
Err(e) => Err(e),
},
)
.try_reduce(
|| 0, // Initial accumulator for combining results
|acc1, acc2| Ok(acc1 + acc2),
);
match cat_counted {
Ok(total) => println!("Number of CATs: {}", total),
Err(_) => println!("Error counting CATs"),
}
Ok(())
}