@ -2266,6 +2266,13 @@ Compaction* VersionSet::PickCompactionUniversal(int level, double score) {
newerfile = f ;
}
// Is the earliest file part of this compaction?
int last_index = file_by_time [ file_by_time . size ( ) - 1 ] ;
FileMetaData * last_file = current_ - > files_ [ level ] [ last_index ] ;
if ( c - > inputs_ [ 0 ] [ c - > inputs_ [ 0 ] . size ( ) - 1 ] = = last_file ) {
c - > bottommost_level_ = true ;
}
// update statistics
if ( options_ - > statistics ! = nullptr ) {
options_ - > statistics - > measureTime ( NUM_FILES_IN_SINGLE_COMPACTION ,
@ -2444,13 +2451,15 @@ Compaction* VersionSet::PickCompaction() {
assert ( ! c - > inputs_ [ 0 ] . empty ( ) ) ;
}
// Setup "level+1" files (inputs_[1])
SetupOtherInputs ( c ) ;
// mark all the files that are being compacted
c - > MarkFilesBeingCompacted ( true ) ;
// Is this compaction creating a file at the bottommost level
c - > SetupBottomMostLevel ( false ) ;
// remember this currently undergoing compaction
compactions_in_progress_ [ level ] . insert ( c ) ;
@ -2624,6 +2633,13 @@ Compaction* VersionSet::CompactRange(
const InternalKey * begin ,
const InternalKey * end ) {
std : : vector < FileMetaData * > inputs ;
// All files are 'overlapping' in universal style compaction.
// We have to compact the entire range in one shot.
if ( options_ - > compaction_style = = kCompactionStyleUniversal ) {
begin = nullptr ;
end = nullptr ;
}
current_ - > GetOverlappingInputs ( level , begin , end , & inputs ) ;
if ( inputs . empty ( ) ) {
return nullptr ;
@ -2667,6 +2683,9 @@ Compaction* VersionSet::CompactRange(
// upon other files because manual compactions are processed when
// the system has a max of 1 background compaction thread.
c - > MarkFilesBeingCompacted ( true ) ;
// Is this compaction creating a file at the bottommost level
c - > SetupBottomMostLevel ( true ) ;
return c ;
}
@ -2686,6 +2705,7 @@ Compaction::Compaction(int level, int out_level, uint64_t target_file_size,
base_index_ ( - 1 ) ,
parent_index_ ( - 1 ) ,
score_ ( 0 ) ,
bottommost_level_ ( false ) ,
level_ptrs_ ( std : : vector < size_t > ( number_levels ) ) {
edit_ = new VersionEdit ( number_levels_ ) ;
for ( int i = 0 ; i < number_levels_ ; i + + ) {
@ -2718,6 +2738,10 @@ void Compaction::AddInputDeletions(VersionEdit* edit) {
}
bool Compaction : : IsBaseLevelForKey ( const Slice & user_key ) {
if ( input_version_ - > vset_ - > options_ - > compaction_style = =
kCompactionStyleUniversal ) {
return bottommost_level_ ;
}
// Maybe use binary search to find right entry instead of linear search?
const Comparator * user_cmp = input_version_ - > vset_ - > icmp_ . user_comparator ( ) ;
for ( int lvl = level_ + 2 ; lvl < number_levels_ ; lvl + + ) {
@ -2776,6 +2800,31 @@ void Compaction::MarkFilesBeingCompacted(bool value) {
}
}
// Is this compaction producing files at the bottommost level?
void Compaction : : SetupBottomMostLevel ( bool isManual ) {
if ( input_version_ - > vset_ - > options_ - > compaction_style = =
kCompactionStyleUniversal ) {
// If universal compaction style is used and manual
// compaction is occuring, then we are guaranteed that
// all files will be picked in a single compaction
// run. We can safely set bottommost_level_ = true.
// If it is not manual compaction, then bottommost_level_
// is already set when the Compaction was created.
if ( isManual ) {
bottommost_level_ = true ;
}
return ;
}
bottommost_level_ = true ;
int num_levels = input_version_ - > vset_ - > NumberLevels ( ) ;
for ( int i = level ( ) + 2 ; i < num_levels ; i + + ) {
if ( input_version_ - > vset_ - > NumLevelFiles ( i ) > 0 ) {
bottommost_level_ = false ;
break ;
}
}
}
void Compaction : : ReleaseInputs ( ) {
if ( input_version_ ! = nullptr ) {
input_version_ - > Unref ( ) ;