source: code/trunk/vendor/github.com/andybalholm/brotli/cluster_command.go@ 145

Last change on this file since 145 was 145, checked in by Izuru Yakumo, 22 months ago

Updated the Makefile and vendored depedencies

Signed-off-by: Izuru Yakumo <yakumo.izuru@…>

File size: 4.6 KB
Line 
1package brotli
2
3/* Copyright 2013 Google Inc. All Rights Reserved.
4
5 Distributed under MIT license.
6 See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
7*/
8
9/* Computes the bit cost reduction by combining out[idx1] and out[idx2] and if
10 it is below a threshold, stores the pair (idx1, idx2) in the *pairs queue. */
11func compareAndPushToQueueCommand(out []histogramCommand, cluster_size []uint32, idx1 uint32, idx2 uint32, max_num_pairs uint, pairs []histogramPair, num_pairs *uint) {
12 var is_good_pair bool = false
13 var p histogramPair
14 p.idx2 = 0
15 p.idx1 = p.idx2
16 p.cost_combo = 0
17 p.cost_diff = p.cost_combo
18 if idx1 == idx2 {
19 return
20 }
21
22 if idx2 < idx1 {
23 var t uint32 = idx2
24 idx2 = idx1
25 idx1 = t
26 }
27
28 p.idx1 = idx1
29 p.idx2 = idx2
30 p.cost_diff = 0.5 * clusterCostDiff(uint(cluster_size[idx1]), uint(cluster_size[idx2]))
31 p.cost_diff -= out[idx1].bit_cost_
32 p.cost_diff -= out[idx2].bit_cost_
33
34 if out[idx1].total_count_ == 0 {
35 p.cost_combo = out[idx2].bit_cost_
36 is_good_pair = true
37 } else if out[idx2].total_count_ == 0 {
38 p.cost_combo = out[idx1].bit_cost_
39 is_good_pair = true
40 } else {
41 var threshold float64
42 if *num_pairs == 0 {
43 threshold = 1e99
44 } else {
45 threshold = brotli_max_double(0.0, pairs[0].cost_diff)
46 }
47 var combo histogramCommand = out[idx1]
48 var cost_combo float64
49 histogramAddHistogramCommand(&combo, &out[idx2])
50 cost_combo = populationCostCommand(&combo)
51 if cost_combo < threshold-p.cost_diff {
52 p.cost_combo = cost_combo
53 is_good_pair = true
54 }
55 }
56
57 if is_good_pair {
58 p.cost_diff += p.cost_combo
59 if *num_pairs > 0 && histogramPairIsLess(&pairs[0], &p) {
60 /* Replace the top of the queue if needed. */
61 if *num_pairs < max_num_pairs {
62 pairs[*num_pairs] = pairs[0]
63 (*num_pairs)++
64 }
65
66 pairs[0] = p
67 } else if *num_pairs < max_num_pairs {
68 pairs[*num_pairs] = p
69 (*num_pairs)++
70 }
71 }
72}
73
74func histogramCombineCommand(out []histogramCommand, cluster_size []uint32, symbols []uint32, clusters []uint32, pairs []histogramPair, num_clusters uint, symbols_size uint, max_clusters uint, max_num_pairs uint) uint {
75 var cost_diff_threshold float64 = 0.0
76 var min_cluster_size uint = 1
77 var num_pairs uint = 0
78 {
79 /* We maintain a vector of histogram pairs, with the property that the pair
80 with the maximum bit cost reduction is the first. */
81 var idx1 uint
82 for idx1 = 0; idx1 < num_clusters; idx1++ {
83 var idx2 uint
84 for idx2 = idx1 + 1; idx2 < num_clusters; idx2++ {
85 compareAndPushToQueueCommand(out, cluster_size, clusters[idx1], clusters[idx2], max_num_pairs, pairs[0:], &num_pairs)
86 }
87 }
88 }
89
90 for num_clusters > min_cluster_size {
91 var best_idx1 uint32
92 var best_idx2 uint32
93 var i uint
94 if pairs[0].cost_diff >= cost_diff_threshold {
95 cost_diff_threshold = 1e99
96 min_cluster_size = max_clusters
97 continue
98 }
99
100 /* Take the best pair from the top of heap. */
101 best_idx1 = pairs[0].idx1
102
103 best_idx2 = pairs[0].idx2
104 histogramAddHistogramCommand(&out[best_idx1], &out[best_idx2])
105 out[best_idx1].bit_cost_ = pairs[0].cost_combo
106 cluster_size[best_idx1] += cluster_size[best_idx2]
107 for i = 0; i < symbols_size; i++ {
108 if symbols[i] == best_idx2 {
109 symbols[i] = best_idx1
110 }
111 }
112
113 for i = 0; i < num_clusters; i++ {
114 if clusters[i] == best_idx2 {
115 copy(clusters[i:], clusters[i+1:][:num_clusters-i-1])
116 break
117 }
118 }
119
120 num_clusters--
121 {
122 /* Remove pairs intersecting the just combined best pair. */
123 var copy_to_idx uint = 0
124 for i = 0; i < num_pairs; i++ {
125 var p *histogramPair = &pairs[i]
126 if p.idx1 == best_idx1 || p.idx2 == best_idx1 || p.idx1 == best_idx2 || p.idx2 == best_idx2 {
127 /* Remove invalid pair from the queue. */
128 continue
129 }
130
131 if histogramPairIsLess(&pairs[0], p) {
132 /* Replace the top of the queue if needed. */
133 var front histogramPair = pairs[0]
134 pairs[0] = *p
135 pairs[copy_to_idx] = front
136 } else {
137 pairs[copy_to_idx] = *p
138 }
139
140 copy_to_idx++
141 }
142
143 num_pairs = copy_to_idx
144 }
145
146 /* Push new pairs formed with the combined histogram to the heap. */
147 for i = 0; i < num_clusters; i++ {
148 compareAndPushToQueueCommand(out, cluster_size, best_idx1, clusters[i], max_num_pairs, pairs[0:], &num_pairs)
149 }
150 }
151
152 return num_clusters
153}
154
155/* What is the bit cost of moving histogram from cur_symbol to candidate. */
156func histogramBitCostDistanceCommand(histogram *histogramCommand, candidate *histogramCommand) float64 {
157 if histogram.total_count_ == 0 {
158 return 0.0
159 } else {
160 var tmp histogramCommand = *histogram
161 histogramAddHistogramCommand(&tmp, candidate)
162 return populationCostCommand(&tmp) - candidate.bit_cost_
163 }
164}
Note: See TracBrowser for help on using the repository browser.