mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 21:28:11 +09:00 
			
		
		
		
	* update github.com/blevesearch/bleve v2.0.2 -> v2.0.3 * github.com/denisenkom/go-mssqldb v0.9.0 -> v0.10.0 * github.com/editorconfig/editorconfig-core-go v2.4.1 -> v2.4.2 * github.com/go-chi/cors v1.1.1 -> v1.2.0 * github.com/go-git/go-billy v5.0.0 -> v5.1.0 * github.com/go-git/go-git v5.2.0 -> v5.3.0 * github.com/go-ldap/ldap v3.2.4 -> v3.3.0 * github.com/go-redis/redis v8.6.0 -> v8.8.2 * github.com/go-sql-driver/mysql v1.5.0 -> v1.6.0 * github.com/go-swagger/go-swagger v0.26.1 -> v0.27.0 * github.com/lib/pq v1.9.0 -> v1.10.1 * github.com/mattn/go-sqlite3 v1.14.6 -> v1.14.7 * github.com/go-testfixtures/testfixtures v3.5.0 -> v3.6.0 * github.com/issue9/identicon v1.0.1 -> v1.2.0 * github.com/klauspost/compress v1.11.8 -> v1.12.1 * github.com/mgechev/revive v1.0.3 -> v1.0.6 * github.com/microcosm-cc/bluemonday v1.0.7 -> v1.0.8 * github.com/niklasfasching/go-org v1.4.0 -> v1.5.0 * github.com/olivere/elastic v7.0.22 -> v7.0.24 * github.com/pelletier/go-toml v1.8.1 -> v1.9.0 * github.com/prometheus/client_golang v1.9.0 -> v1.10.0 * github.com/xanzy/go-gitlab v0.44.0 -> v0.48.0 * github.com/yuin/goldmark v1.3.3 -> v1.3.5 * github.com/6543/go-version v1.2.4 -> v1.3.1 * do github.com/lib/pq v1.10.0 -> v1.10.1 again ...
		
			
				
	
	
		
			313 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
			
		
		
	
	
			313 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
| package zstd
 | |
| 
 | |
| import (
 | |
| 	"errors"
 | |
| 	"fmt"
 | |
| 	"runtime"
 | |
| 	"strings"
 | |
| )
 | |
| 
 | |
| // EOption is an option for creating a encoder.
 | |
| type EOption func(*encoderOptions) error
 | |
| 
 | |
| // options retains accumulated state of multiple options.
 | |
| type encoderOptions struct {
 | |
| 	concurrent      int
 | |
| 	level           EncoderLevel
 | |
| 	single          *bool
 | |
| 	pad             int
 | |
| 	blockSize       int
 | |
| 	windowSize      int
 | |
| 	crc             bool
 | |
| 	fullZero        bool
 | |
| 	noEntropy       bool
 | |
| 	allLitEntropy   bool
 | |
| 	customWindow    bool
 | |
| 	customALEntropy bool
 | |
| 	lowMem          bool
 | |
| 	dict            *dict
 | |
| }
 | |
| 
 | |
| func (o *encoderOptions) setDefault() {
 | |
| 	*o = encoderOptions{
 | |
| 		concurrent:    runtime.GOMAXPROCS(0),
 | |
| 		crc:           true,
 | |
| 		single:        nil,
 | |
| 		blockSize:     1 << 16,
 | |
| 		windowSize:    8 << 20,
 | |
| 		level:         SpeedDefault,
 | |
| 		allLitEntropy: true,
 | |
| 		lowMem:        false,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // encoder returns an encoder with the selected options.
 | |
| func (o encoderOptions) encoder() encoder {
 | |
| 	switch o.level {
 | |
| 	case SpeedFastest:
 | |
| 		if o.dict != nil {
 | |
| 			return &fastEncoderDict{fastEncoder: fastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize), lowMem: o.lowMem}}}
 | |
| 		}
 | |
| 		return &fastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize), lowMem: o.lowMem}}
 | |
