@ -133,8 +133,8 @@ class UniversalCompactionBuilder {
UniversalCompactionPicker * picker_ ;
UniversalCompactionPicker * picker_ ;
LogBuffer * log_buffer_ ;
LogBuffer * log_buffer_ ;
static std : : vector < SortedRun > CalculateSortedRuns (
static std : : vector < UniversalCompactionBuilder : : SortedRun > CalculateSortedRuns (
const VersionStorageInfo & vstorage ) ;
const VersionStorageInfo & vstorage , int last_level ) ;
// Pick a path ID to place a newly generated file, with its estimated file
// Pick a path ID to place a newly generated file, with its estimated file
// size.
// size.
@ -339,13 +339,13 @@ void UniversalCompactionBuilder::SortedRun::DumpSizeInfo(
std : : vector < UniversalCompactionBuilder : : SortedRun >
std : : vector < UniversalCompactionBuilder : : SortedRun >
UniversalCompactionBuilder : : CalculateSortedRuns (
UniversalCompactionBuilder : : CalculateSortedRuns (
const VersionStorageInfo & vstorage ) {
const VersionStorageInfo & vstorage , int last_level ) {
std : : vector < UniversalCompactionBuilder : : SortedRun > ret ;
std : : vector < UniversalCompactionBuilder : : SortedRun > ret ;
for ( FileMetaData * f : vstorage . LevelFiles ( 0 ) ) {
for ( FileMetaData * f : vstorage . LevelFiles ( 0 ) ) {
ret . emplace_back ( 0 , f , f - > fd . GetFileSize ( ) , f - > compensated_file_size ,
ret . emplace_back ( 0 , f , f - > fd . GetFileSize ( ) , f - > compensated_file_size ,
f - > being_compacted ) ;
f - > being_compacted ) ;
}
}
for ( int level = 1 ; level < vstorage . num_levels ( ) ; level + + ) {
for ( int level = 1 ; level < = last_level ; level + + ) {
uint64_t total_compensated_size = 0U ;
uint64_t total_compensated_size = 0U ;
uint64_t total_size = 0U ;
uint64_t total_size = 0U ;
bool being_compacted = false ;
bool being_compacted = false ;
@ -374,7 +374,9 @@ UniversalCompactionBuilder::CalculateSortedRuns(
Compaction * UniversalCompactionBuilder : : PickCompaction ( ) {
Compaction * UniversalCompactionBuilder : : PickCompaction ( ) {
const int kLevel0 = 0 ;
const int kLevel0 = 0 ;
score_ = vstorage_ - > CompactionScore ( kLevel0 ) ;
score_ = vstorage_ - > CompactionScore ( kLevel0 ) ;
sorted_runs_ = CalculateSortedRuns ( * vstorage_ ) ;
int max_output_level =
vstorage_ - > MaxOutputLevel ( ioptions_ . allow_ingest_behind ) ;
sorted_runs_ = CalculateSortedRuns ( * vstorage_ , max_output_level ) ;
if ( sorted_runs_ . size ( ) = = 0 | |
if ( sorted_runs_ . size ( ) = = 0 | |
( vstorage_ - > FilesMarkedForPeriodicCompaction ( ) . empty ( ) & &
( vstorage_ - > FilesMarkedForPeriodicCompaction ( ) . empty ( ) & &
@ -471,6 +473,8 @@ Compaction* UniversalCompactionBuilder::PickCompaction() {
" UniversalCompactionBuilder::PickCompaction:Return " , nullptr ) ;
" UniversalCompactionBuilder::PickCompaction:Return " , nullptr ) ;
return nullptr ;
return nullptr ;
}
}
assert ( c - > output_level ( ) < =
vstorage_ - > MaxOutputLevel ( ioptions_ . allow_ingest_behind ) ) ;
if ( mutable_cf_options_ . compaction_options_universal . allow_trivial_move = =
if ( mutable_cf_options_ . compaction_options_universal . allow_trivial_move = =
true & &
true & &
@ -698,22 +702,18 @@ Compaction* UniversalCompactionBuilder::PickCompactionToReduceSortedRuns(
GetPathId ( ioptions_ , mutable_cf_options_ , estimated_total_size ) ;
GetPathId ( ioptions_ , mutable_cf_options_ , estimated_total_size ) ;
int start_level = sorted_runs_ [ start_index ] . level ;
int start_level = sorted_runs_ [ start_index ] . level ;
int output_level ;
int output_level ;
// last level is reserved for the files ingested behind
int max_output_level =
vstorage_ - > MaxOutputLevel ( ioptions_ . allow_ingest_behind ) ;
if ( first_index_after = = sorted_runs_ . size ( ) ) {
if ( first_index_after = = sorted_runs_ . size ( ) ) {
output_level = vstorage_ - > num_levels ( ) - 1 ;
output_level = max_output_level ;
} else if ( sorted_runs_ [ first_index_after ] . level = = 0 ) {
} else if ( sorted_runs_ [ first_index_after ] . level = = 0 ) {
output_level = 0 ;
output_level = 0 ;
} else {
} else {
output_level = sorted_runs_ [ first_index_after ] . level - 1 ;
output_level = sorted_runs_ [ first_index_after ] . level - 1 ;
}
}
// last level is reserved for the files ingested behind
std : : vector < CompactionInputFiles > inputs ( max_output_level + 1 ) ;
if ( ioptions_ . allow_ingest_behind & &
( output_level = = vstorage_ - > num_levels ( ) - 1 ) ) {
assert ( output_level > 1 ) ;
output_level - - ;
}
std : : vector < CompactionInputFiles > inputs ( vstorage_ - > num_levels ( ) ) ;
for ( size_t i = 0 ; i < inputs . size ( ) ; + + i ) {
for ( size_t i = 0 ; i < inputs . size ( ) ; + + i ) {
inputs [ i ] . level = start_level + static_cast < int > ( i ) ;
inputs [ i ] . level = start_level + static_cast < int > ( i ) ;
}
}
@ -1192,8 +1192,10 @@ Compaction* UniversalCompactionBuilder::PickDeleteTriggeredCompaction() {
return nullptr ;
return nullptr ;
}
}
int max_output_level =
vstorage_ - > MaxOutputLevel ( ioptions_ . allow_ingest_behind ) ;
// Pick the first non-empty level after the start_level
// Pick the first non-empty level after the start_level
for ( output_level = start_level + 1 ; output_level < vstorage_ - > num_levels ( ) ;
for ( output_level = start_level + 1 ; output_level < = max_output_level ;
output_level + + ) {
output_level + + ) {
if ( vstorage_ - > NumLevelFiles ( output_level ) ! = 0 ) {
if ( vstorage_ - > NumLevelFiles ( output_level ) ! = 0 ) {
break ;
break ;
@ -1201,9 +1203,9 @@ Compaction* UniversalCompactionBuilder::PickDeleteTriggeredCompaction() {
}
}
// If all higher levels are empty, pick the highest level as output level
// If all higher levels are empty, pick the highest level as output level
if ( output_level = = vstorage_ - > num_levels ( ) ) {
if ( output_level > max_output_level ) {
if ( start_level = = 0 ) {
if ( start_level = = 0 ) {
output_level = vstorage_ - > num_levels ( ) - 1 ;
output_level = max_output_level ;
} else {
} else {
// If start level is non-zero and all higher levels are empty, this
// If start level is non-zero and all higher levels are empty, this
// compaction will translate into a trivial move. Since the idea is
// compaction will translate into a trivial move. Since the idea is
@ -1212,11 +1214,7 @@ Compaction* UniversalCompactionBuilder::PickDeleteTriggeredCompaction() {
return nullptr ;
return nullptr ;
}
}
}
}
if ( ioptions_ . allow_ingest_behind & &
assert ( output_level < = max_output_level ) ;
output_level = = vstorage_ - > num_levels ( ) - 1 ) {
assert ( output_level > 1 ) ;
output_level - - ;
}
if ( output_level ! = 0 ) {
if ( output_level ! = 0 ) {
if ( start_level = = 0 ) {
if ( start_level = = 0 ) {
@ -1293,8 +1291,9 @@ Compaction* UniversalCompactionBuilder::PickCompactionWithSortedRunRange(
uint32_t path_id =
uint32_t path_id =
GetPathId ( ioptions_ , mutable_cf_options_ , estimated_total_size ) ;
GetPathId ( ioptions_ , mutable_cf_options_ , estimated_total_size ) ;
int start_level = sorted_runs_ [ start_index ] . level ;
int start_level = sorted_runs_ [ start_index ] . level ;
int max_output_level =
std : : vector < CompactionInputFiles > inputs ( vstorage_ - > num_levels ( ) ) ;
vstorage_ - > MaxOutputLevel ( ioptions_ . allow_ingest_behind ) ;
std : : vector < CompactionInputFiles > inputs ( max_output_level + 1 ) ;
for ( size_t i = 0 ; i < inputs . size ( ) ; + + i ) {
for ( size_t i = 0 ; i < inputs . size ( ) ; + + i ) {
inputs [ i ] . level = start_level + static_cast < int > ( i ) ;
inputs [ i ] . level = start_level + static_cast < int > ( i ) ;
}
}
@ -1331,13 +1330,7 @@ Compaction* UniversalCompactionBuilder::PickCompactionWithSortedRunRange(
int output_level ;
int output_level ;
if ( end_index = = sorted_runs_ . size ( ) - 1 ) {
if ( end_index = = sorted_runs_ . size ( ) - 1 ) {
// output files at the last level, unless it's reserved
output_level = max_output_level ;
output_level = vstorage_ - > num_levels ( ) - 1 ;
// last level is reserved for the files ingested behind
if ( ioptions_ . allow_ingest_behind ) {
assert ( output_level > 1 ) ;
output_level - - ;
}
} else {
} else {
// if it's not including all sorted_runs, it can only output to the level
// if it's not including all sorted_runs, it can only output to the level
// above the `end_index + 1` sorted_run.
// above the `end_index + 1` sorted_run.