Skip to content

Commit 9ba5661

Browse files
committed
db: introduce DBCompressionSettings
This commit introduces `DBCompressionSettings` which contains a `sstable.CompressionProfile` for each level. We define three standard levels (fastest, balanced, good).
1 parent a4a4349 commit 9ba5661

File tree

4 files changed

+120
-9
lines changed

4 files changed

+120
-9
lines changed

metamorphic/options.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -811,6 +811,20 @@ func RandomOptions(
811811
}
812812
opts.Levels[0] = lopts
813813

814+
// Sometimes apply DBCompressionSettings.
815+
if rng.IntN(2) == 0 {
816+
csList := []pebble.DBCompressionSettings{
817+
pebble.DBCompressionNone,
818+
pebble.DBCompressionFastest,
819+
pebble.DBCompressionBalanced,
820+
pebble.DBCompressionGood,
821+
}
822+
cs := csList[rng.IntN(len(csList))]
823+
opts.ApplyCompressionSettings(func() pebble.DBCompressionSettings {
824+
return cs
825+
})
826+
}
827+
814828
// Explicitly disable disk-backed FS's for the random configurations. The
815829
// single standard test configuration that uses a disk-backed FS is
816830
// sufficient.

options.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,8 @@ type LevelOptions struct {
405405
//
406406
// The default value is Snappy for L0, or the function from the previous level
407407
// for all other levels.
408+
//
409+
// ApplyCompressionSettings can be used to initialize this field for all levels.
408410
Compression func() *sstable.CompressionProfile
409411

410412
// FilterPolicy defines a filter algorithm (such as a Bloom filter) that can
@@ -1273,6 +1275,54 @@ func DebugCheckLevels(db *DB) error {
12731275
return db.CheckLevels(nil)
12741276
}
12751277

1278+
// DBCompressionSettings contains compression settings for the entire store. It
1279+
// defines compression profiles for each LSM level.
1280+
type DBCompressionSettings struct {
1281+
Name string
1282+
Levels [manifest.NumLevels]*block.CompressionProfile
1283+
}
1284+
1285+
// Predefined compression settings.
1286+
var (
1287+
DBCompressionNone = UniformDBCompressionSettings("NoCompression", block.NoCompression)
1288+
DBCompressionFastest = UniformDBCompressionSettings("Fastest", block.FastestCompression)
1289+
DBCompressionBalanced = func() DBCompressionSettings {
1290+
profile := UniformDBCompressionSettings("Balanced", block.FastestCompression)
1291+
profile.Levels[manifest.NumLevels-2] = block.FastCompression // Zstd1 for value blocks.
1292+
profile.Levels[manifest.NumLevels-1] = block.BalancedCompression // Zstd1 for data blocks, Zstd3 for value blocks.
1293+
return profile
1294+
}()
1295+
DBCompressionGood = func() DBCompressionSettings {
1296+
profile := UniformDBCompressionSettings("Good", block.FastestCompression)
1297+
profile.Levels[manifest.NumLevels-2] = block.BalancedCompression // Zstd1 for data blocks, Zstd3 for value blocks.
1298+
profile.Levels[manifest.NumLevels-1] = block.GoodCompression // Zstd3 for data and value blocks.
1299+
return profile
1300+
}()
1301+
)
1302+
1303+
// UniformDBCompressionSettings returns a DBCompressionSettings which uses the
1304+
// same compression profile on all LSM levels.
1305+
func UniformDBCompressionSettings(
1306+
name string, profile *block.CompressionProfile,
1307+
) DBCompressionSettings {
1308+
cs := DBCompressionSettings{Name: name}
1309+
for i := range cs.Levels {
1310+
cs.Levels[i] = profile
1311+
}
1312+
return cs
1313+
}
1314+
1315+
// ApplyCompressionSettings sets the Compression field in each LevelOptions to
1316+
// call the given function and return the compression profile for that level.
1317+
func (o *Options) ApplyCompressionSettings(csFn func() DBCompressionSettings) {
1318+
for i := range o.Levels {
1319+
levelIdx := i
1320+
o.Levels[i].Compression = func() *block.CompressionProfile {
1321+
return csFn().Levels[levelIdx]
1322+
}
1323+
}
1324+
}
1325+
12761326
// EnsureDefaults ensures that the default values for all options are set if a
12771327
// valid value was not already specified.
12781328
func (o *Options) EnsureDefaults() {

options_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/cockroachdb/errors"
1515
"github.com/cockroachdb/pebble/internal/base"
1616
"github.com/cockroachdb/pebble/internal/testkeys"
17+
"github.com/cockroachdb/pebble/sstable/block"
1718
"github.com/cockroachdb/pebble/vfs"
1819
"github.com/cockroachdb/pebble/wal"
1920
"github.com/stretchr/testify/require"
@@ -576,3 +577,26 @@ func TestKeyCategories(t *testing.T) {
576577
})
577578
}
578579
}
580+
581+
func TestApplyDBCompressionSettings(t *testing.T) {
582+
var o Options
583+
o.testingRandomized(t)
584+
585+
var profile DBCompressionSettings
586+
o.ApplyCompressionSettings(func() DBCompressionSettings {
587+
return profile
588+
})
589+
590+
profile = UniformDBCompressionSettings("Test", block.FastestCompression)
591+
profile.Levels[1] = block.FastestCompression
592+
profile.Levels[2] = block.BalancedCompression
593+
profile.Levels[3] = block.GoodCompression
594+
require.Equal(t, block.FastestCompression, o.Levels[1].Compression())
595+
require.Equal(t, block.BalancedCompression, o.Levels[2].Compression())
596+
require.Equal(t, block.GoodCompression, o.Levels[3].Compression())
597+
598+
profile = UniformDBCompressionSettings("Test2", block.FastestCompression)
599+
require.Equal(t, block.FastestCompression, o.Levels[1].Compression())
600+
require.Equal(t, block.FastestCompression, o.Levels[2].Compression())
601+
require.Equal(t, block.FastestCompression, o.Levels[3].Compression())
602+
}