| 
 | |
| 	case SpeedDefault:
 | |
| 		if o.dict != nil {
 | |
| 			return &doubleFastEncoderDict{fastEncoderDict: fastEncoderDict{fastEncoder: fastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize), lowMem: o.lowMem}}}}
 | |
| 		}
 | |
| 		return &doubleFastEncoder{fastEncoder: fastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize), lowMem: o.lowMem}}}
 | |
| 	case SpeedBetterCompression:
 | |
| 		if o.dict != nil {
 | |
| 			return &betterFastEncoderDict{betterFastEncoder: betterFastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize), lowMem: o.lowMem}}}
 | |
| 		}
 | |
| 		return &betterFastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize), lowMem: o.lowMem}}
 | |
| 	case SpeedBestCompression:
 | |
| 		return &bestFastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize), lowMem: o.lowMem}}
 | |
| 	}
 | |
| 	panic("unknown compression level")
 | |
| }
 | |
| 
 | |
| // WithEncoderCRC will add CRC value to output.
 | |
| // Output will be 4 bytes larger.
 | |
| func WithEncoderCRC(b bool) EOption {
 | |
| 	return func(o *encoderOptions) error { o.crc = b; return nil }
 | |
| }
 | |
| 
 | |
| // WithEncoderConcurrency will set the concurrency,
 | |
| // meaning the maximum number of encoders to run concurrently.
 | |
| // The value supplied must be at least 1.
 | |
| // By default this will be set to GOMAXPROCS.
 | |
