diff --git a/src/pkg/compress/flate/huffman_code.go b/src/pkg/compress/flate/huffman_code.go index 009cce6267..3b9fce466e 100644 --- a/src/pkg/compress/flate/huffman_code.go +++ b/src/pkg/compress/flate/huffman_code.go @@ -19,23 +19,13 @@ type literalNode struct { freq int32 } -type chain struct { - // The sum of the leaves in this tree - freq int32 - - // The number of literals to the left of this item at this level - leafCount int32 - - // The right child of this chain in the previous level. - up *chain -} - +// A levelInfo describes the state of the constructed tree for a given depth. type levelInfo struct { // Our level. for better printing level int32 - // The most recent chain generated for this level - lastChain *chain + // The frequency of the last node at this level + lastFreq int32 // The frequency of the next character to add to this level nextCharFreq int32 @@ -47,12 +37,6 @@ type levelInfo struct { // The number of chains remaining to generate for this level before moving // up to the next level needed int32 - - // The levelInfo for level+1 - up *levelInfo - - // The levelInfo for level-1 - down *levelInfo } func maxNode() literalNode { return literalNode{math.MaxUint16, math.MaxInt32} } @@ -121,6 +105,8 @@ func (h *huffmanEncoder) bitLength(freq []int32) int64 { return total } +const maxBitsLimit = 16 + // Return the number of literals assigned to each bit size in the Huffman encoding // // This method is only called when list.length >= 3 @@ -131,9 +117,13 @@ func (h *huffmanEncoder) bitLength(freq []int32) int64 { // frequency, and has as its last element a special element with frequency // MaxInt32 // maxBits The maximum number of bits that should be used to encode any literal. +// Must be less than 16. // return An integer array in which array[i] indicates the number of literals // that should be encoded in i bits. func (h *huffmanEncoder) bitCounts(list []literalNode, maxBits int32) []int32 { + if maxBits >= maxBitsLimit { + panic("flate: maxBits too large") + } n := int32(len(list)) list = list[0 : n+1] list[n] = maxNode() @@ -148,53 +138,61 @@ func (h *huffmanEncoder) bitCounts(list []literalNode, maxBits int32) []int32 { // A bogus "Level 0" whose sole purpose is so that // level1.prev.needed==0. This makes level1.nextPairFreq // be a legitimate value that never gets chosen. - top := &levelInfo{needed: 0} - chain2 := &chain{list[1].freq, 2, new(chain)} + var levels [maxBitsLimit]levelInfo + // leafCounts[i] counts the number of literals at the left + // of ancestors of the rightmost node at level i. + // leafCounts[i][j] is the number of literals at the left + // of the level j ancestor. + var leafCounts [maxBitsLimit][maxBitsLimit]int32 + for level := int32(1); level <= maxBits; level++ { // For every level, the first two items are the first two characters. // We initialize the levels as if we had already figured this out. - top = &levelInfo{ + levels[level] = levelInfo{ level: level, - lastChain: chain2, + lastFreq: list[1].freq, nextCharFreq: list[2].freq, nextPairFreq: list[0].freq + list[1].freq, - down: top, } - top.down.up = top + leafCounts[level][level] = 2 if level == 1 { - top.nextPairFreq = math.MaxInt32 + levels[level].nextPairFreq = math.MaxInt32 } } // We need a total of 2*n - 2 items at top level and have already generated 2. - top.needed = 2*n - 4 + levels[maxBits].needed = 2*n - 4 - l := top + level := maxBits for { + l := &levels[level] if l.nextPairFreq == math.MaxInt32 && l.nextCharFreq == math.MaxInt32 { // We've run out of both leafs and pairs. // End all calculations for this level. - // To m sure we never come back to this level or any lower level, + // To make sure we never come back to this level or any lower level, // set nextPairFreq impossibly large. - l.lastChain = nil l.needed = 0 - l = l.up - l.nextPairFreq = math.MaxInt32 + levels[level+1].nextPairFreq = math.MaxInt32 + level++ continue } - prevFreq := l.lastChain.freq + prevFreq := l.lastFreq if l.nextCharFreq < l.nextPairFreq { // The next item on this row is a leaf node. - n := l.lastChain.leafCount + 1 - l.lastChain = &chain{l.nextCharFreq, n, l.lastChain.up} + n := leafCounts[level][level] + 1 + l.lastFreq = l.nextCharFreq + // Lower leafCounts are the same of the previous node. + leafCounts[level][level] = n l.nextCharFreq = list[n].freq } else { // The next item on this row is a pair from the previous row. // nextPairFreq isn't valid until we generate two // more values in the level below - l.lastChain = &chain{l.nextPairFreq, l.lastChain.leafCount, l.down.lastChain} - l.down.needed = 2 + l.lastFreq = l.nextPairFreq + // Take leaf counts from the lower level, except counts[level] remains the same. + copy(leafCounts[level][:level], leafCounts[level-1][:level]) + levels[l.level-1].needed = 2 } if l.needed--; l.needed == 0 { @@ -202,33 +200,33 @@ func (h *huffmanEncoder) bitCounts(list []literalNode, maxBits int32) []int32 { // Continue calculating one level up. Fill in nextPairFreq // of that level with the sum of the two nodes we've just calculated on // this level. - up := l.up - if up == nil { + if l.level == maxBits { // All done! break } - up.nextPairFreq = prevFreq + l.lastChain.freq - l = up + levels[l.level+1].nextPairFreq = prevFreq + l.lastFreq + level++ } else { // If we stole from below, move down temporarily to replenish it. - for l.down.needed > 0 { - l = l.down + for levels[level-1].needed > 0 { + level-- } } } // Somethings is wrong if at the end, the top level is null or hasn't used // all of the leaves. - if top.lastChain.leafCount != n { - panic("top.lastChain.leafCount != n") + if leafCounts[maxBits][maxBits] != n { + panic("leafCounts[maxBits][maxBits] != n") } bitCount := make([]int32, maxBits+1) bits := 1 - for chain := top.lastChain; chain.up != nil; chain = chain.up { + counts := &leafCounts[maxBits] + for level := maxBits; level > 0; level-- { // chain.leafCount gives the number of literals requiring at least "bits" // bits to encode. - bitCount[bits] = chain.leafCount - chain.up.leafCount + bitCount[bits] = counts[level] - counts[level-1] bits++ } return bitCount