aboutsummaryrefslogtreecommitdiff
path: root/src/renderer.rs
diff options
context:
space:
mode:
authorDaniel Schadt <kingdread@gmx.de>2023-01-16 20:58:53 +0100
committerDaniel Schadt <kingdread@gmx.de>2023-01-16 21:01:41 +0100
commitf81eb4882a015ff19cb7209980ca3c7dd33bbae1 (patch)
treeacc2e2bbff10dbd65a316ae6954bf1882aeb1d47 /src/renderer.rs
parent18f99254e8a044cb1ebd8ea2653e13b67257b67b (diff)
downloadhittekaart-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.rs41
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(())
}