1
0
mirror of https://github.com/chylex/Brotli-Builder.git synced 2025-04-13 00:15:42 +02:00

Remove HuffmanNode.SymbolCount and use HuffmanTree lookup instead

This commit is contained in:
chylex 2019-11-30 01:48:09 +01:00
parent 698bded3fb
commit 53f3f2b7d2
7 changed files with 8 additions and 31 deletions

View File

@ -27,13 +27,13 @@ namespace BrotliLib.Brotli.Components.Header{
public static readonly BitSerializer<HuffmanTree<T>, Context> Serialize = (writer, obj, context) => {
int bitsPerSymbol = context.AlphabetSize.BitsPerSymbol;
writer.WriteChunk(2, obj.Root.SymbolCount - 1);
writer.WriteChunk(2, obj.SymbolCount - 1);
foreach(T symbol in obj.OrderBy(kvp => kvp.Value.Length).Select(kvp => kvp.Key)){
writer.WriteChunk(bitsPerSymbol, context.SymbolToBits(symbol));
}
if (obj.Root.SymbolCount == 4){
if (obj.SymbolCount == 4){
writer.WriteBit(obj.MaxDepth > 2);
}
};

View File

@ -38,6 +38,11 @@ namespace BrotliLib.Brotli.Components.Header{
/// </summary>
public HuffmanNode<T> Root { get; }
/// <summary>
/// Total amount of symbols in the tree.
/// </summary>
public int SymbolCount => ReverseLookup.Count;
/// <summary>
/// Length of the longest path in the tree.
/// </summary>
@ -177,7 +182,7 @@ namespace BrotliLib.Brotli.Components.Header{
);
public static readonly BitSerializer<HuffmanTree<T>, Context> Serialize = (writer, obj, context) => {
if (obj.Root.SymbolCount <= 4){
if (obj.SymbolCount <= 4){
writer.WriteChunk(2, 0b01);
Simple.Serialize(writer, obj, context);
}

View File

@ -8,8 +8,6 @@ namespace BrotliLib.Collections.Huffman{
/// Dummy node used as a workaround for leaking Huffman tree generation.
/// </summary>
public sealed class Dummy : HuffmanNode<T>{
public override int SymbolCount => 0;
public override T LookupValue(IBitReader bits){
return default!;
}

View File

@ -8,8 +8,6 @@ namespace BrotliLib.Collections.Huffman{
/// Leaf node that contains a <see cref="value"/> of type <code>T</code>.
/// </summary>
public sealed class Leaf : HuffmanNode<T>{
public override int SymbolCount => 1;
private readonly T value;
public Leaf(T value){

View File

@ -9,15 +9,11 @@ namespace BrotliLib.Collections.Huffman{
/// Path node with exactly two child nodes. When traversing through the tree, a 0 bit indicates going <see cref="left"/> while a 1 bit indicates going <see cref="right"/>.
/// </summary>
public sealed class Path : HuffmanNode<T>{
public override int SymbolCount => symbolCount;
private readonly HuffmanNode<T> left, right;
private readonly int symbolCount;
public Path(HuffmanNode<T> left, HuffmanNode<T> right){
this.left = left;
this.right = right;
this.symbolCount = left.SymbolCount + right.SymbolCount;
}
public override T LookupValue(IBitReader bits){

View File

@ -8,8 +8,6 @@ namespace BrotliLib.Collections.Huffman{
/// </summary>
/// <typeparam name="T">Type of values contained inside the tree.</typeparam>
public abstract partial class HuffmanNode<T>{
public abstract int SymbolCount { get; }
/// <summary>
/// Traverses through the tree, consuming the <paramref name="bits"/> reader until it hits a <see cref="Leaf"/> node.
/// Returns the found value, or <code>default(T)</code> if the <paramref name="bits"/> reader reaches the end.

View File

@ -34,24 +34,6 @@ module Helper =
)
module Count =
[<Fact>]
let ``a leaf node has 1 symbol`` () =
Assert.Equal(1, Helper.leaf.SymbolCount)
[<Fact>]
let ``a path of depth 1 has 2 symbols`` () =
Assert.Equal(2, Helper.depth1.SymbolCount)
[<Fact>]
let ``a path of depth 2 with 3 symbols returns correct value`` () =
Assert.Equal(3, Helper.depth2count3.SymbolCount)
[<Fact>]
let ``a path of depth 2 with 4 symbols returns correct value`` () =
Assert.Equal(4, Helper.depth2count4.SymbolCount)
module Traversal =
[<Fact>]
let ``a leaf node returns its value without consuming any bits`` () =