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

Revisit BrotliStream CompressionLevel values #46595

Closed
stephentoub opened this issue Jan 5, 2021 · 7 comments · Fixed by #57561 or #72266
Closed

Revisit BrotliStream CompressionLevel values #46595

stephentoub opened this issue Jan 5, 2021 · 7 comments · Fixed by #57561 or #72266
Assignees
Milestone

Comments

@stephentoub
Copy link
Member

stephentoub commented Jan 5, 2021

Two independent-but-related issues:

  1. The ctor:
public BrotliStream(Stream stream, CompressionLevel compressionLevel)

passes the compressionLevel to the function:

        internal static int GetQualityFromCompressionLevel(CompressionLevel level) =>
            level switch
            {
                CompressionLevel.Optimal => Quality_Default,
                CompressionLevel.NoCompression => Quality_Min,
                CompressionLevel.Fastest => 1,
                CompressionLevel.SmallestSize => Quality_Max,
                _ => (int)level,
            };

with no argument validation. If an arbitrary level is provided, that then gets passed through as-is to the underlying library, resulting in inconsistent and potentially unexpected behavior. We should decide whether we're ok with this behavior or whether we should take a breaking change to correct it and be more like DeflateStream, which throws for an unknown value.

  1. The quality values are set as:
        public const int Quality_Min = 0;
        public const int Quality_Default = 11;
        public const int Quality_Max = 11;

With the introduction of SmallestSize (#1549 (comment)) and the rationale employed for it that Optimal should really be a good balance between speed and size, we should define it closer to 6 rather than 11. The docs will also need to be updated.

@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added area-System.IO.Compression untriaged New issue has not been triaged by the area owner labels Jan 5, 2021
@stephentoub stephentoub changed the title Revisit BrotliStream Revisit BrotliStream CompressionLevel values Jan 5, 2021
@stephentoub stephentoub added this to the 6.0.0 milestone Jan 5, 2021
@stephentoub stephentoub added bug tenet-performance Performance related issue labels Jan 5, 2021
@GSPP
Copy link

GSPP commented Jan 7, 2021

Users are definitely going to take a dependency on this. It will become harder and harder to change this.

@carlossanlop
Copy link
Member

Triage:

We should decide whether we're ok with this behavior or whether we should take a breaking change to correct it

  1. I think we should be slightly more strict with validation: The user should still be able to pass an arbitrary value, but only if it's between the acceptable ranges of the underlying algorithm.

we should define it closer to 6 rather than 11

  1. Makes sense. We should make the change. I think the docs are already correct in triple slash for both the SmallestSize and Optimal enum values, so we need to make sure the MS Docs texts are updated.

This could become a breaking change for customers already using Optimal, so we need to make sure to report this.

@carlossanlop carlossanlop added help wanted [up-for-grabs] Good issue for external contributors and removed untriaged New issue has not been triaged by the area owner labels Jan 19, 2021
@stephentoub
Copy link
Member Author

stephentoub commented Jan 19, 2021

I think we should be slightly more strict with validation: The user should still be able to pass an arbitrary value, but only if it's between the acceptable ranges of the underlying algorithm.

To be clear, this means that if someone passes in the values 0, 1, 2, or 3 it's interpreted as the corresponding value from CompressionLevel, but if someone passes in 4 through 11, it's interpreted completely differently as the underlying compression level setting? (Also, the validation you propose is already done.)

@adamsitnik adamsitnik modified the milestones: 6.0.0, 7.0.0 Jul 26, 2021
i3arnon added a commit to i3arnon/runtime that referenced this issue Aug 15, 2021
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Aug 15, 2021
@i3arnon
Copy link
Contributor

i3arnon commented Aug 15, 2021

I went ahead with a PR that validates that values are between 0 and 11: #57440

@carlossanlop
Copy link
Member

carlossanlop commented Nov 1, 2021

To be clear, this means that if someone passes in the values 0, 1, 2, or 3 it's interpreted as the corresponding value from CompressionLevel, but if someone passes in 4 through 11, it's interpreted completely differently as the underlying compression level setting?

I see what you mean. My idea would be confusing to users.

What about a constructor that takes an integer between 0 and 11, to allow users to freely specify a valid compression level value accepted by the underlying algorithm, without using a CompressionLevel enum value? We could consider it an advanced API.

@stephentoub
Copy link
Member Author

What about a constructor that takes an integer between 0 and 11, to allow users to freely specify a valid compression level value accepted by the underlying algorithm, without using a CompressionLevel enum value? We could consider it an advanced API.

That's what BrotliEncoder provides, what #1556 proposes for BrotliStream, and what #42820 discusses standardizing for all of compression.

@ghost ghost locked as resolved and limited conversation to collaborators Dec 15, 2021
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Jan 24, 2022
@stephentoub
Copy link
Member Author

stephentoub commented Jul 14, 2022

@carlossanlop, this was closed by #57561, but it only addressed half of this issue. Was closing it intentional? The two halves should really be addressed together.

@stephentoub stephentoub reopened this Jul 14, 2022
@stephentoub stephentoub removed the help wanted [up-for-grabs] Good issue for external contributors label Jul 14, 2022
@dotnet dotnet unlocked this conversation Jul 14, 2022
@stephentoub stephentoub self-assigned this Jul 15, 2022
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Jul 15, 2022
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Jul 15, 2022
@ghost ghost locked as resolved and limited conversation to collaborators Aug 15, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.