- Commit
- 67ba2c9015ac86ec8d2503287d1300b48d2c570b
- Parent
- fbb8a822f6a46161bc600f248964ffd27de273c5
- Author
- Pablo <pablo-pie@riseup.net>
- Date
[optimize] Index entries that should be skipped at startup
Custum build of stapix for tikz.pablopie.xyz
[optimize] Index entries that should be skipped at startup
2 files changed, 102 insertions, 88 deletions
| Status | Name | Changes | Insertions | Deletions |
| Modified | src/log.rs | 2 files changed | 0 | 23 |
| Modified | src/main.rs | 2 files changed | 102 | 65 |
diff --git a/src/log.rs b/src/log.rs @@ -27,7 +27,6 @@ pub(crate) enum Level { pub struct JobListLogger { total: usize, count: usize, - skipped: usize, current_job_name: String, } @@ -99,7 +98,6 @@ impl JobListLogger { Self { total: total_jobs, count: 0, - skipped: 0, current_job_name: String::with_capacity(STRING_CAPACITY), } } @@ -132,13 +130,6 @@ impl JobListLogger { self.job_finished_impl(); } - pub fn job_skipped(&mut self) { - self.count += 1; - self.skipped += 1; - - if self.count == self.total { self.log_skipped(); } - } - fn inc_counter(&mut self, job_name: &str) { self.count += 1; self.current_job_name.clear(); @@ -152,20 +143,6 @@ impl JobListLogger { name = self.current_job_name, empty = "", ); - - if self.count == self.total && self.skipped > 0 { self.log_skipped(); } - } - - fn log_skipped(&self) { - use crate::FULL_BUILD_OPT; - - print!(" {BOLD_YELLOW}Skipped{RESET} "); - if self.skipped == 1 { - print!("one entry. "); - } else { - print!("{} entries. ", self.skipped); - } - println!("Use {FULL_BUILD_OPT} to overwrite"); } }
diff --git a/src/main.rs b/src/main.rs @@ -54,7 +54,8 @@ fn main() -> ExitCode { }; let mut full_build = false; - let mut num_threads = num_cpus::get() - 1; + let total_threads = num_cpus::get(); + let mut num_threads = total_threads - 1; while let Some(arg) = args.next() { let mut is_valid_arg = false; @@ -108,7 +109,7 @@ fn main() -> ExitCode { log::usage_config(); return ExitCode::FAILURE; } - Ok(Ok(pics)) => if render_gallery(pics, full_build, num_threads).is_err() { + Ok(Ok(pics)) => if render_gallery(pics, full_build, num_threads, total_threads).is_err() { return ExitCode::FAILURE; }, } @@ -121,97 +122,133 @@ fn render_gallery( pics: Vec<GalleryEntry>, full_build: bool, num_threads: usize, + total_threads: usize, ) -> Result<(), ()> { + struct Job { + pic_id: usize, + image_path: PathBuf, + thumb_path: PathBuf, + page_path: PathBuf, + } + let start = Instant::now(); - // ======================================================================== - for pic in &pics { - let mut target_path = PathBuf::from(TARGET_PATH); - target_path.push(IMAGES_PATH); - target_path.push(&pic.file_name); + let mut skipped = 0; + let mut jobs = Vec::with_capacity(pics.len()); + for (pic_id, pic) in pics.iter().enumerate() { + let mut image_path = PathBuf::from(TARGET_PATH); + image_path.push(IMAGES_PATH); + image_path.push(&pic.file_name); - if !full_build && !needs_update(pic, &target_path) { - copy(&pic.path, &target_path)?; - } - } + let thumb_path: PathBuf = ThumbPath(pic).into(); - infoln!("Copied image files to the target directory"); + let mut page_path = PathBuf::from(TARGET_PATH); + page_path.push(PAGES_PATH); + page_path.push(pic.file_name.clone() + ".html"); - // ======================================================================== - for pic in &pics { if pic.alt.is_empty() { warnln!( "Empty text alternative was specified for the file {name:?}", name = pic.file_name ); } - } - // ======================================================================== - let num_threads = cmp::min(num_threads, pics.len()); - let rendering_pool = ThreadPool::with_name( - String::from("thumbnails renderer"), - num_threads - ); - let (sender, reciever) = mpsc::channel(); - - infoln!("Rendering thumbnails... (using {num_threads} threads)"); - let mut thumbs_logger = JobListLogger::new(pics.len()); - - let mut render_pool_count = 0; - for (id, pic) in pics.iter().enumerate() { - let thumb_path: PathBuf = ThumbPath(pic).into(); - - if !full_build && !needs_update(pic, &thumb_path) { - thumbs_logger.job_skipped(); - continue; + if full_build || needs_update(pic, &image_path) + || needs_update(pic, &thumb_path) + || needs_update(pic, &page_path) { + jobs.push(Job { pic_id, image_path, thumb_path, page_path, }); + } else { + skipped += 1; } + } - render_pool_count += 1; + // ======================================================================== + if !jobs.is_empty() { + infoln!("Rendering HTML files..."); + } + let mut pages_logger = JobListLogger::new(1 + jobs.len()); - let sender = sender.clone(); - let pic = pic.clone(); + pages_logger.job_started("index.html"); + render_index(&pics).map_err(|_| ())?; + pages_logger.job_finished(); - rendering_pool.execute(move || { - // NOTE: we need to send the picture id back so that the main thread - // knows how to log the fact we finished rendering it - let _ = sender.send(render_thumbnail(&pic, &thumb_path).map(|()| id)); - }); + if jobs.is_empty() { + warnln!( + "Skipping all {total} entries: no update is required. Use {FULL_BUILD_OPT} to overwrite", + total = pics.len(), + ); + log::finished(start.elapsed()); + return Ok(()); } - for _ in 0..render_pool_count { - let msg = reciever.recv(); - // propagate the panic to the main thread: reciever.recv should - // only fail if some of the rendering threads panicked - if msg.is_err() { panic!("rendering thread panicked!"); } + for Job { pic_id, page_path, .. } in &jobs { + let pic = &pics[*pic_id]; + pages_logger.job_started(&pic.file_name); + render_pic_page(pic, page_path).map_err(|_| ())?; + pages_logger.job_finished(); + } - let job_id = msg.unwrap()?; - let pic = &pics[job_id]; - thumbs_logger.job_started_and_finished(&pic.file_name); + // ======================================================================== + for Job { pic_id, image_path, .. } in &jobs { + let pic = &pics[*pic_id]; + copy(&pic.path, image_path)?; } - drop(thumbs_logger); + + infoln!("Copied image files to the target directory"); // ======================================================================== - infoln!("Rendering HTML files..."); - let mut pages_logger = JobListLogger::new(1 + pics.len()); + let num_threads = cmp::min(num_threads, jobs.len()); + let mut thumbs_logger = JobListLogger::new(jobs.len()); + + // NOTE: only spawn the threads if necessary + if num_threads > 1 { + infoln!("Rendering thumbnails... (using {num_threads}/{total_threads} threads)"); + let rendering_pool = ThreadPool::with_name( + String::from("thumbnails renderer"), + num_threads, + ); + let (sender, reciever) = mpsc::channel(); + + for Job { pic_id, thumb_path, .. } in &jobs { + let pic_id = *pic_id; + let thumb_path = thumb_path.clone(); + let pic = pics[pic_id].clone(); + let sender = sender.clone(); + + rendering_pool.execute(move || { + // NOTE: we need to send the picture id back so that the main thread + // knows how to log the fact we finished rendering it + let _ = sender.send( + render_thumbnail(&pic, &thumb_path).map(|()| pic_id) + ); + }); + } - pages_logger.job_started("index page"); - render_index(&pics).map_err(|_| ())?; - pages_logger.job_finished(); + for _ in 0..jobs.len() { + let msg = reciever.recv(); + // propagate the panic to the main thread: reciever.recv should + // only fail if some of the rendering threads panicked + if msg.is_err() { panic!("rendering thread panicked!"); } - for pic in pics { - let mut path = PathBuf::from(TARGET_PATH); - path.push(PAGES_PATH); - path.push(pic.file_name.clone() + ".html"); + let pic_id = msg.unwrap()?; + let pic = &pics[pic_id]; + thumbs_logger.job_started_and_finished(&pic.file_name); + } + } else { + infoln!("Rendering thumbnails... (using 1/{total_threads} thread)"); + for Job { pic_id, thumb_path, .. } in &jobs { + let pic = &pics[*pic_id]; - if !full_build && !needs_update(&pic, &path) { - pages_logger.job_skipped(); - continue; + thumbs_logger.job_started(&pic.file_name); + render_thumbnail(pic, thumb_path)?; + thumbs_logger.job_finished(); } + } - pages_logger.job_started(&pic.file_name); - render_pic_page(&pic, &path).map_err(|_| ())?; - pages_logger.job_finished(); + // ========================================================================== + if skipped > 1 { + warnln!("Skipped {skipped}/{total} entries. Use {FULL_BUILD_OPT} to overwrite", + total = pics.len()); } log::finished(start.elapsed());