diff options
author | Daniel Schadt <kingdread@gmx.de> | 2023-01-16 20:58:53 +0100 |
---|---|---|
committer | Daniel Schadt <kingdread@gmx.de> | 2023-01-16 21:01:41 +0100 |
commit | f81eb4882a015ff19cb7209980ca3c7dd33bbae1 (patch) | |
tree | acc2e2bbff10dbd65a316ae6954bf1882aeb1d47 /src/renderer.rs | |
parent | 18f99254e8a044cb1ebd8ea2653e13b67257b67b (diff) | |
download | hittekaart-f81eb4882a015ff19cb7209980ca3c7dd33bbae1.tar.gz hittekaart-f81eb4882a015ff19cb7209980ca3c7dd33bbae1.tar.bz2 hittekaart-f81eb4882a015ff19cb7209980ca3c7dd33bbae1.zip |
use a single thread to write out files
It seems like this does not make the encoding slower, and the main point
is that we might want to support SQLite storage for the tiles, in which
case it might be good to have only one writer. Even with the FS-based
approach, maybe it's good to have a single thread responsible for
writing everything, and not hammer the OS with 16 write requests at
once.
Diffstat (limited to 'src/renderer.rs')
-rw-r--r-- | src/renderer.rs | 41 |
1 files changed, 30 insertions, 11 deletions
diff --git a/src/renderer.rs b/src/renderer.rs index 2f29828..de65da6 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -1,6 +1,9 @@ -use std::{fs, path::Path}; +use std::{fs, mem, path::Path, sync::mpsc, thread}; -use color_eyre::eyre::{bail, Result}; +use color_eyre::{ + eyre::{bail, Result}, + Report, +}; use image::{ImageBuffer, Luma, Pixel, RgbaImage}; use nalgebra::{vector, Vector2}; use rayon::iter::ParallelIterator; @@ -143,22 +146,38 @@ pub fn lazy_colorization<P: AsRef<Path>, F: Fn(usize) + Send + Sync>( return Ok(()); } - layer - .into_parallel_tiles() - .try_for_each(|(tile_x, tile_y, tile)| { - let colorized = colorize_tile(&tile, max.into()); + type Job = (u64, u64, Vec<u8>); + let (tx, rx) = mpsc::sync_channel::<Job>(30); + + thread::scope(|s| { + let saver = s.spawn(move || loop { + let Ok((tile_x, tile_y, data)) = rx.recv() else { return Ok(()) }; let folder = base_dir.join(tile_x.to_string()); let metadata = folder.metadata(); match metadata { - Err(_) => fs::create_dir_all(&folder)?, + Err(_) => fs::create_dir(&folder)?, Ok(m) if !m.is_dir() => bail!("Output path is not a directory"), _ => {} } let file = folder.join(format!("{tile_y}.png")); - layer::compress_png(&colorized, file)?; - progress_callback(1); - Ok(()) - })?; + fs::write(file, data)?; + }); + + layer + .into_parallel_tiles() + .try_for_each(|(tile_x, tile_y, tile)| { + let colorized = colorize_tile(&tile, max.into()); + let data = layer::compress_png_as_bytes(&colorized)?; + tx.send((tile_x, tile_y, data))?; + progress_callback(1); + Ok::<(), Report>(()) + })?; + + mem::drop(tx); + saver.join().unwrap()?; + Ok::<_, Report>(()) + })?; + Ok(()) } |