diff --git a/options/options_helper.cc b/options/options_helper.cc index 94410e530..b54d589a3 100644 --- a/options/options_helper.cc +++ b/options/options_helper.cc @@ -454,6 +454,12 @@ bool ParseOptionHelper(char* opt_address, const OptionType& opt_type, case OptionType::kInt: *reinterpret_cast(opt_address) = ParseInt(value); break; + case OptionType::kInt32T: + *reinterpret_cast(opt_address) = ParseInt32(value); + break; + case OptionType::kInt64T: + PutUnaligned(reinterpret_cast(opt_address), ParseInt64(value)); + break; case OptionType::kVectorInt: *reinterpret_cast*>(opt_address) = ParseVectorInt(value); break; @@ -563,6 +569,16 @@ bool SerializeSingleOptionHelper(const char* opt_address, case OptionType::kInt: *value = ToString(*(reinterpret_cast(opt_address))); break; + case OptionType::kInt32T: + *value = ToString(*(reinterpret_cast(opt_address))); + break; + case OptionType::kInt64T: + { + int64_t v; + GetUnaligned(reinterpret_cast(opt_address), &v); + *value = ToString(v); + } + break; case OptionType::kVectorInt: return SerializeIntVector( *reinterpret_cast*>(opt_address), value); diff --git a/options/options_helper.h b/options/options_helper.h index 016a0a1af..1d3d880a6 100644 --- a/options/options_helper.h +++ b/options/options_helper.h @@ -47,6 +47,8 @@ Status GetTableFactoryFromMap( enum class OptionType { kBoolean, kInt, + kInt32T, + kInt64T, kVectorInt, kUInt, kUInt32T, diff --git a/options/options_parser.cc b/options/options_parser.cc index a6bb8db2d..2a85fa534 100644 --- a/options/options_parser.cc +++ b/options/options_parser.cc @@ -500,6 +500,16 @@ bool AreEqualOptions( case OptionType::kInt: return (*reinterpret_cast(offset1) == *reinterpret_cast(offset2)); + case OptionType::kInt32T: + return (*reinterpret_cast(offset1) == + *reinterpret_cast(offset2)); + case OptionType::kInt64T: + { + int64_t v1, v2; + GetUnaligned(reinterpret_cast(offset1), &v1); + GetUnaligned(reinterpret_cast(offset2), &v2); + return (v1 == v2); + } case OptionType::kVectorInt: return (*reinterpret_cast*>(offset1) == *reinterpret_cast*>(offset2)); diff --git a/options/options_test.cc b/options/options_test.cc index b7076c8bd..d6ccf531a 100644 --- a/options/options_test.cc +++ b/options/options_test.cc @@ -21,6 +21,7 @@ #include "options/options_helper.h" #include "options/options_parser.h" #include "options/options_sanity_check.h" +#include "port/port.h" #include "rocksdb/cache.h" #include "rocksdb/convenience.h" #include "rocksdb/memtablerep.h" @@ -1813,6 +1814,18 @@ bool IsEscapedString(const std::string& str) { } } // namespace +TEST_F(OptionsParserTest, IntegerParsing) { + ASSERT_EQ(ParseUint64("18446744073709551615"), 18446744073709551615U); + ASSERT_EQ(ParseUint32("4294967295"), 4294967295U); + ASSERT_EQ(ParseSizeT("18446744073709551615"), 18446744073709551615U); + ASSERT_EQ(ParseInt64("9223372036854775807"), 9223372036854775807U); + ASSERT_EQ(ParseInt64("-9223372036854775808"), port::kMinInt64); + ASSERT_EQ(ParseInt32("2147483647"), 2147483647U); + ASSERT_EQ(ParseInt32("-2147483648"), port::kMinInt32); + ASSERT_EQ(ParseInt("-32767"), -32767); + ASSERT_EQ(ParseDouble("-1.234567"), -1.234567); +} + TEST_F(OptionsParserTest, EscapeOptionString) { ASSERT_EQ(UnescapeOptionString( "This is a test string with \\# \\: and \\\\ escape chars."), diff --git a/port/port_posix.h b/port/port_posix.h index 2d2a7a79c..c53a640e9 100644 --- a/port/port_posix.h +++ b/port/port_posix.h @@ -87,8 +87,10 @@ namespace port { // For use at db/file_indexer.h kLevelMaxIndex const uint32_t kMaxUint32 = std::numeric_limits::max(); const int kMaxInt32 = std::numeric_limits::max(); +const int kMinInt32 = std::numeric_limits::min(); const uint64_t kMaxUint64 = std::numeric_limits::max(); const int64_t kMaxInt64 = std::numeric_limits::max(); +const int64_t kMinInt64 = std::numeric_limits::min(); const size_t kMaxSizet = std::numeric_limits::max(); static const bool kLittleEndian = PLATFORM_IS_LITTLE_ENDIAN; diff --git a/port/win/port_win.h b/port/win/port_win.h index 9b8ba9ff8..8f579c984 100644 --- a/port/win/port_win.h +++ b/port/win/port_win.h @@ -93,7 +93,9 @@ namespace port { // For use at db/file_indexer.h kLevelMaxIndex const uint32_t kMaxUint32 = UINT32_MAX; const int kMaxInt32 = INT32_MAX; +const int kMinInt32 = INT32_MIN; const int64_t kMaxInt64 = INT64_MAX; +const int64_t kMinInt64 = INT64_MIN; const uint64_t kMaxUint64 = UINT64_MAX; #ifdef _WIN64 @@ -109,8 +111,10 @@ const size_t kMaxSizet = UINT_MAX; // For use at db/file_indexer.h kLevelMaxIndex const uint32_t kMaxUint32 = std::numeric_limits::max(); const int kMaxInt32 = std::numeric_limits::max(); +const int kMinInt32 = std::numeric_limits::min(); const uint64_t kMaxUint64 = std::numeric_limits::max(); const int64_t kMaxInt64 = std::numeric_limits::max(); +const int64_t kMinInt64 = std::numeric_limits::min(); const size_t kMaxSizet = std::numeric_limits::max(); diff --git a/util/string_util.cc b/util/string_util.cc index f3581105e..26e6759ac 100644 --- a/util/string_util.cc +++ b/util/string_util.cc @@ -21,6 +21,7 @@ #include #include #include "rocksdb/env.h" +#include "port/port.h" #include "rocksdb/slice.h" namespace rocksdb { @@ -276,6 +277,15 @@ uint32_t ParseUint32(const std::string& value) { } } +int32_t ParseInt32(const std::string& value) { + int64_t num = ParseInt64(value); + if (num <= port::kMaxInt32 && num >= port::kMinInt32) { + return static_cast(num); + } else { + throw std::out_of_range(value); + } +} + #endif uint64_t ParseUint64(const std::string& value) { @@ -303,6 +313,31 @@ uint64_t ParseUint64(const std::string& value) { return num; } +int64_t ParseInt64(const std::string& value) { + size_t endchar; +#ifndef CYGWIN + int64_t num = std::stoll(value.c_str(), &endchar); +#else + char* endptr; + int64_t num = std::strtoll(value.c_str(), &endptr, 0); + endchar = endptr - value.c_str(); +#endif + + 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; +} + int ParseInt(const std::string& value) { size_t endchar; #ifndef CYGWIN diff --git a/util/string_util.h b/util/string_util.h index b2bca40ac..6e125ddfa 100644 --- a/util/string_util.h +++ b/util/string_util.h @@ -109,12 +109,17 @@ std::string trim(const std::string& str); bool ParseBoolean(const std::string& type, const std::string& value); uint32_t ParseUint32(const std::string& value); + +int32_t ParseInt32(const std::string& value); #endif uint64_t ParseUint64(const std::string& value); int ParseInt(const std::string& value); + +int64_t ParseInt64(const std::string& value); + double ParseDouble(const std::string& value); size_t ParseSizeT(const std::string& value);