Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compress inputs #6

Closed
wants to merge 4 commits into from
Closed

Compress inputs #6

wants to merge 4 commits into from

Conversation

mlodato517
Copy link
Owner

@mlodato517 mlodato517 commented Feb 1, 2022

This PR

  • Adds a workspace member for compressing inputs
  • Compresses the input to day1 (for a saving of like 87%!)
  • Updates day1 to use the compressed input
  • Ignores any future input.txts

Why?
I don't know, saving space sounded nice and it wasn't
something I'd ever tried before. The brotli library has pretty
rough struct/function names and was missing a lot of docs
so that could be a nice contribution sometime!

@mlodato517 mlodato517 self-assigned this Feb 1, 2022
pub fn compress(input: String) -> Vec<u8> {
let input = input.into_bytes();
let mut output = Vec::with_capacity(input.len());
brotli::BrotliCompress(&mut input.as_slice(), &mut output, &Default::default()).unwrap();
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of the default parameters we could probably specify a quality to get even smaller things.

**Why?**
So we can compress inputs because 🤷.
Using the new `compress` member. Also ignore any future `input.txt`s.
@mlodato517 mlodato517 marked this pull request as ready for review February 1, 2022 13:18
#[macro_export]
macro_rules! aoc_input {
($path:literal) => {{
let file = include_bytes!("../input.compressed").to_vec();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should use $path here :)

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated in d102205!

/// Decompresses the passed byte vector into a string.
pub fn decompress(input: Vec<u8>) -> String {
let mut output = Vec::with_capacity(input.len());
brotli::BrotliDecompress(&mut input.as_slice(), &mut output).unwrap();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mark was smarter than me and noticed this was weird. He might figure out why this needs to be this way.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So there's a lot to say here. I'll leave high level overviews and we can dig into anything else if we feel like it!

  1. The reason why we need a &mut here is not because of anything to do with the Read trait - it's just required by the BrotliDecompress API.
  2. According to the Rust API guidelines, BrotliDecompress really should accept readers and writers by value, not by &mut. However making the switch is a breaking change! First, to see why this is surprising, look at this example showing it "isn't" a breaking change. Next, look at this example showing it is a breaking change! What's going on here?? It turns out to be a fairly complicated topic called reborrowing. It doesn't work trivially with generics so there's a bit of tension here between the Rust API guidelines recommending something for flexibility while that flexibility also requires surprise manual reborrowing. Either way, we can't just make a PR to update it :-)

Copy link
Owner Author

@mlodato517 mlodato517 Feb 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though I did take this opportunity to rewrite the compress library in terms of Readers and Writers though I'm not sure it's actually better - 5599a7f. One benefit is that the compress binary doesn't need to read into strings and write out to files - it reads from a file and writes directly to a file 🤷

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh and another thing that was originally weird - we wondered why the std::io::Read trait took &mut self all the time since reading sounded like something you could do in a shared setting. I imagine this is because reading from a network socket or file requires updating internal state that's unsafe to do with a shared reference.

**This Commit**
Updates the `aoc_input` macro to use the passed `$path` when determining
which file to read.

**Why?**
Because the original was definitely a typo. However, we could decide
that all inputs are in a consistent place and not have the macro take an
argument but this seems less weird for now.

See #6 (comment)
for more details.
@mlodato517
Copy link
Owner Author

I think we've learned some cool stuff here about the Read and Write traits but I'm going to close this one since it isn't obviously super valuable and it'll be one less thing to think about! We can always resurrect it if we come upon a day with an absolutely gigantic input.

@mlodato517 mlodato517 closed this Feb 25, 2022
@mlodato517 mlodato517 deleted the compress-inputs branch February 25, 2022 14:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants