If User setting of compaction multipliers overflow, use default value 1 instead

Summary: Currently, compaction multipliers can overflow and cause unexpected behaviors. In this patch, we detect those overflows and use multiplier 1 for them.

Test Plan: make all check

Reviewers: dhruba, haobo, igor, kailiu

Reviewed By: kailiu

CC: leveldb

Differential Revision: https://reviews.facebook.net/D15321
This commit is contained in:
Siying Dong 2014-01-23 16:27:34 -08:00
parent aba2acb5ec
commit 4605e20c58

View File

@ -22,6 +22,21 @@ uint64_t TotalFileSize(const std::vector<FileMetaData*>& files) {
return sum; return sum;
} }
// Multiple two operands. If they overflow, return op1.
uint64_t MultiplyCheckOverflow(uint64_t op1, int op2) {
if (op1 == 0) {
return 0;
}
if (op2 <= 0) {
return op1;
}
uint64_t casted_op2 = (uint64_t) op2;
if (std::numeric_limits<uint64_t>::max() / op1 < casted_op2) {
return op1;
}
return op1 * casted_op2;
}
} // anonymous namespace } // anonymous namespace
CompactionPicker::CompactionPicker(const Options* options, CompactionPicker::CompactionPicker(const Options* options,
@ -48,10 +63,11 @@ void CompactionPicker::Init() {
max_file_size_[i] = ULLONG_MAX; max_file_size_[i] = ULLONG_MAX;
level_max_bytes_[i] = options_->max_bytes_for_level_base; level_max_bytes_[i] = options_->max_bytes_for_level_base;
} else if (i > 1) { } else if (i > 1) {
max_file_size_[i] = max_file_size_[i - 1] * target_file_size_multiplier; max_file_size_[i] = MultiplyCheckOverflow(max_file_size_[i - 1],
level_max_bytes_[i] = target_file_size_multiplier);
level_max_bytes_[i - 1] * max_bytes_multiplier * level_max_bytes_[i] = MultiplyCheckOverflow(
options_->max_bytes_for_level_multiplier_additional[i - 1]; MultiplyCheckOverflow(level_max_bytes_[i - 1], max_bytes_multiplier),
options_->max_bytes_for_level_multiplier_additional[i - 1]);
} else { } else {
max_file_size_[i] = options_->target_file_size_base; max_file_size_[i] = options_->target_file_size_base;
level_max_bytes_[i] = options_->max_bytes_for_level_base; level_max_bytes_[i] = options_->max_bytes_for_level_base;