diff --git a/.gitignore b/.gitignore index e2a3069..2014045 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target +/test *~ diff --git a/src/main.rs b/src/main.rs index ec910e1..c8dded1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ #![allow(dead_code)] +use std::convert::TryFrom; #[macro_export] macro_rules! unwrap { (return $($code:expr)?; $err:expr) => { @@ -38,10 +39,23 @@ fn work(arg::Operation{output, inputs}: arg::Operation) -> Result<(), Box, _) = { + let mut off = 0; + ((0..).zip(inputs.into_iter()).map(|(i, input)| job::create(i, input, &mut off)).collect(), off) + }; + debug_assert!(u64::try_from(size).is_ok(), "Output file too large, would exceed unsigned 64bit integer"); + // - `fallocate` the output file fd to the sum of all input file sizes // - `mmap` the output file as writable - // + let output = output.complete(size)?; + + // - create state + let state: state::State = {todo!()}; + // - spawn the task thread pool // - move the output mapped file to the thread-safe refcounted `state::State`. // - dispatch jobs to the pool with their fds, stats, and calculated output offsets; along with a reference to the output mapped file and a sender for the completion stream (`job::Prelude::start`) @@ -51,6 +65,12 @@ fn work(arg::Operation{output, inputs}: arg::Operation) -> Result<(), Box for MemoryMapMut impl MemoryMapMut { + /// Unmap this file and return the fd + pub fn unmap(self) -> fs::File + { + use std::{mem, ptr}; + let mut this = mem::ManuallyDrop::new(self); + unsafe { + let map = (&mut this.map as *mut MmapMut).read(); + let file = (&mut this.file as *mut fs::File).read(); + + let _ = map.flush(); + + drop(map); + file + } + } #[inline] pub fn as_slice_mut(&mut self) -> &mut [u8] { self.as_mut() diff --git a/src/open.rs b/src/open.rs index 9ad7f2b..5b20aee 100644 --- a/src/open.rs +++ b/src/open.rs @@ -27,6 +27,12 @@ pub struct Output(File); impl Output { + /// Consume into a normal file. + #[inline] pub fn into_inner(self) -> File + { + self.0 + } + /// Allocate this reserved output file `to` bytes, the map it and return. pub fn complete(self, to: usize) -> Result {