dict.go 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. // Copyright (c) 2022+ Klaus Post. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package s2
  5. import (
  6. "bytes"
  7. "encoding/binary"
  8. "sync"
  9. )
  10. const (
  11. // MinDictSize is the minimum dictionary size when repeat has been read.
  12. MinDictSize = 16
  13. // MaxDictSize is the maximum dictionary size when repeat has been read.
  14. MaxDictSize = 65536
  15. // MaxDictSrcOffset is the maximum offset where a dictionary entry can start.
  16. MaxDictSrcOffset = 65535
  17. )
  18. // Dict contains a dictionary that can be used for encoding and decoding s2
  19. type Dict struct {
  20. dict []byte
  21. repeat int // Repeat as index of dict
  22. fast, better, best sync.Once
  23. fastTable *[1 << 14]uint16
  24. betterTableShort *[1 << 14]uint16
  25. betterTableLong *[1 << 17]uint16
  26. bestTableShort *[1 << 16]uint32
  27. bestTableLong *[1 << 19]uint32
  28. }
  29. // NewDict will read a dictionary.
  30. // It will return nil if the dictionary is invalid.
  31. func NewDict(dict []byte) *Dict {
  32. if len(dict) == 0 {
  33. return nil
  34. }
  35. var d Dict
  36. // Repeat is the first value of the dict
  37. r, n := binary.Uvarint(dict)
  38. if n <= 0 {
  39. return nil
  40. }
  41. dict = dict[n:]
  42. d.dict = dict
  43. if cap(d.dict) < len(d.dict)+16 {
  44. d.dict = append(make([]byte, 0, len(d.dict)+16), d.dict...)
  45. }
  46. if len(dict) < MinDictSize || len(dict) > MaxDictSize {
  47. return nil
  48. }
  49. d.repeat = int(r)
  50. if d.repeat > len(dict) {
  51. return nil
  52. }
  53. return &d
  54. }
  55. // Bytes will return a serialized version of the dictionary.
  56. // The output can be sent to NewDict.
  57. func (d *Dict) Bytes() []byte {
  58. dst := make([]byte, binary.MaxVarintLen16+len(d.dict))
  59. return append(dst[:binary.PutUvarint(dst, uint64(d.repeat))], d.dict...)
  60. }
  61. // MakeDict will create a dictionary.
  62. // 'data' must be at least MinDictSize.
  63. // If data is longer than MaxDictSize only the last MaxDictSize bytes will be used.
  64. // If searchStart is set the start repeat value will be set to the last
  65. // match of this content.
  66. // If no matches are found, it will attempt to find shorter matches.
  67. // This content should match the typical start of a block.
  68. // If at least 4 bytes cannot be matched, repeat is set to start of block.
  69. func MakeDict(data []byte, searchStart []byte) *Dict {
  70. if len(data) == 0 {
  71. return nil
  72. }
  73. if len(data) > MaxDictSize {
  74. data = data[len(data)-MaxDictSize:]
  75. }
  76. var d Dict
  77. dict := data
  78. d.dict = dict
  79. if cap(d.dict) < len(d.dict)+16 {
  80. d.dict = append(make([]byte, 0, len(d.dict)+16), d.dict...)
  81. }
  82. if len(dict) < MinDictSize {
  83. return nil
  84. }
  85. // Find the longest match possible, last entry if multiple.
  86. for s := len(searchStart); s > 4; s-- {
  87. if idx := bytes.LastIndex(data, searchStart[:s]); idx >= 0 && idx <= len(data)-8 {
  88. d.repeat = idx
  89. break
  90. }
  91. }
  92. return &d
  93. }
  94. // MakeDictManual will create a dictionary.
  95. // 'data' must be at least MinDictSize and less than or equal to MaxDictSize.
  96. // A manual first repeat index into data must be provided.
  97. // It must be less than len(data)-8.
  98. func MakeDictManual(data []byte, firstIdx uint16) *Dict {
  99. if len(data) < MinDictSize || int(firstIdx) >= len(data)-8 || len(data) > MaxDictSize {
  100. return nil
  101. }
  102. var d Dict
  103. dict := data
  104. d.dict = dict
  105. if cap(d.dict) < len(d.dict)+16 {
  106. d.dict = append(make([]byte, 0, len(d.dict)+16), d.dict...)
  107. }
  108. d.repeat = int(firstIdx)
  109. return &d
  110. }
  111. // Encode returns the encoded form of src. The returned slice may be a sub-
  112. // slice of dst if dst was large enough to hold the entire encoded block.
  113. // Otherwise, a newly allocated slice will be returned.
  114. //
  115. // The dst and src must not overlap. It is valid to pass a nil dst.
  116. //
  117. // The blocks will require the same amount of memory to decode as encoding,
  118. // and does not make for concurrent decoding.
  119. // Also note that blocks do not contain CRC information, so corruption may be undetected.
  120. //
  121. // If you need to encode larger amounts of data, consider using
  122. // the streaming interface which gives all of these features.
  123. func (d *Dict) Encode(dst, src []byte) []byte {
  124. if n := MaxEncodedLen(len(src)); n < 0 {
  125. panic(ErrTooLarge)
  126. } else if cap(dst) < n {
  127. dst = make([]byte, n)
  128. } else {
  129. dst = dst[:n]
  130. }
  131. // The block starts with the varint-encoded length of the decompressed bytes.
  132. dstP := binary.PutUvarint(dst, uint64(len(src)))
  133. if len(src) == 0 {
  134. return dst[:dstP]
  135. }
  136. if len(src) < minNonLiteralBlockSize {
  137. dstP += emitLiteral(dst[dstP:], src)
  138. return dst[:dstP]
  139. }
  140. n := encodeBlockDictGo(dst[dstP:], src, d)
  141. if n > 0 {
  142. dstP += n
  143. return dst[:dstP]
  144. }
  145. // Not compressible
  146. dstP += emitLiteral(dst[dstP:], src)
  147. return dst[:dstP]
  148. }
  149. // EncodeBetter returns the encoded form of src. The returned slice may be a sub-
  150. // slice of dst if dst was large enough to hold the entire encoded block.
  151. // Otherwise, a newly allocated slice will be returned.
  152. //
  153. // EncodeBetter compresses better than Encode but typically with a
  154. // 10-40% speed decrease on both compression and decompression.
  155. //
  156. // The dst and src must not overlap. It is valid to pass a nil dst.
  157. //
  158. // The blocks will require the same amount of memory to decode as encoding,
  159. // and does not make for concurrent decoding.
  160. // Also note that blocks do not contain CRC information, so corruption may be undetected.
  161. //
  162. // If you need to encode larger amounts of data, consider using
  163. // the streaming interface which gives all of these features.
  164. func (d *Dict) EncodeBetter(dst, src []byte) []byte {
  165. if n := MaxEncodedLen(len(src)); n < 0 {
  166. panic(ErrTooLarge)
  167. } else if len(dst) < n {
  168. dst = make([]byte, n)
  169. }
  170. // The block starts with the varint-encoded length of the decompressed bytes.
  171. dstP := binary.PutUvarint(dst, uint64(len(src)))
  172. if len(src) == 0 {
  173. return dst[:dstP]
  174. }
  175. if len(src) < minNonLiteralBlockSize {
  176. dstP += emitLiteral(dst[dstP:], src)
  177. return dst[:dstP]
  178. }
  179. n := encodeBlockBetterDict(dst[dstP:], src, d)
  180. if n > 0 {
  181. dstP += n
  182. return dst[:dstP]
  183. }
  184. // Not compressible
  185. dstP += emitLiteral(dst[dstP:], src)
  186. return dst[:dstP]
  187. }
  188. // EncodeBest returns the encoded form of src. The returned slice may be a sub-
  189. // slice of dst if dst was large enough to hold the entire encoded block.
  190. // Otherwise, a newly allocated slice will be returned.
  191. //
  192. // EncodeBest compresses as good as reasonably possible but with a
  193. // big speed decrease.
  194. //
  195. // The dst and src must not overlap. It is valid to pass a nil dst.
  196. //
  197. // The blocks will require the same amount of memory to decode as encoding,
  198. // and does not make for concurrent decoding.
  199. // Also note that blocks do not contain CRC information, so corruption may be undetected.
  200. //
  201. // If you need to encode larger amounts of data, consider using
  202. // the streaming interface which gives all of these features.
  203. func (d *Dict) EncodeBest(dst, src []byte) []byte {
  204. if n := MaxEncodedLen(len(src)); n < 0 {
  205. panic(ErrTooLarge)
  206. } else if len(dst) < n {
  207. dst = make([]byte, n)
  208. }
  209. // The block starts with the varint-encoded length of the decompressed bytes.
  210. dstP := binary.PutUvarint(dst, uint64(len(src)))
  211. if len(src) == 0 {
  212. return dst[:dstP]
  213. }
  214. if len(src) < minNonLiteralBlockSize {
  215. dstP += emitLiteral(dst[dstP:], src)
  216. return dst[:dstP]
  217. }
  218. n := encodeBlockBest(dst[dstP:], src, d)
  219. if n > 0 {
  220. dstP += n
  221. return dst[:dstP]
  222. }
  223. // Not compressible
  224. dstP += emitLiteral(dst[dstP:], src)
  225. return dst[:dstP]
  226. }
  227. // Decode returns the decoded form of src. The returned slice may be a sub-
  228. // slice of dst if dst was large enough to hold the entire decoded block.
  229. // Otherwise, a newly allocated slice will be returned.
  230. //
  231. // The dst and src must not overlap. It is valid to pass a nil dst.
  232. func (d *Dict) Decode(dst, src []byte) ([]byte, error) {
  233. dLen, s, err := decodedLen(src)
  234. if err != nil {
  235. return nil, err
  236. }
  237. if dLen <= cap(dst) {
  238. dst = dst[:dLen]
  239. } else {
  240. dst = make([]byte, dLen)
  241. }
  242. if s2DecodeDict(dst, src[s:], d) != 0 {
  243. return nil, ErrCorrupt
  244. }
  245. return dst, nil
  246. }
  247. func (d *Dict) initFast() {
  248. d.fast.Do(func() {
  249. const (
  250. tableBits = 14
  251. maxTableSize = 1 << tableBits
  252. )
  253. var table [maxTableSize]uint16
  254. // We stop so any entry of length 8 can always be read.
  255. for i := 0; i < len(d.dict)-8-2; i += 3 {
  256. x0 := load64(d.dict, i)
  257. h0 := hash6(x0, tableBits)
  258. h1 := hash6(x0>>8, tableBits)
  259. h2 := hash6(x0>>16, tableBits)
  260. table[h0] = uint16(i)
  261. table[h1] = uint16(i + 1)
  262. table[h2] = uint16(i + 2)
  263. }
  264. d.fastTable = &table
  265. })
  266. }
  267. func (d *Dict) initBetter() {
  268. d.better.Do(func() {
  269. const (
  270. // Long hash matches.
  271. lTableBits = 17
  272. maxLTableSize = 1 << lTableBits
  273. // Short hash matches.
  274. sTableBits = 14
  275. maxSTableSize = 1 << sTableBits
  276. )
  277. var lTable [maxLTableSize]uint16
  278. var sTable [maxSTableSize]uint16
  279. // We stop so any entry of length 8 can always be read.
  280. for i := 0; i < len(d.dict)-8; i++ {
  281. cv := load64(d.dict, i)
  282. lTable[hash7(cv, lTableBits)] = uint16(i)
  283. sTable[hash4(cv, sTableBits)] = uint16(i)
  284. }
  285. d.betterTableShort = &sTable
  286. d.betterTableLong = &lTable
  287. })
  288. }
  289. func (d *Dict) initBest() {
  290. d.best.Do(func() {
  291. const (
  292. // Long hash matches.
  293. lTableBits = 19
  294. maxLTableSize = 1 << lTableBits
  295. // Short hash matches.
  296. sTableBits = 16
  297. maxSTableSize = 1 << sTableBits
  298. )
  299. var lTable [maxLTableSize]uint32
  300. var sTable [maxSTableSize]uint32
  301. // We stop so any entry of length 8 can always be read.
  302. for i := 0; i < len(d.dict)-8; i++ {
  303. cv := load64(d.dict, i)
  304. hashL := hash8(cv, lTableBits)
  305. hashS := hash4(cv, sTableBits)
  306. candidateL := lTable[hashL]
  307. candidateS := sTable[hashS]
  308. lTable[hashL] = uint32(i) | candidateL<<16
  309. sTable[hashS] = uint32(i) | candidateS<<16
  310. }
  311. d.bestTableShort = &sTable
  312. d.bestTableLong = &lTable
  313. })
  314. }