raw savings

arg-parsing-better
Avril 3 years ago
parent 18c7c12025
commit 9d339d9628
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -13,7 +13,7 @@ codegen-units = 1
panic = "unwind"
[features]
default = ["splash", "inspect", "defer-drop", "jemalloc", "prealloc"]
default = ["splash", "inspect", "defer-drop", "jemalloc"]
# Use jemalloc as global allocator instead of system allocator.
# May potentially cause some speedups and better memory profile on large runs.

@ -33,7 +33,8 @@ const OPTIONS_NORMAL: &'static [&'static str] = &[
"-v Verbose mode. Output extra information.",
#[cfg(feature="inspect")] "--save <file> Dump the collected data to this file for further inspection.",
#[cfg(feature="inspect")] "-D Dump the collected data to `stdout` (see `--save`.)",
#[cfg(feature="prealloc")] "--save-raw <file> Dump the collected data to this file uncompressed.",
#[cfg(feature="inspect")] "--save-raw <file> Dump the collected data to this file uncompressed. (see `--save`.)",
#[cfg(feature="inspect")] "-Dr Dump the collected data to standard output uncompressed. (see `--save-raw`.)",
"- Stop parsing arguments, treat all the rest as paths.",
];
@ -143,15 +144,23 @@ fn parse<I: IntoIterator<Item=String>>(args: I) -> eyre::Result<Mode>
#[cfg(feature="inspect")] "-D" => {
cfg.serialise_output = Some(config::OutputSerialisationMode::Stdout);
},
#[cfg(feature="inspect")] "-Dr" => {
cfg.serialise_output = Some(config::OutputSerialisationMode::RawStdout);
},
#[cfg(feature="inspect")] "--save" => {
let file = args.next().ok_or(eyre!("`--save` expects a filename parameter"))
.with_suggestion(suggestion_intended_arg.clone())?;
cfg.serialise_output = Some(config::OutputSerialisationMode::File(file.into()));
},
#[cfg(feature="prealloc")] "--save-raw" => {
#[cfg(feature="inspect")] "--save-raw" => {
let file = args.next().ok_or(eyre!("`--save-raw` expects a filename parameter"))
.with_suggestion(suggestion_intended_arg.clone())?;
cfg.serialise_output = Some(config::OutputSerialisationMode::PreallocFile(file.into()));
#[cfg(feature="prealloc")] {
cfg.serialise_output = Some(config::OutputSerialisationMode::PreallocFile(file.into()));
}
#[cfg(not(feature="prealloc"))] {
cfg.serialise_output = Some(config::OutputSerialisationMode::RawFile(file.into()));
}
},
"--recursive" => {
let max = args.next().ok_or(eyre!("`--recursive` expects a parameter"))

@ -98,13 +98,29 @@ impl From<usize> for Recursion
#[cfg(feature="inspect")]
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum OutputSerialisationMode
{
Stdout,
File(PathBuf),
RawFile(PathBuf),
RawStdout,
#[cfg(feature="prealloc")] PreallocFile(PathBuf),
}
#[cfg(feature="inspect")]
impl OutputSerialisationMode
{
/// Should this serialisation mode be compressed?
#[inline] pub fn should_compress(&self) -> bool
{
match self {
Self::File(_) | Self::Stdout => true,
_ => false,
}
}
}
/// Configuration for this run
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Config
@ -139,11 +155,11 @@ impl Config
#[inline] pub fn is_using_stdout(&self) -> bool
{
#[cfg(feature="inspect")] {
return if let Some(OutputSerialisationMode::Stdout) = self.serialise_output {
true
} else {
false
};
return match self.serialise_output {
Some(OutputSerialisationMode::Stdout) |
Some(OutputSerialisationMode::RawStdout) => true,
_ => false,
}
}
#[cfg(not(feature="inspect"))] {
false

@ -73,8 +73,10 @@ async fn normal(cfg: config::Config) -> eyre::Result<()>
type BoxedWrite = Box<dyn tokio::io::AsyncWrite + Unpin>;
use futures::FutureExt;
use config::OutputSerialisationMode;
let should_comp = ser_out.should_compress();
match ser_out {
OutputSerialisationMode::File(output_file) => {
OutputSerialisationMode::File(output_file) |
OutputSerialisationMode::RawFile(output_file) => {
use tokio::fs::OpenOptions;
(async move {
let stream = OpenOptions::new()
@ -86,25 +88,27 @@ async fn normal(cfg: config::Config) -> eyre::Result<()>
.with_section(|| format!("{:?}", output_file).header("File was"))?;
Ok::<BoxedWrite, eyre::Report>(Box::new(stream))
}.boxed(), None)
}.boxed(), None, should_comp)
},
OutputSerialisationMode::Stdout => (async move { Ok::<BoxedWrite, _>(Box::new(tokio::io::stdout())) }.boxed(), None),
OutputSerialisationMode::Stdout |
OutputSerialisationMode::RawStdout => (async move { Ok::<BoxedWrite, _>(Box::new(tokio::io::stdout())) }.boxed(), Option::<&std::path::PathBuf>::None, should_comp),
#[cfg(feature="prealloc")] OutputSerialisationMode::PreallocFile(output_file) => {
(async move {
Ok::<BoxedWrite, _>(Box::new(tokio::io::sink())) // we use a sink as a shim stream since it will never be used when tuple item `.1` is Some()
}.boxed(), Some(output_file))
}.boxed(), Some(output_file), false)
},
}
}) {
// We use tuple item `.1` here to indicate if we're in normal write mode.
// None -> normal
// Some(path) -> prealloc
Some((stream_fut, None)) => {
// `.2` indicates if we should compress while in normal write mode.
Some((stream_fut, None, compress)) => {
let stream = stream_fut.await?;
serial::write_async(stream, &graph, true).await // TODO: raw version
serial::write_async(stream, &graph, compress).await // TODO: raw version, how to implement?
.wrap_err(eyre!("Failed to serialise graph to stream"))?;
},
#[cfg(feature="prealloc")] Some((_task_fut, Some(output_file))) => {
#[cfg(feature="prealloc")] Some((_task_fut, Some(output_file), _)) => {
use tokio::fs::OpenOptions;
let file = OpenOptions::new()
.write(true)

@ -17,18 +17,49 @@ const DEFER_DROP_SIZE_FLOOR: usize = 1024 * 1024; // 1 MB
enum MaybeCompressor<'a, T>
{
Compressing(Compressor<&'a mut T>),
Decompressing(Decompressor<&'a mut T>),
Raw(&'a mut T),
}
/// Compress or decompress?
#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy, PartialOrd, Ord)]
enum CompKind
{
Compress,
Decompress
}
impl Default for CompKind
{
#[inline]
fn default() -> Self
{
Self::Compress
}
}
impl<'a, T> MaybeCompressor<'a, T>
{
/// What kind is this compressor set to
pub fn kind(&self) -> Option<CompKind>
{
Some(match self {
Self::Raw(_) => return None,
Self::Compressing(_) => CompKind::Compress,
Self::Decompressing(_) => CompKind::Decompress,
})
}
}
impl<'a, T> MaybeCompressor<'a, T>
where T: AsyncWrite + Unpin + 'a
{
pub fn new(raw: &'a mut T, compress: bool) -> Self
pub fn new(raw: &'a mut T, compress: Option<CompKind>) -> Self
{
if compress {
Self::Compressing(Compressor::new(raw))
} else {
Self::Raw(raw)
match compress {
Some(CompKind::Compress) => Self::Compressing(Compressor::new(raw)),
Some(CompKind::Decompress) => Self::Decompressing(Decompressor::new(raw)),
None => Self::Raw(raw),
}
}
}
@ -39,6 +70,7 @@ where T: AsyncWrite + Unpin + 'a
fn deref_mut(&mut self) -> &mut Self::Target {
match self {
Self::Compressing(t) => t,
Self::Decompressing(t) => t,
Self::Raw(o) => o,
}
}
@ -51,6 +83,7 @@ where T: AsyncWrite + Unpin + 'a
fn deref(&self) -> &Self::Target {
match self {
Self::Compressing(t) => t,
Self::Decompressing(t) => t,
Self::Raw(o) => o,
}
}
@ -73,7 +106,7 @@ where W: AsyncWrite + Unpin
.with_section(sect_type_name.clone())?;
{
let mut stream = MaybeCompressor::new(&mut to, compress);
let mut stream = MaybeCompressor::new(&mut to, compress.then(|| CompKind::Compress));
cfg_eprintln!(Verbose; config::get_global(), "Writing {} bytes of type {:?} to stream of type {:?}", vec.len(), std::any::type_name::<T>(), std::any::type_name::<W>());

Loading…
Cancel
Save