sstable/block/compression.go

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,17 +61,41 @@ var (
6161
MinLZCompression = simpleCompressionProfile("MinLZ", compression.MinLZFastest)
6262

6363
DefaultCompression = SnappyCompression
64-
FastestCompression = simpleCompressionProfile("Fastest", fastestAlgorithm())
64+
FastestCompression = simpleCompressionProfile("Fastest", fastestCompression)
65+
66+
FastCompression = registerCompressionProfile(CompressionProfile{
67+
Name: "Fast",
68+
DataBlocks: fastestCompression,
69+
ValueBlocks: compression.ZstdLevel1,
70+
OtherBlocks: fastestCompression,
71+
MinReductionPercent: 10,
72+
})
73+
74+
BalancedCompression = registerCompressionProfile(CompressionProfile{
75+
Name: "Balanced",
76+
DataBlocks: compression.ZstdLevel1,
77+
ValueBlocks: compression.ZstdLevel3,
78+
OtherBlocks: fastestCompression,
79+
MinReductionPercent: 5,
80+
})
81+
82+
GoodCompression = registerCompressionProfile(CompressionProfile{
83+
Name: "Good",
84+
DataBlocks: compression.ZstdLevel3,
85+
ValueBlocks: compression.ZstdLevel3,
86+
OtherBlocks: fastestCompression,
87+
MinReductionPercent: 5,
88+
})
6589
)
6690

67-
var fastestAlgorithm = func() compression.Setting {
91+
var fastestCompression = func() compression.Setting {
6892
if runtime.GOARCH == "arm64" {
6993
// MinLZ is generally faster and better than Snappy except for arm64: Snappy
7094
// has an arm64 assembly implementation and MinLZ does not.
7195
return compression.Snappy
7296
}
7397
return compression.MinLZFastest
74-
}
98+
}()
7599

76100
// simpleCompressionProfile returns a CompressionProfile that uses the same
77101
// compression setting for all blocks and which uses the uncompressed block if
@@ -80,15 +104,13 @@ var fastestAlgorithm = func() compression.Setting {
80104
//
81105
// It should only be used during global initialization.
82106
func simpleCompressionProfile(name string, setting compression.Setting) *CompressionProfile {
83-
p := &CompressionProfile{
107+
return registerCompressionProfile(CompressionProfile{
84108
Name: name,
85109
DataBlocks: setting,
86110
ValueBlocks: setting,
87111
OtherBlocks: setting,
88112
MinReductionPercent: 12,
89-
}
90-
registerCompressionProfile(p)
91-
return p
113+
})
92114
}
93115

94116
// CompressionProfileByName returns the built-in compression profile with the
@@ -102,12 +124,13 @@ func CompressionProfileByName(name string) *CompressionProfile {
102124

103125
var compressionProfileMap = make(map[string]*CompressionProfile)
104126

105-
func registerCompressionProfile(p *CompressionProfile) {
127+
func registerCompressionProfile(p CompressionProfile) *CompressionProfile {
106128
key := strings.ToLower(p.Name)
107129
if _, ok := compressionProfileMap[key]; ok {
108130
panic(errors.AssertionFailedf("duplicate compression profile: %s", p.Name))
109131
}
110-
compressionProfileMap[key] = p
132+
compressionProfileMap[key] = &p
133+
return &p
111134
}
112135

113136
// CompressionIndicator is the byte stored physically within the block.Trailer

0 commit comments

Comments
 (0)