From 6b5963335ea630eaa70d7b1ce1e89189dc92c60b Mon Sep 17 00:00:00 2001 From: Andy Balholm Date: Thu, 7 May 2020 17:51:21 -0700 Subject: [PATCH] Use sort.Sort to sort Huffman trees. --- brotli_bit_stream.go | 11 ++++--- entropy_encode.go | 69 +++++++++----------------------------------- 2 files changed, 19 insertions(+), 61 deletions(-) diff --git a/brotli_bit_stream.go b/brotli_bit_stream.go index 23d63f1..4e5d105 100644 --- a/brotli_bit_stream.go +++ b/brotli_bit_stream.go @@ -1,6 +1,9 @@ package brotli -import "math" +import ( + "math" + "sort" +) const maxHuffmanTreeSize = (2*numCommandSymbols + 1) @@ -411,10 +414,6 @@ func buildAndStoreHuffmanTree(histogram []uint32, histogram_length uint, alphabe } } -func sortHuffmanTree1(v0 huffmanTree, v1 huffmanTree) bool { - return v0.total_count_ < v1.total_count_ -} - func buildAndStoreHuffmanTreeFast(histogram []uint32, histogram_total uint, max_bits uint, depth []byte, bits []uint16, storage_ix *uint, storage []byte) { var count uint = 0 var symbols = [4]uint{0} @@ -471,7 +470,7 @@ func buildAndStoreHuffmanTreeFast(histogram []uint32, histogram_total uint, max_ var j int = n + 1 var k int - sortHuffmanTreeItems(tree, uint(n), huffmanTreeComparator(sortHuffmanTree1)) + sort.Sort(sortHuffmanTree(tree[:n])) /* The nodes are: [0, n): the sorted leaf nodes that we start with. diff --git a/entropy_encode.go b/entropy_encode.go index 3f469a3..e48ca25 100644 --- a/entropy_encode.go +++ b/entropy_encode.go @@ -1,6 +1,9 @@ package brotli -import "math" +import ( + "math" + "sort" +) /* Copyright 2010 Google Inc. All Rights Reserved. @@ -23,55 +26,6 @@ func initHuffmanTree(self *huffmanTree, count uint32, left int16, right int16) { self.index_right_or_value_ = right } -/* Input size optimized Shell sort. */ -type huffmanTreeComparator func(huffmanTree, huffmanTree) bool - -var sortHuffmanTreeItems_gaps = []uint{132, 57, 23, 10, 4, 1} - -func sortHuffmanTreeItems(items []huffmanTree, n uint, comparator huffmanTreeComparator) { - if n < 13 { - /* Insertion sort. */ - var i uint - for i = 1; i < n; i++ { - var tmp huffmanTree = items[i] - var k uint = i - var j uint = i - 1 - for comparator(tmp, items[j]) { - items[k] = items[j] - k = j - if j == 0 { - break - } - j-- - } - - items[k] = tmp - } - - return - } else { - var g int - if n < 57 { - g = 2 - } else { - g = 0 - } - for ; g < 6; g++ { - var gap uint = sortHuffmanTreeItems_gaps[g] - var i uint - for i = gap; i < n; i++ { - var j uint = i - var tmp huffmanTree = items[i] - for ; j >= gap && comparator(tmp, items[j-gap]); j -= gap { - items[j] = items[j-gap] - } - - items[j] = tmp - } - } - } -} - /* Returns 1 if assignment of depths succeeded, otherwise 0. */ func setDepth(p0 int, pool []huffmanTree, depth []byte, max_depth int) bool { var stack [16]int @@ -104,12 +58,17 @@ func setDepth(p0 int, pool []huffmanTree, depth []byte, max_depth int) bool { } /* Sort the root nodes, least popular first. */ -func sortHuffmanTree(v0 huffmanTree, v1 huffmanTree) bool { - if v0.total_count_ != v1.total_count_ { - return v0.total_count_ < v1.total_count_ +type sortHuffmanTree []huffmanTree + +func (s sortHuffmanTree) Len() int { return len(s) } +func (s sortHuffmanTree) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +func (s sortHuffmanTree) Less(i, j int) bool { + if s[i].total_count_ != s[j].total_count_ { + return s[i].total_count_ < s[j].total_count_ } - return v0.index_right_or_value_ > v1.index_right_or_value_ + return s[i].index_right_or_value_ > s[j].index_right_or_value_ } /* This function will create a Huffman tree. @@ -155,7 +114,7 @@ func createHuffmanTree(data []uint32, length uint, tree_limit int, tree []huffma break } - sortHuffmanTreeItems(tree, n, huffmanTreeComparator(sortHuffmanTree)) + sort.Sort(sortHuffmanTree(tree[:n])) /* The nodes are: [0, n): the sorted leaf nodes that we start with.