diff --git a/util/options_helper.cc b/util/options_helper.cc index bffcc1f5c5..1112152828 100644 --- a/util/options_helper.cc +++ b/util/options_helper.cc @@ -43,20 +43,56 @@ bool ParseBoolean(const std::string& type, const std::string& value) { throw type; } } -int ParseInt(const std::string& value) { return std::stoi(value); } - -uint32_t ParseUint32(const std::string& value) { - return static_cast(std::stoul(value)); -} uint64_t ParseUint64(const std::string& value) { - return std::stoull(value); + size_t endchar; + uint64_t num = std::stoull(value.c_str(), &endchar); + + if (endchar < value.length()) { + char c = value[endchar]; + if (c == 'k' || c == 'K') + num <<= 10LL; + else if (c == 'm' || c == 'M') + num <<= 20LL; + else if (c == 'g' || c == 'G') + num <<= 30LL; + else if (c == 't' || c == 'T') + num <<= 40LL; + } + + return num; } size_t ParseSizeT(const std::string& value) { return static_cast(ParseUint64(value)); } +uint32_t ParseUint32(const std::string& value) { + uint64_t num = ParseUint64(value); + if ((num >> 32LL) == 0) { + return static_cast(num); + } else { + throw std::out_of_range(value); + } +} + +int ParseInt(const std::string& value) { + size_t endchar; + int num = std::stoi(value.c_str(), &endchar); + + if (endchar < value.length()) { + char c = value[endchar]; + if (c == 'k' || c == 'K') + num <<= 10; + else if (c == 'm' || c == 'M') + num <<= 20; + else if (c == 'g' || c == 'G') + num <<= 30; + } + + return num; +} + double ParseDouble(const std::string& value) { return std::stod(value); } diff --git a/util/options_test.cc b/util/options_test.cc index 6bf2f0b0f6..b2087608f8 100644 --- a/util/options_test.cc +++ b/util/options_test.cc @@ -298,6 +298,28 @@ TEST(OptionsTest, GetOptionsFromStringTest) { // Missing option name ASSERT_TRUE(!GetColumnFamilyOptionsFromString(base_cf_opt, "write_buffer_size=13; =100;", &new_cf_opt)); + // Units (k) + ASSERT_TRUE(GetColumnFamilyOptionsFromString(base_cf_opt, + "memtable_prefix_bloom_bits=14k;max_write_buffer_number=-15K", + &new_cf_opt)); + ASSERT_EQ(new_cf_opt.memtable_prefix_bloom_bits, 14*1024); + ASSERT_EQ(new_cf_opt.max_write_buffer_number, -15*1024); + // Units (m) + ASSERT_TRUE(GetColumnFamilyOptionsFromString(base_cf_opt, + "max_write_buffer_number=16m;inplace_update_num_locks=17M", + &new_cf_opt)); + ASSERT_EQ(new_cf_opt.max_write_buffer_number, 16*1024*1024); + ASSERT_EQ(new_cf_opt.inplace_update_num_locks, 17*1024*1024); + // Units (g) + ASSERT_TRUE(GetColumnFamilyOptionsFromString(base_cf_opt, + "write_buffer_size=18g;arena_block_size=19G", &new_cf_opt)); + ASSERT_EQ(new_cf_opt.write_buffer_size, 18*1024LL*1024LL*1024LL); + ASSERT_EQ(new_cf_opt.arena_block_size, 19*1024LL*1024LL*1024LL); + // Units (t) + ASSERT_TRUE(GetColumnFamilyOptionsFromString(base_cf_opt, + "write_buffer_size=20t;arena_block_size=21T", &new_cf_opt)); + ASSERT_EQ(new_cf_opt.write_buffer_size, 20*1024LL*1024LL*1024LL*1024LL); + ASSERT_EQ(new_cf_opt.arena_block_size, 21*1024LL*1024LL*1024LL*1024LL); } } // namespace rocksdb