@ -1228,10 +1228,19 @@ Status CompactionJob::FinishCompactionOutputFile(
lower_bound = nullptr ;
}
if ( next_table_min_key ! = nullptr ) {
// This isn't the last file in the subcompaction, so extend until the next
// file starts.
// This may be the last file in the subcompaction in some cases, so we
// need to compare the end key of subcompaction with the next file start
// key. When the end key is chosen by the subcompaction, we know that
// it must be the biggest key in output file. Therefore, it is safe to
// use the smaller key as the upper bound of the output file, to ensure
// that there is no overlapping between different output files.
upper_bound_guard = ExtractUserKey ( * next_table_min_key ) ;
upper_bound = & upper_bound_guard ;
if ( sub_compact - > end ! = nullptr & &
ucmp - > Compare ( upper_bound_guard , * sub_compact - > end ) > = 0 ) {
upper_bound = sub_compact - > end ;
} else {
upper_bound = & upper_bound_guard ;
}
} else {
// This is the last file in the subcompaction, so extend until the
// subcompaction ends.
@ -1249,6 +1258,13 @@ Status CompactionJob::FinishCompactionOutputFile(
has_overlapping_endpoints = false ;
}
// The end key of the subcompaction must be bigger or equal to the upper
// bound. If the end of subcompaction is null or the upper bound is null,
// it means that this file is the last file in the compaction. So there
// will be no overlapping between this file and others.
assert ( sub_compact - > end = = nullptr | |
upper_bound = = nullptr | |
ucmp - > Compare ( * upper_bound , * sub_compact - > end ) < = 0 ) ;
auto it = range_del_agg - > NewIterator ( lower_bound , upper_bound ,
has_overlapping_endpoints ) ;
// Position the range tombstone output iterator. There may be tombstone