1
2
3
4
5 package flate
6
7
8
9
10 func sortByFreq(data []literalNode) {
11 n := len(data)
12 quickSortByFreq(data, 0, n, maxDepth(n))
13 }
14
15 func quickSortByFreq(data []literalNode, a, b, maxDepth int) {
16 for b-a > 12 {
17 if maxDepth == 0 {
18 heapSort(data, a, b)
19 return
20 }
21 maxDepth--
22 mlo, mhi := doPivotByFreq(data, a, b)
23
24
25 if mlo-a < b-mhi {
26 quickSortByFreq(data, a, mlo, maxDepth)
27 a = mhi
28 } else {
29 quickSortByFreq(data, mhi, b, maxDepth)
30 b = mlo
31 }
32 }
33 if b-a > 1 {
34
35
36 for i := a + 6; i < b; i++ {
37 if data[i].freq == data[i-6].freq && data[i].literal < data[i-6].literal || data[i].freq < data[i-6].freq {
38 data[i], data[i-6] = data[i-6], data[i]
39 }
40 }
41 insertionSortByFreq(data, a, b)
42 }
43 }
44
45 func doPivotByFreq(data []literalNode, lo, hi int) (midlo, midhi int) {
46 m := int(uint(lo+hi) >> 1)
47 if hi-lo > 40 {
48
49 s := (hi - lo) / 8
50 medianOfThreeSortByFreq(data, lo, lo+s, lo+2*s)
51 medianOfThreeSortByFreq(data, m, m-s, m+s)
52 medianOfThreeSortByFreq(data, hi-1, hi-1-s, hi-1-2*s)
53 }
54 medianOfThreeSortByFreq(data, lo, m, hi-1)
55
56
57
58
59
60
61
62
63 pivot := lo
64 a, c := lo+1, hi-1
65
66 for ; a < c && (data[a].freq == data[pivot].freq && data[a].literal < data[pivot].literal || data[a].freq < data[pivot].freq); a++ {
67 }
68 b := a
69 for {
70 for ; b < c && (data[pivot].freq == data[b].freq && data[pivot].literal > data[b].literal || data[pivot].freq > data[b].freq); b++ {
71 }
72 for ; b < c && (data[pivot].freq == data[c-1].freq && data[pivot].literal < data[c-1].literal || data[pivot].freq < data[c-1].freq); c-- {
73 }
74 if b >= c {
75 break
76 }
77
78 data[b], data[c-1] = data[c-1], data[b]
79 b++
80 c--
81 }
82
83
84 protect := hi-c < 5
85 if !protect && hi-c < (hi-lo)/4 {
86
87 dups := 0
88 if data[pivot].freq == data[hi-1].freq && data[pivot].literal > data[hi-1].literal || data[pivot].freq > data[hi-1].freq {
89 data[c], data[hi-1] = data[hi-1], data[c]
90 c++
91 dups++
92 }
93 if data[b-1].freq == data[pivot].freq && data[b-1].literal > data[pivot].literal || data[b-1].freq > data[pivot].freq {
94 b--
95 dups++
96 }
97
98
99
100 if data[m].freq == data[pivot].freq && data[m].literal > data[pivot].literal || data[m].freq > data[pivot].freq {
101 data[m], data[b-1] = data[b-1], data[m]
102 b--
103 dups++
104 }
105
106 protect = dups > 1
107 }
108 if protect {
109
110
111
112
113 for {
114 for ; a < b && (data[b-1].freq == data[pivot].freq && data[b-1].literal > data[pivot].literal || data[b-1].freq > data[pivot].freq); b-- {
115 }
116 for ; a < b && (data[a].freq == data[pivot].freq && data[a].literal < data[pivot].literal || data[a].freq < data[pivot].freq); a++ {
117 }
118 if a >= b {
119 break
120 }
121
122 data[a], data[b-1] = data[b-1], data[a]
123 a++
124 b--
125 }
126 }
127
128 data[pivot], data[b-1] = data[b-1], data[pivot]
129 return b - 1, c
130 }
131
132
133 func insertionSortByFreq(data []literalNode, a, b int) {
134 for i := a + 1; i < b; i++ {
135 for j := i; j > a && (data[j].freq == data[j-1].freq && data[j].literal < data[j-1].literal || data[j].freq < data[j-1].freq); j-- {
136 data[j], data[j-1] = data[j-1], data[j]
137 }
138 }
139 }
140
141
142
143
144
145 func medianOfThreeSortByFreq(data []literalNode, m1, m0, m2 int) {
146
147 if data[m1].freq == data[m0].freq && data[m1].literal < data[m0].literal || data[m1].freq < data[m0].freq {
148 data[m1], data[m0] = data[m0], data[m1]
149 }
150
151 if data[m2].freq == data[m1].freq && data[m2].literal < data[m1].literal || data[m2].freq < data[m1].freq {
152 data[m2], data[m1] = data[m1], data[m2]
153
154 if data[m1].freq == data[m0].freq && data[m1].literal < data[m0].literal || data[m1].freq < data[m0].freq {
155 data[m1], data[m0] = data[m0], data[m1]
156 }
157 }
158
159 }
160
View as plain text