diff --git a/db/compaction_picker.cc b/db/compaction_picker.cc index cfa3770d7..5839d4dac 100644 --- a/db/compaction_picker.cc +++ b/db/compaction_picker.cc @@ -22,6 +22,21 @@ uint64_t TotalFileSize(const std::vector& files) { 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::max() / op1 < casted_op2) { + return op1; + } + return op1 * casted_op2; +} + } // anonymous namespace CompactionPicker::CompactionPicker(const Options* options, @@ -48,10 +63,11 @@ void CompactionPicker::Init() { max_file_size_[i] = ULLONG_MAX; level_max_bytes_[i] = options_->max_bytes_for_level_base; } else if (i > 1) { - max_file_size_[i] = max_file_size_[i - 1] * target_file_size_multiplier; - level_max_bytes_[i] = - level_max_bytes_[i - 1] * max_bytes_multiplier * - options_->max_bytes_for_level_multiplier_additional[i - 1]; + max_file_size_[i] = MultiplyCheckOverflow(max_file_size_[i - 1], + target_file_size_multiplier); + level_max_bytes_[i] = MultiplyCheckOverflow( + MultiplyCheckOverflow(level_max_bytes_[i - 1], max_bytes_multiplier), + options_->max_bytes_for_level_multiplier_additional[i - 1]); } else { max_file_size_[i] = options_->target_file_size_base; level_max_bytes_[i] = options_->max_bytes_for_level_base;