| func WithEncoderConcurrency(n int) EOption {
 | |
| 	return func(o *encoderOptions) error {
 | |
| 		if n <= 0 {
 | |
| 			return fmt.Errorf("concurrency must be at least 1")
 | |
| 		}
 | |
| 		o.concurrent = n
 | |
| 		return nil
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // WithWindowSize will set the maximum allowed back-reference distance.
 | |
| // The value must be a power of two between MinWindowSize and MaxWindowSize.
 | |
| // A larger value will enable better compression but allocate more memory and,
 | |
| // for above-default values, take considerably longer.
 | |
| // The default value is determined by the compression level.
 | |
| func WithWindowSize(n int) EOption {
 | |
| 	return func(o *encoderOptions) error {
 | |
| 		switch {
 | |
| 		case n < MinWindowSize:
 | |
| 			return fmt.Errorf("window size must be at least %d", MinWindowSize)
 | |
| 		case n > MaxWindowSize:
 | |
| 			return fmt.Errorf("window size must be at most %d", MaxWindowSize)
 | |
| 		case (n & (n - 1)) != 0:
 | |
| 			return errors.New("window size must be a power of 2")
 | |
| 		}
 | |
| 
 | |
| 		o.windowSize = n
 | |
| 		o.customWindow = true
 | |
| 		if o.blockSize > o.windowSize {
 | |
| 			o.blockSize = o.windowSize
 | |
| 		}
 | |
| 		return nil
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // WithEncoderPadding will add padding to all output so the size will be a multiple of n.
 | |
| // This can be used to obfuscate the exact output size or make blocks of a certain size.
 | |
| // The contents will be a skippable frame, so it will be invisible by the decoder.
 | |
| // n must be > 0 and <= 1GB, 1<<30 bytes.
 | |
| // The padded area will be filled with data from crypto/rand.Reader.
 | |
| // If `EncodeAll` is used with data already in the destination, the total size will be multiple of this.
 | |
| func WithEncoderPadding(n int) EOption {
 | |
| 	return func(o *encoderOptions) error {
 | |
| 		if n <= 0 {
 | |
| 			return fmt.Errorf("padding must be at least 1")
 | |
| 		}
 | |
| 		// No need to waste our time.
 | |
| 		if n == 1 {
 | |
| 			o.pad = 0
 | |
| 		}
 | |
| 		if n > 1<<30 {
 | |
| 			return fmt.Errorf("padding must less than 1GB (1<<30 bytes) ")
 | |
| 		}
 | |
| 		o.pad = n
 | |
| 		return nil
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // EncoderLevel predefines encoder compression levels.
 | |
| // Only use the constants made available, since the actual mapping
 | |
| // of these values are very likely to change and your compression could change
 | |
| // unpredictably when upgrading the library.
 | |
| type EncoderLevel int
 | |
| 
 | |
| const (
 | |
| 	speedNotSet EncoderLevel = iota
 | |
| 
 | |
| 	// SpeedFastest will choose the fastest reasonable compression.
 | |
| 	// This is roughly equivalent to the fastest Zstandard mode.
 | |
| 	SpeedFastest
 | |
| 
 | |
| 	// SpeedDefault is the default "pretty fast" compression option.
 | |
| 	// This is roughly equivalent to the default Zstandard mode (level 3).
 | |
| 	SpeedDefault
 | |
| 
 | |
| 	// SpeedBetterCompression will yield better compression than the default.
 | |
| 	// Currently it is about zstd level 7-8 with ~ 2x-3x the default CPU usage.
 | |
| 	// By using this, notice that CPU usage may go up in the future.
 | |
| 	SpeedBetterCompression
 | |
| 
 | |
| 	// SpeedBestCompression will choose the best available compression option.
 | |
| 	// This will offer the best compression no matter the CPU cost.
 | |
| 	SpeedBestCompression
 | |
| 
 | |
| 	// speedLast should be kept as the last actual compression option.
 | |
| 	// The is not for external usage, but is used to keep track of the valid options.
 | |
| 	speedLast
 | |
| )
 | |
| 
 | |
| // EncoderLevelFromString will convert a string representation of an encoding level back
 | |
| // to a compression level. The compare is not case sensitive.
 | |
| // If the string wasn't recognized, (false, SpeedDefault) will be returned.
 | |
| func EncoderLevelFromString(s string) (bool, EncoderLevel) {
 | |
| 	for l := speedNotSet + 1; l < speedLast; l++ {
 | |
| 		if strings.EqualFold(s, l.String()) {
 | |
| 			return true, l
 | |
| 		}
 | |
| 	}
 | |
| 	return false, SpeedDefault
 | |
| }
 | |
| 
 | |
| // EncoderLevelFromZstd will return an encoder level that closest matches the compression
 | |
| // ratio of a specific zstd compression level.
 | |
| // Many input values will provide the same compression level.
 | |
| func EncoderLevelFromZstd(level int) EncoderLevel {
 | |
| 	switch {
 | |
| 	case level < 3:
 | |
| 		return SpeedFastest
 | |
| 	case level >= 3 && level < 6:
 | |
| 		return SpeedDefault
 | |
| 	case level >= 6 && level < 10:
 | |
| 		return SpeedBetterCompression
 | |
| 	case level >= 10:
 | |
| 		return SpeedBetterCompression
 | |
| 	}
 | |
| 	return SpeedDefault
 | |
| }
 | |
| 
 | |
| // String provides a string representation of the compression level.
 | |
| func (e EncoderLevel) String() string {
 | |
| 	switch e {
 | |
| 	case SpeedFastest:
 | |
| 		return "fastest"
 | |
| 	case SpeedDefault:
 | |
| 		return "default"
 | |
| 	case SpeedBetterCompression:
 | |
| 		return "better"
 | |
| 	case SpeedBestCompression:
 | |
| 		return "best"
 | |
| 	default:
 | |
| 		return "invalid"
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // WithEncoderLevel specifies a predefined compression level.
 | |
| func WithEncoderLevel(l EncoderLevel) EOption {
 | |
| 	return func(o *encoderOptions) error {
 | |
| 		switch {
 | |
| 		case l <= speedNotSet || l >= speedLast:
 | |
| 			return fmt.Errorf("unknown encoder level")
 | |
| 		}
 | |
| 		o.level = l
 | |
| 		if !o.customWindow {
 | |
| 			switch o.level {
 | |
| 			case SpeedFastest:
 | |
| 				o.windowSize = 4 << 20
 | |
| 			case SpeedDefault:
 | |
| 				o.windowSize = 8 << 20
 | |
| 			case SpeedBetterCompression:
 | |
| 				o.windowSize = 16 << 20
 | |
| 			case SpeedBestCompression:
 | |
| 				o.windowSize = 32 << 20
 | |
| 			}
 | |
| 		}
 | |
| 		if !o.customALEntropy {
 | |
| 			o.allLitEntropy = l > SpeedFastest
 | |
| 		}
 | |
| 
 | |
| 		return nil
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // WithZeroFrames will encode 0 length input as full frames.
 | |
| // This can be needed for compatibility with zstandard usage,
 | |
| // but is not needed for this package.
 | |
| func WithZeroFrames(b bool) EOption {
 | |
| 	return func(o *encoderOptions) error {
 | |
| 		o.fullZero = b
 | |
| 		return nil
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // WithAllLitEntropyCompression will apply entropy compression if no matches are found.
 | |
| // Disabling this will skip incompressible data faster, but in cases with no matches but
 | |
| // skewed character distribution compression is lost.
 | |
| // Default value depends on the compression level selected.
 | |
| func WithAllLitEntropyCompression(b bool) EOption {
 | |
| 	return func(o *encoderOptions) error {
 | |
| 		o.customALEntropy = true
 | |
| 		o.allLitEntropy = b
 | |
| 		return nil
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // WithNoEntropyCompression will always skip entropy compression of literals.
 | |
| // This can be useful if content has matches, but unlikely to benefit from entropy
 | |
| // compression. Usually the slight speed improvement is not worth enabling this.
 | |
| func WithNoEntropyCompression(b bool) EOption {
 | |
| 	return func(o *encoderOptions) error {
 | |
| 		o.noEntropy = b
 | |
| 		return nil
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // WithSingleSegment will set the "single segment" flag when EncodeAll is used.
 | |
| // If this flag is set, data must be regenerated within a single continuous memory segment.
 | |
| // In this case, Window_Descriptor byte is skipped, but Frame_Content_Size is necessarily present.
 | |
| // As a consequence, the decoder must allocate a memory segment of size equal or larger than size of your content.
 | |
| // In order to preserve the decoder from unreasonable memory requirements,
 | |
| // a decoder is allowed to reject a compressed frame which requests a memory size beyond decoder's authorized range.
 | |
| // For broader compatibility, decoders are recommended to support memory sizes of at least 8 MB.
 | |
| // This is only a recommendation, each decoder is free to support higher or lower limits, depending on local limitations.
 | |
| // If this is not specified, block encodes will automatically choose this based on the input size.
 | |
| // This setting has no effect on streamed encodes.
 | |
| func WithSingleSegment(b bool) EOption {
 | |
| 	return func(o *encoderOptions) error {
 | |
| 		o.single = &b
 | |
| 		return nil
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // WithLowerEncoderMem will trade in some memory cases trade less memory usage for
 | |
| // slower encoding speed.
 | |
| // This will not change the window size which is the primary function for reducing
 | |
| // memory usage. See WithWindowSize.
 | |
| func WithLowerEncoderMem(b bool) EOption {
 | |
| 	return func(o *encoderOptions) error {
 | |
| 		o.lowMem = b
 | |
| 		return nil
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // WithEncoderDict allows to register a dictionary that will be used for the encode.
 | |
| // The encoder *may* choose to use no dictionary instead for certain payloads.
 | |
| func WithEncoderDict(dict []byte) EOption {
 | |
| 	return func(o *encoderOptions) error {
 | |
| 		d, err := loadDict(dict)
 | |
| 		if err != nil {
 | |
| 			return err
 | |
| 		}
 | |
| 		o.dict = d
 | |
| 		return nil
 | |
| 	}
 | |
| }
 |