From 9271879298c24aaf89369183f21c3456b5a3cd48 Mon Sep 17 00:00:00 2001 From: Avril Date: Sun, 27 Dec 2020 23:39:50 +0000 Subject: [PATCH] job skel --- src/job.rs | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++- src/main.rs | 2 +- src/pool.rs | 4 +-- src/work.rs | 13 +++++++ 4 files changed, 114 insertions(+), 4 deletions(-) create mode 100644 src/work.rs diff --git a/src/job.rs b/src/job.rs index 7af98ca..03960c6 100644 --- a/src/job.rs +++ b/src/job.rs @@ -1,8 +1,40 @@ use super::*; use std::fs::{ - File, Metadata, + File, Metadata, OpenOptions, +}; +use std::convert::TryFrom; +use std::path::Path; +use std::io::{ + self, + Read, }; +#[derive(Debug)] +pub struct Prelude +{ + file: File, + stat: Metadata, + offset: usize, +} + +impl Prelude{ + pub fn len(&self) -> usize + { + usize::try_from(self.stat.len()).expect("Failed to fit file size into pointer size") + } + + /// Convert this job prelude into a job, assigning it this state + pub fn start(self, state: state::State) -> Job + { + Job { + fd: self.file, + stat: self.stat, + offset: self.offset, + state, + } + } +} + #[derive(Debug)] pub struct Job { @@ -16,3 +48,68 @@ pub struct Job } //TODO: job's work :^) + +impl Job +{ + pub fn state(&self) -> &state::State + { + &self.state + } + + pub fn info(&self) -> (&File, &Metadata) + { + (&self.fd, &self.stat) + } + + pub fn len(&self) -> usize + { + usize::try_from(self.stat.len()).expect("Failed to fit file size into pointer size") + } + + pub fn start(&self) -> usize + { + self.offset + } + pub fn end(&self) -> usize + { + self.len() + self.offset + } + + /// Get the output slice for this job. + pub fn output_slice<'a, 'b>(&'a mut self) -> &'b mut [u8] + where 'a: 'b + { + unsafe { + self.state.slice(self.start() .. self.end()) + } + } +} + +impl Read for Job +{ + #[inline] fn read(&mut self, buf: &mut [u8]) -> io::Result + { + self.fd.read(buf) + } +} + +/// Create a job description for this file. +/// +/// `sz` is the offset of the *end* of the last job. (or 0 for the first). +/// `sz` is then updated with this file's size for this method to be used again on the next file. +pub fn create_from_file(file: impl AsRef, sz: &mut usize) -> io::Result +{ + let file = OpenOptions::new() + .read(true) + .open(file.as_ref())?; + + let stat = file.metadata()?; + let offset = *sz; + + let prelude = Prelude { + file, stat, offset, + }; + *sz += prelude.len(); + + Ok(prelude) +} diff --git a/src/main.rs b/src/main.rs index 26f2344..16d8915 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,10 @@ - #![allow(dead_code)] mod state; mod pool; mod map; mod job; +mod work; fn main() { println!("Hello, world!"); diff --git a/src/pool.rs b/src/pool.rs index 3cc25f6..07406c7 100644 --- a/src/pool.rs +++ b/src/pool.rs @@ -12,9 +12,9 @@ use std::iter::FromIterator; fn work(recv: state::PendingReceiver) -> Result<(), Box> { - while let Some(job) = recv.recv()? + while let Some(mut job) = recv.recv()? { - //todo: work on job + work::work_on(&mut job)?; } Ok(()) diff --git a/src/work.rs b/src/work.rs new file mode 100644 index 0000000..aae3cb0 --- /dev/null +++ b/src/work.rs @@ -0,0 +1,13 @@ +use super::*; +use job::Job; +use std::io::Read; + +pub fn work_on(job: &mut Job) -> Result<(), Box> +{ + let output = job.output_slice(); + let mut buf = [0u8; 4096]; + while let Ok(read) = job.read(&mut buf) { + //TODO: copy from `job`'s file into `output`. + } + todo!() +}