use std::{ error::Error, io::{stdout, Write}, time::{Duration, Instant}, }; use itertools::Itertools; use notmuch::{Notmuch, NotmuchError, SearchSummary, ThreadSet}; use rayon::iter::{ParallelBridge, ParallelIterator}; #[test] #[ignore] // it is too expensive, run with `cargo test -- --ignored` fn parse_one() -> Result<(), Box> { // take_hook() returns the default hook in case when a custom one is not set let orig_hook = std::panic::take_hook(); std::panic::set_hook(Box::new(move |panic_info| { // invoke the default handler and exit the process orig_hook(panic_info); std::process::exit(1); })); let nm = Notmuch::default(); let total = nm.count("*")? as f32; let start = Instant::now(); nm.message_ids("*")? .iter() .enumerate() .par_bridge() .for_each(|(i, msg)| { let ts = nm .show(&msg) .expect(&format!("failed to show msg: {}", msg)); //println!("{:?}", ts); if i > 0 && i % 1000 == 0 { let diff = start.elapsed(); let progress = i as f32; let percent = (progress * 100.) / total; let duration_per_message = diff.div_f32(progress); let total_runtime = duration_per_message.mul_f32(total as f32); let eta = duration_per_message.mul_f32(total - progress); print!( "\nElapsed {}s ETA {}s Total {}s Time/msg {}us Percent {}% ", diff.as_secs_f32(), eta.as_secs_f32(), total_runtime.as_secs_f32(), duration_per_message.as_micros(), percent ); stdout().flush().expect("failed to flush stdout"); } if i % 10 == 0 { print!("."); stdout().flush().expect("failed to flush stdout"); } }); println!("\n"); Ok(()) } #[test] #[ignore] // it is too expensive fn parse_bulk() -> Result<(), Box> { // take_hook() returns the default hook in case when a custom one is not set let orig_hook = std::panic::take_hook(); std::panic::set_hook(Box::new(move |panic_info| { // invoke the default handler and exit the process orig_hook(panic_info); std::process::exit(1); })); let nm = Notmuch::default(); let total = nm.count("*")? as f32; let start = Instant::now(); let chunk_size = 1000; nm.message_ids("*")? .chunks(chunk_size) .into_iter() .enumerate() //.par_bridge() .for_each(|(i, msgs)| { let query = msgs.join(" OR "); let ts = nm .show(&query) .expect(&format!("failed to show msgs: {}", query)); //println!("{:?}", ts); if i > 0 && i % 10 == 0 { let progress = (i * chunk_size) as f32; let diff = start.elapsed(); let percent = (progress * 100.) / total; let duration_per_message = diff.div_f32(progress); let total_runtime = duration_per_message.mul_f32(total as f32); let eta = duration_per_message.mul_f32(total - progress); print!( "\nElapsed {}s ETA {}s Total {}s Time/msg {}us Percent {}% ", diff.as_secs_f32(), eta.as_secs_f32(), total_runtime.as_secs_f32(), duration_per_message.as_micros(), percent ); stdout().flush().expect("failed to flush stdout"); } print!("."); stdout().flush().expect("failed to flush stdout"); }); println!("\n"); Ok(()) }