1
2
3
4
5 package zstd
6
7 import (
8 "fmt"
9 "math"
10 "sync"
11 )
12
13 var (
14
15
16
17 fsePredef [3]fseDecoder
18
19
20
21
22 fsePredefEnc [3]fseEncoder
23
24
25
26 symbolTableX [3][]baseOffset
27
28
29
30 maxTableSymbol = [3]uint8{tableLiteralLengths: maxLiteralLengthSymbol, tableOffsets: maxOffsetLengthSymbol, tableMatchLengths: maxMatchLengthSymbol}
31
32
33 bitTables = [3][]byte{tableLiteralLengths: llBitsTable[:], tableOffsets: nil, tableMatchLengths: mlBitsTable[:]}
34 )
35
36 type tableIndex uint8
37
38 const (
39
40 tableLiteralLengths tableIndex = 0
41 tableOffsets tableIndex = 1
42 tableMatchLengths tableIndex = 2
43
44 maxLiteralLengthSymbol = 35
45 maxOffsetLengthSymbol = 30
46 maxMatchLengthSymbol = 52
47 )
48
49
50 type baseOffset struct {
51 baseLine uint32
52 addBits uint8
53 }
54
55
56 func fillBase(dst []baseOffset, base uint32, bits ...uint8) {
57 if len(bits) != len(dst) {
58 panic(fmt.Sprintf("len(dst) (%d) != len(bits) (%d)", len(dst), len(bits)))
59 }
60 for i, bit := range bits {
61 if base > math.MaxInt32 {
62 panic("invalid decoding table, base overflows int32")
63 }
64
65 dst[i] = baseOffset{
66 baseLine: base,
67 addBits: bit,
68 }
69 base += 1 << bit
70 }
71 }
72
73 var predef sync.Once
74
75 func initPredefined() {
76 predef.Do(func() {
77
78 tmp := make([]baseOffset, 36)
79 for i := range tmp[:16] {
80 tmp[i] = baseOffset{
81 baseLine: uint32(i),
82 addBits: 0,
83 }
84 }
85 fillBase(tmp[16:], 16, 1, 1, 1, 1, 2, 2, 3, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)
86 symbolTableX[tableLiteralLengths] = tmp
87
88
89 tmp = make([]baseOffset, 53)
90 for i := range tmp[:32] {
91 tmp[i] = baseOffset{
92
93 baseLine: uint32(i) + 3,
94 addBits: 0,
95 }
96 }
97 fillBase(tmp[32:], 35, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)
98 symbolTableX[tableMatchLengths] = tmp
99
100
101 tmp = make([]baseOffset, maxOffsetBits+1)
102 tmp[1] = baseOffset{
103 baseLine: 1,
104 addBits: 1,
105 }
106 fillBase(tmp[2:], 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30)
107 symbolTableX[tableOffsets] = tmp
108
109
110
111 for i := range fsePredef[:] {
112 f := &fsePredef[i]
113 switch tableIndex(i) {
114 case tableLiteralLengths:
115
116 f.actualTableLog = 6
117 copy(f.norm[:], []int16{4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1,
118 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 1, 1, 1, 1, 1,
119 -1, -1, -1, -1})
120 f.symbolLen = 36
121 case tableOffsets:
122
123 f.actualTableLog = 5
124 copy(f.norm[:], []int16{
125 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
126 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1})
127 f.symbolLen = 29
128 case tableMatchLengths:
129
130 f.actualTableLog = 6
131 copy(f.norm[:], []int16{
132 1, 4, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
133 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
134 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1,
135 -1, -1, -1, -1, -1})
136 f.symbolLen = 53
137 }
138 if err := f.buildDtable(); err != nil {
139 panic(fmt.Errorf("building table %v: %v", tableIndex(i), err))
140 }
141 if err := f.transform(symbolTableX[i]); err != nil {
142 panic(fmt.Errorf("building table %v: %v", tableIndex(i), err))
143 }
144 f.preDefined = true
145
146
147 enc := &fsePredefEnc[i]
148 copy(enc.norm[:], f.norm[:])
149 enc.symbolLen = f.symbolLen
150 enc.actualTableLog = f.actualTableLog
151 if err := enc.buildCTable(); err != nil {
152 panic(fmt.Errorf("building encoding table %v: %v", tableIndex(i), err))
153 }
154 enc.setBits(bitTables[i])
155 enc.preDefined = true
156 }
157 })
158 }
159
View as plain text