Files
kopia/snapshot/policy/compression_policy.go
Prasad Ghangal 3bf947d746 feat(repository): Metadata compression config support for directory and indirect content (#4080)
* Configure compressor for k and x prefixed content

Adds metadata compression setting to policy
Add support to configure compressor for k and x prefixed content
Set zstd-fastest as the default compressor for metadata in the policy
Adds support to set and show metadata compression to kopia policy commands
Adds metadata compression config to dir writer

Signed-off-by: Prasad Ghangal <prasad.ganghal@veeam.com>

* Pass concatenate options with ConcatenateOptions struct

Signed-off-by: Prasad Ghangal <prasad.ganghal@veeam.com>

* Move content compression handling to caller

Signed-off-by: Prasad Ghangal <prasad.ganghal@veeam.com>

* Move handling manifests to manifest pkg

Signed-off-by: Prasad Ghangal <prasad.ganghal@veeam.com>

* Correct const in server_test

Signed-off-by: Prasad Ghangal <prasad.ganghal@veeam.com>

* Remove unnecessary whitespace

Signed-off-by: Prasad Ghangal <prasad.ganghal@veeam.com>

* Disable metadata compression for < V2 format

Signed-off-by: Prasad Ghangal <prasad.ganghal@veeam.com>

---------

Signed-off-by: Prasad Ghangal <prasad.ganghal@veeam.com>
2024-10-23 23:28:23 -07:00

98 lines
3.5 KiB
Go

package policy
import (
"path/filepath"
"sort"
"github.com/kopia/kopia/fs"
"github.com/kopia/kopia/repo/compression"
"github.com/kopia/kopia/snapshot"
)
// CompressionPolicy specifies compression policy.
type CompressionPolicy struct {
CompressorName compression.Name `json:"compressorName,omitempty"`
OnlyCompress []string `json:"onlyCompress,omitempty"`
NoParentOnlyCompress bool `json:"noParentOnlyCompress,omitempty"`
NeverCompress []string `json:"neverCompress,omitempty"`
NoParentNeverCompress bool `json:"noParentNeverCompress,omitempty"`
MinSize int64 `json:"minSize,omitempty"`
MaxSize int64 `json:"maxSize,omitempty"`
}
// MetadataCompressionPolicy specifies compression policy for metadata.
type MetadataCompressionPolicy struct {
CompressorName compression.Name `json:"compressorName,omitempty"`
}
// CompressionPolicyDefinition specifies which policy definition provided the value of a particular field.
type CompressionPolicyDefinition struct {
CompressorName snapshot.SourceInfo `json:"compressorName,omitempty"`
OnlyCompress snapshot.SourceInfo `json:"onlyCompress,omitempty"`
NeverCompress snapshot.SourceInfo `json:"neverCompress,omitempty"`
MinSize snapshot.SourceInfo `json:"minSize,omitempty"`
MaxSize snapshot.SourceInfo `json:"maxSize,omitempty"`
}
// MetadataCompressionPolicyDefinition specifies which policy definition provided the value of a particular field.
type MetadataCompressionPolicyDefinition struct {
CompressorName snapshot.SourceInfo `json:"compressorName,omitempty"`
}
// CompressorForFile returns compression name to be used for compressing a given file according to policy, using attributes such as name or size.
func (p *CompressionPolicy) CompressorForFile(e fs.Entry) compression.Name {
ext := filepath.Ext(e.Name())
size := e.Size()
if p.CompressorName == "none" {
return ""
}
if v := p.MinSize; v > 0 && size < v {
return ""
}
if v := p.MaxSize; v > 0 && size > v {
return ""
}
if len(p.OnlyCompress) > 0 && isInSortedSlice(ext, p.OnlyCompress) {
return p.CompressorName
}
if isInSortedSlice(ext, p.NeverCompress) {
return ""
}
return p.CompressorName
}
// Merge applies default values from the provided policy.
func (p *CompressionPolicy) Merge(src CompressionPolicy, def *CompressionPolicyDefinition, si snapshot.SourceInfo) {
mergeCompressionName(&p.CompressorName, src.CompressorName, &def.CompressorName, si)
mergeInt64(&p.MinSize, src.MinSize, &def.MinSize, si)
mergeInt64(&p.MaxSize, src.MaxSize, &def.MaxSize, si)
mergeStrings(&p.OnlyCompress, &p.NoParentOnlyCompress, src.OnlyCompress, src.NoParentOnlyCompress, &def.OnlyCompress, si)
mergeStrings(&p.NeverCompress, &p.NoParentNeverCompress, src.NeverCompress, src.NoParentNeverCompress, &def.NeverCompress, si)
}
// Merge applies default values from the provided policy.
func (p *MetadataCompressionPolicy) Merge(src MetadataCompressionPolicy, def *MetadataCompressionPolicyDefinition, si snapshot.SourceInfo) {
mergeCompressionName(&p.CompressorName, src.CompressorName, &def.CompressorName, si)
}
// MetadataCompressor returns compression name to be used for according to policy.
func (p *MetadataCompressionPolicy) MetadataCompressor() compression.Name {
if p.CompressorName == "none" {
return ""
}
return p.CompressorName
}
func isInSortedSlice(s string, slice []string) bool {
x := sort.SearchStrings(slice, s)
return x < len(slice) && slice[x] == s
}