options.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. package lz4
  2. import (
  3. "fmt"
  4. "runtime"
  5. "sync"
  6. )
  7. //go:generate go run golang.org/x/tools/cmd/stringer -type=BlockSize,CompressionLevel -output options_gen.go
  8. // Option defines the parameters to setup an LZ4 Writer or Reader.
  9. type Option func(*_Writer) error
  10. // Default options.
  11. var (
  12. defaultBlockSizeOption = BlockSizeOption(Block4Mb)
  13. defaultChecksumOption = ChecksumOption(true)
  14. defaultConcurrency = ConcurrencyOption(1)
  15. )
  16. const (
  17. Block64Kb BlockSize = 1 << (16 + iota*2)
  18. Block256Kb
  19. Block1Mb
  20. Block4Mb
  21. )
  22. var (
  23. blockPool64K = sync.Pool{New: func() interface{} { return make([]byte, Block64Kb) }}
  24. blockPool256K = sync.Pool{New: func() interface{} { return make([]byte, Block256Kb) }}
  25. blockPool1M = sync.Pool{New: func() interface{} { return make([]byte, Block1Mb) }}
  26. blockPool4M = sync.Pool{New: func() interface{} { return make([]byte, Block4Mb) }}
  27. )
  28. // BlockSizeIndex defines the size of the blocks to be compressed.
  29. type BlockSize uint32
  30. func (b BlockSize) isValid() bool {
  31. return b.index() > 0
  32. }
  33. func (b BlockSize) index() BlockSizeIndex {
  34. switch b {
  35. case Block64Kb:
  36. return 4
  37. case Block256Kb:
  38. return 5
  39. case Block1Mb:
  40. return 6
  41. case Block4Mb:
  42. return 7
  43. }
  44. return 0
  45. }
  46. type BlockSizeIndex uint8
  47. func (b BlockSizeIndex) get() []byte {
  48. var buf interface{}
  49. switch b {
  50. case 4:
  51. buf = blockPool64K.Get()
  52. case 5:
  53. buf = blockPool256K.Get()
  54. case 6:
  55. buf = blockPool1M.Get()
  56. case 7:
  57. buf = blockPool4M.Get()
  58. }
  59. return buf.([]byte)
  60. }
  61. func (b BlockSizeIndex) put(buf []byte) {
  62. switch b {
  63. case 4:
  64. blockPool64K.Put(buf)
  65. case 5:
  66. blockPool256K.Put(buf)
  67. case 6:
  68. blockPool1M.Put(buf)
  69. case 7:
  70. blockPool4M.Put(buf)
  71. }
  72. }
  73. // BlockSizeOption defines the maximum size of compressed blocks (default=Block4Mb).
  74. func BlockSizeOption(size BlockSize) Option {
  75. return func(w *_Writer) error {
  76. if !size.isValid() {
  77. return fmt.Errorf("lz4: invalid block size %d", size)
  78. }
  79. w.frame.Descriptor.Flags.BlockSizeIndexSet(size.index())
  80. return nil
  81. }
  82. }
  83. // BlockChecksumOption enables or disables block checksum (default=false).
  84. func BlockChecksumOption(flag bool) Option {
  85. return func(w *_Writer) error {
  86. w.frame.Descriptor.Flags.BlockChecksumSet(flag)
  87. return nil
  88. }
  89. }
  90. // ChecksumOption enables/disables all blocks checksum (default=true).
  91. func ChecksumOption(flag bool) Option {
  92. return func(w *_Writer) error {
  93. w.frame.Descriptor.Flags.ContentChecksumSet(flag)
  94. return nil
  95. }
  96. }
  97. // SizeOption sets the size of the original uncompressed data (default=0).
  98. func SizeOption(size uint64) Option {
  99. return func(w *_Writer) error {
  100. w.frame.Descriptor.Flags.SizeSet(size > 0)
  101. w.frame.Descriptor.ContentSize = size
  102. return nil
  103. }
  104. }
  105. // ConcurrencyOption sets the number of go routines used for compression.
  106. // If n<0, then the output of runtime.GOMAXPROCS(0) is used.
  107. func ConcurrencyOption(n int) Option {
  108. return func(w *_Writer) error {
  109. switch n {
  110. case 0, 1:
  111. default:
  112. if n < 0 {
  113. n = runtime.GOMAXPROCS(0)
  114. }
  115. }
  116. w.num = n
  117. return nil
  118. }
  119. }
  120. // CompressionLevel defines the level of compression to use. The higher the better, but slower, compression.
  121. type CompressionLevel uint32
  122. const (
  123. Fast CompressionLevel = 0
  124. Level1 CompressionLevel = 1 << (8 + iota)
  125. Level2
  126. Level3
  127. Level4
  128. Level5
  129. Level6
  130. Level7
  131. Level8
  132. Level9
  133. )
  134. // CompressionLevelOption defines the compression level (default=Fast).
  135. func CompressionLevelOption(level CompressionLevel) Option {
  136. return func(w *_Writer) error {
  137. switch level {
  138. case Fast, Level1, Level2, Level3, Level4, Level5, Level6, Level7, Level8, Level9:
  139. default:
  140. return fmt.Errorf("lz4: invalid compression level %d", level)
  141. }
  142. w.level = level
  143. return nil
  144. }
  145. }