use super::{ParallelCompressor, ParallelEncodeError, TaskCount, WaitStatus, core};
use crate::compressor::Operation;
use std::{mem::MaybeUninit, time::Duration};
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub enum ParallelEncoderStatus {
NeedsInput,
NeedsOutput,
Pending,
Finished,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub struct ParallelProgress {
pub consumed: usize,
pub produced: usize,
pub status: ParallelEncoderStatus,
}
pub struct ParallelTaskQueue {
inner: core::QueueHandle,
}
impl ParallelTaskQueue {
pub fn recv(&self) -> Option<super::OwnedParallelTask> {
self.inner
.recv()
.map(|inner| super::ScopedParallelTask { inner })
}
pub fn try_recv(&self) -> Option<super::OwnedParallelTask> {
self.inner
.try_recv()
.map(|inner| super::ScopedParallelTask { inner })
}
}
impl Clone for ParallelTaskQueue {
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
}
}
}
impl IntoIterator for ParallelTaskQueue {
type Item = super::OwnedParallelTask;
type IntoIter = ParallelTasks;
fn into_iter(self) -> ParallelTasks {
ParallelTasks { queue: self }
}
}
impl std::fmt::Debug for ParallelTaskQueue {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ParallelTaskQueue").finish_non_exhaustive()
}
}
#[derive(Debug)]
pub struct ParallelTasks {
queue: ParallelTaskQueue,
}
impl Iterator for ParallelTasks {
type Item = super::OwnedParallelTask;
fn next(&mut self) -> Option<Self::Item> {
self.queue.recv()
}
}
pub struct ParallelEncoderSession<'c> {
inner: core::BorrowedStream<'c>,
}
impl ParallelEncoderSession<'_> {
pub fn process(
&mut self,
input: &[u8],
output: &mut [u8],
operation: Operation,
) -> Result<ParallelProgress, ParallelEncodeError> {
let core::BorrowedStream { parent, stream } = &mut self.inner;
stream.process(parent, input, output, operation)
}
pub fn process_uninit(
&mut self,
input: &[u8],
output: &mut [MaybeUninit<u8>],
operation: Operation,
) -> Result<ParallelProgress, ParallelEncodeError> {
let core::BorrowedStream { parent, stream } = &mut self.inner;
stream.process(parent, input, output, operation)
}
pub fn flush(&mut self, output: &mut [u8]) -> Result<ParallelProgress, ParallelEncodeError> {
self.process(&[], output, Operation::Flush)
}
pub fn finish(&mut self, output: &mut [u8]) -> Result<ParallelProgress, ParallelEncodeError> {
self.process(&[], output, Operation::End)
}
pub fn wait(&mut self) -> Result<(), ParallelEncodeError> {
let core::BorrowedStream { parent, stream } = &mut self.inner;
stream.wait(parent, None).map(|_| ())
}
pub fn wait_timeout(&mut self, timeout: Duration) -> Result<WaitStatus, ParallelEncodeError> {
let core::BorrowedStream { parent, stream } = &mut self.inner;
stream.wait(parent, Some(timeout))
}
#[must_use]
pub const fn is_finished(&self) -> bool {
self.inner.stream.is_finished()
}
}
impl std::fmt::Debug for ParallelEncoderSession<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ParallelEncoderSession")
.field("finished", &self.is_finished())
.finish_non_exhaustive()
}
}
pub struct ParallelEncoderSessionOwned {
inner: core::OwnedStream,
}
impl ParallelEncoderSessionOwned {
pub fn process(
&mut self,
input: &[u8],
output: &mut [u8],
operation: Operation,
) -> Result<ParallelProgress, ParallelEncodeError> {
let core::OwnedStream { parent, stream } = &mut self.inner;
stream.process(parent, input, output, operation)
}
pub fn process_uninit(
&mut self,
input: &[u8],
output: &mut [MaybeUninit<u8>],
operation: Operation,
) -> Result<ParallelProgress, ParallelEncodeError> {
let core::OwnedStream { parent, stream } = &mut self.inner;
stream.process(parent, input, output, operation)
}
pub fn flush(&mut self, output: &mut [u8]) -> Result<ParallelProgress, ParallelEncodeError> {
self.process(&[], output, Operation::Flush)
}
pub fn finish(&mut self, output: &mut [u8]) -> Result<ParallelProgress, ParallelEncodeError> {
self.process(&[], output, Operation::End)
}
pub fn wait(&mut self) -> Result<(), ParallelEncodeError> {
let core::OwnedStream { parent, stream } = &mut self.inner;
stream.wait(parent, None).map(|_| ())
}
pub fn wait_timeout(&mut self, timeout: Duration) -> Result<WaitStatus, ParallelEncodeError> {
let core::OwnedStream { parent, stream } = &mut self.inner;
stream.wait(parent, Some(timeout))
}
#[must_use]
pub const fn is_finished(&self) -> bool {
self.inner.stream.is_finished()
}
#[must_use]
pub fn into_compressor(self) -> ParallelCompressor {
ParallelCompressor {
inner: self.inner.into_parent(),
}
}
}
impl std::fmt::Debug for ParallelEncoderSessionOwned {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ParallelEncoderSessionOwned")
.field("finished", &self.is_finished())
.finish_non_exhaustive()
}
}
impl ParallelCompressor {
pub fn start(
&mut self,
window: TaskCount,
) -> Result<(ParallelEncoderSession<'_>, ParallelTaskQueue), ParallelEncodeError> {
let (stream, queue) = core::Stream::new(&self.inner, window)?;
Ok((
ParallelEncoderSession {
inner: core::BorrowedStream {
parent: &mut self.inner,
stream,
},
},
ParallelTaskQueue { inner: queue },
))
}
pub fn into_session(
self,
window: TaskCount,
) -> Result<(ParallelEncoderSessionOwned, ParallelTaskQueue), ParallelEncodeError> {
let (stream, queue) = core::Stream::new(&self.inner, window)?;
Ok((
ParallelEncoderSessionOwned {
inner: core::OwnedStream {
parent: self.inner,
stream,
},
},
ParallelTaskQueue { inner: queue },
))
}
}