Skip to content

Commit

Permalink
db: convert adjustedOutputLevel into a function
Browse files Browse the repository at this point in the history
There's benefits to turning adjustedOutputLevel into a function.
1. Multilevel compactions will want to edit the adjustedOutputLevel,
   and currently does so in a hacky way. With this change, I can get
   rid of the hack.
2. Storing the baseLevel is much better because it doesn't change once
   set.
  • Loading branch information
bananabrick committed Oct 6, 2023
1 parent 4280b45 commit 470a93d
Showing 1 changed file with 26 additions and 23 deletions.
49 changes: 26 additions & 23 deletions compaction_picker.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,11 +202,9 @@ type pickedCompaction struct {
// extraLevels contain additional levels in between the input and output
// levels that get compacted in multi level compactions
extraLevels []*compactionLevel
// adjustedOutputLevel is the output level used for the purpose of
// determining the target output file size, overlap bytes, and expanded
// bytes, taking into account the base level.
adjustedOutputLevel int
inputs []compactionLevel
inputs []compactionLevel
// LBase at the time of compaction picking.
baseLevel int
// L0-specific compaction info. Set to a non-nil value for all compactions
// where startLevel == 0 that were generated by L0Sublevels.
lcf *manifest.L0CompactionFiles
Expand Down Expand Up @@ -246,28 +244,35 @@ func newPickedCompaction(
startLevel, baseLevel))
}

adjustedOutputLevel := outputLevel
if adjustedOutputLevel > 0 {
// Output level is in the range [baseLevel,numLevels]. For the purpose of
// determining the target output file size, overlap bytes, and expanded
// bytes, we want to adjust the range to [1,numLevels].
adjustedOutputLevel = 1 + outputLevel - baseLevel
}

adjustedLevel := adjustedOutputLevel(outputLevel, baseLevel)
pc := &pickedCompaction{
cmp: opts.Comparer.Compare,
version: cur,
baseLevel: baseLevel,
inputs: []compactionLevel{{level: startLevel}, {level: outputLevel}},
adjustedOutputLevel: adjustedOutputLevel,
maxOutputFileSize: uint64(opts.Level(adjustedOutputLevel).TargetFileSize),
maxOverlapBytes: maxGrandparentOverlapBytes(opts, adjustedOutputLevel),
maxReadCompactionBytes: maxReadCompactionBytes(opts, adjustedOutputLevel),
maxOutputFileSize: uint64(opts.Level(adjustedLevel).TargetFileSize),
maxOverlapBytes: maxGrandparentOverlapBytes(opts, adjustedLevel),
maxReadCompactionBytes: maxReadCompactionBytes(opts, adjustedLevel),
}
pc.startLevel = &pc.inputs[0]
pc.outputLevel = &pc.inputs[1]
return pc
}

// adjustedOutputLevel is the output level used for the purpose of
// determining the target output file size, overlap bytes, and expanded
// bytes, taking into account the base level.
func adjustedOutputLevel(outputLevel int, baseLevel int) int {
adjustedOutputLevel := outputLevel
if adjustedOutputLevel > 0 {
// Output level is in the range [baseLevel, numLevels]. For the purpose of
// determining the target output file size, overlap bytes, and expanded
// bytes, we want to adjust the range to [1,numLevels].
adjustedOutputLevel = 1 + outputLevel - baseLevel
}
return adjustedOutputLevel
}

func newPickedCompactionFromL0(
lcf *manifest.L0CompactionFiles, opts *Options, vers *version, baseLevel int, isBase bool,
) *pickedCompaction {
Expand Down Expand Up @@ -300,7 +305,7 @@ func (pc *pickedCompaction) String() string {
var builder strings.Builder
builder.WriteString(fmt.Sprintf(`Score=%f, `, pc.score))
builder.WriteString(fmt.Sprintf(`Kind=%s, `, pc.kind))
builder.WriteString(fmt.Sprintf(`AdjustedOutputLevel=%d, `, pc.adjustedOutputLevel))
builder.WriteString(fmt.Sprintf(`AdjustedOutputLevel=%d, `, adjustedOutputLevel(pc.outputLevel.level, pc.baseLevel)))
builder.WriteString(fmt.Sprintf(`maxOutputFileSize=%d, `, pc.maxOutputFileSize))
builder.WriteString(fmt.Sprintf(`maxReadCompactionBytes=%d, `, pc.maxReadCompactionBytes))
builder.WriteString(fmt.Sprintf(`smallest=%s, `, pc.smallest))
Expand All @@ -324,7 +329,7 @@ func (pc *pickedCompaction) clone() *pickedCompaction {
cmp: pc.cmp,
score: pc.score,
kind: pc.kind,
adjustedOutputLevel: pc.adjustedOutputLevel,
baseLevel: pc.baseLevel,
maxOutputFileSize: pc.maxOutputFileSize,
maxOverlapBytes: pc.maxOverlapBytes,
maxReadCompactionBytes: pc.maxReadCompactionBytes,
Expand Down Expand Up @@ -402,7 +407,7 @@ func (pc *pickedCompaction) setupInputs(
// growing a compaction results in a larger size, the original compaction
// is used instead.
maxExpandedBytes := expandedCompactionByteSizeLimit(
opts, pc.adjustedOutputLevel, diskAvailBytes,
opts, adjustedOutputLevel(pc.outputLevel.level, pc.baseLevel), diskAvailBytes,
)

// Expand the initial inputs to a clean cut.
Expand Down Expand Up @@ -560,8 +565,6 @@ func (pc *pickedCompaction) setupMultiLevelCandidate(opts *Options, diskAvailByt
pc.startLevel = &pc.inputs[0]
pc.extraLevels = []*compactionLevel{&pc.inputs[1]}
pc.outputLevel = &pc.inputs[2]

pc.adjustedOutputLevel++
return pc.setupInputs(opts, diskAvailBytes, pc.extraLevels[len(pc.extraLevels)-1])
}

Expand Down Expand Up @@ -1699,7 +1702,7 @@ func (pc *pickedCompaction) maybeAddLevel(opts *Options, diskAvailBytes uint64)
return pc
}
if pc.compactionSize() > expandedCompactionByteSizeLimit(
opts, pc.adjustedOutputLevel, diskAvailBytes) {
opts, adjustedOutputLevel(pc.outputLevel.level, pc.baseLevel), diskAvailBytes) {
// Don't add a level if the current compaction exceeds the compaction size limit
return pc
}
Expand Down

0 comments on commit 470a93d

Please sign in to comment.