mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 15:42:02 +00:00
dbms: refactor DoubleConverter [#METR-17328]
This commit is contained in:
parent
1ca3d930da
commit
386d560d39
@ -2,6 +2,7 @@
|
||||
|
||||
#include <double-conversion/double-conversion.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
@ -15,14 +16,28 @@ template <> struct DoubleToStringConverterFlags<true>
|
||||
static constexpr auto flags = double_conversion::DoubleToStringConverter::EMIT_TRAILING_DECIMAL_POINT;
|
||||
};
|
||||
|
||||
template <bool emit_decimal_point = true>
|
||||
const double_conversion::DoubleToStringConverter & getDoubleToStringConverter()
|
||||
template <bool emit_decimal_point>
|
||||
class DoubleConverter
|
||||
{
|
||||
static const double_conversion::DoubleToStringConverter instance{
|
||||
DoubleToStringConverterFlags<emit_decimal_point>::flags, "inf", "nan", 'e', -6, 21, 6, 1
|
||||
};
|
||||
DoubleConverter(const DoubleConverter &) = delete;
|
||||
DoubleConverter & operator=(const DoubleConverter &) = delete;
|
||||
|
||||
return instance;
|
||||
}
|
||||
DoubleConverter() = default;
|
||||
|
||||
public:
|
||||
/** @todo Add commentary on how this constant is deduced.
|
||||
* e.g. it's minus sign, integral zero, decimal point, up to 5 leading zeros and kBase10MaximalLength digits. */
|
||||
static constexpr auto MAX_REPRESENTATION_LENGTH = 26;
|
||||
using BufferType = char[MAX_REPRESENTATION_LENGTH];
|
||||
|
||||
static const auto & instance()
|
||||
{
|
||||
static const double_conversion::DoubleToStringConverter instance{
|
||||
DoubleToStringConverterFlags<emit_decimal_point>::flags, "inf", "nan", 'e', -6, 21, 6, 1
|
||||
};
|
||||
|
||||
return instance;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -87,28 +87,28 @@ inline void writeBoolText(bool x, WriteBuffer & buf)
|
||||
|
||||
inline void writeFloatText(double x, WriteBuffer & buf)
|
||||
{
|
||||
char tmp[25];
|
||||
double_conversion::StringBuilder builder{tmp, sizeof(tmp)};
|
||||
DoubleConverter<false>::BufferType buffer;
|
||||
double_conversion::StringBuilder builder{buffer, sizeof(buffer)};
|
||||
|
||||
const auto result = getDoubleToStringConverter<false>().ToShortest(x, &builder);
|
||||
const auto result = DoubleConverter<false>::instance().ToShortest(x, &builder);
|
||||
|
||||
if (!result)
|
||||
throw Exception("Cannot print double number", ErrorCodes::CANNOT_PRINT_FLOAT_OR_DOUBLE_NUMBER);
|
||||
|
||||
buf.write(tmp, builder.position());
|
||||
buf.write(buffer, builder.position());
|
||||
}
|
||||
|
||||
inline void writeFloatText(float x, WriteBuffer & buf)
|
||||
{
|
||||
char tmp[25];
|
||||
double_conversion::StringBuilder builder{tmp, sizeof(tmp)};
|
||||
DoubleConverter<false>::BufferType buffer;
|
||||
double_conversion::StringBuilder builder{buffer, sizeof(buffer)};
|
||||
|
||||
const auto result = getDoubleToStringConverter<false>().ToShortestSingle(x, &builder);
|
||||
const auto result = DoubleConverter<false>::instance().ToShortestSingle(x, &builder);
|
||||
|
||||
if (!result)
|
||||
throw Exception("Cannot print float number", ErrorCodes::CANNOT_PRINT_FLOAT_OR_DOUBLE_NUMBER);
|
||||
|
||||
buf.write(tmp, builder.position());
|
||||
buf.write(buffer, builder.position());
|
||||
}
|
||||
|
||||
|
||||
|
@ -14,15 +14,15 @@ static void formatReadable(double size, DB::WriteBuffer & out, int precision, co
|
||||
for (; i + 1 < units_size && fabs(size) >= delimiter; ++i)
|
||||
size /= delimiter;
|
||||
|
||||
char tmp[25];
|
||||
double_conversion::StringBuilder builder{tmp, sizeof(tmp)};
|
||||
DB::DoubleConverter<false>::BufferType buffer;
|
||||
double_conversion::StringBuilder builder{buffer, sizeof(buffer)};
|
||||
|
||||
const auto result = DB::getDoubleToStringConverter<false>().ToFixed(size, precision, &builder);
|
||||
const auto result = DB::DoubleConverter<false>::instance().ToFixed(size, precision, &builder);
|
||||
|
||||
if (!result)
|
||||
throw DB::Exception("Cannot print float or double number", DB::ErrorCodes::CANNOT_PRINT_FLOAT_OR_DOUBLE_NUMBER);
|
||||
|
||||
out.write(tmp, builder.position());
|
||||
out.write(buffer, builder.position());
|
||||
writeCString(units[i], out);
|
||||
}
|
||||
|
||||
|
@ -34,15 +34,15 @@ String FieldVisitorDump::operator() (const Array & x) const
|
||||
|
||||
String FieldVisitorToString::formatFloat(const Float64 x)
|
||||
{
|
||||
char tmp[25];
|
||||
double_conversion::StringBuilder builder{tmp, sizeof(tmp)};
|
||||
DoubleConverter<false>::BufferType buffer;
|
||||
double_conversion::StringBuilder builder{buffer, sizeof(buffer)};
|
||||
|
||||
const auto result = getDoubleToStringConverter().ToShortest(x, &builder);
|
||||
const auto result = DoubleConverter<false>::instance().ToShortest(x, &builder);
|
||||
|
||||
if (!result)
|
||||
throw Exception("Cannot print float or double number", ErrorCodes::CANNOT_PRINT_FLOAT_OR_DOUBLE_NUMBER);
|
||||
|
||||
return { tmp, tmp + builder.position() };
|
||||
return { buffer, buffer + builder.position() };
|
||||
}
|
||||
|
||||
String FieldVisitorToString::operator() (const Array & x) const
|
||||
|
@ -35,10 +35,10 @@ static void numWidthConstant(T a, UInt64 & c)
|
||||
|
||||
inline UInt64 floatWidth(const double x)
|
||||
{
|
||||
char tmp[25];
|
||||
double_conversion::StringBuilder builder{tmp, sizeof(tmp)};
|
||||
DoubleConverter<false>::BufferType buffer;
|
||||
double_conversion::StringBuilder builder{buffer, sizeof(buffer)};
|
||||
|
||||
const auto result = getDoubleToStringConverter<false>().ToShortest(x, &builder);
|
||||
const auto result = DoubleConverter<false>::instance().ToShortest(x, &builder);
|
||||
|
||||
if (!result)
|
||||
throw Exception("Cannot print double number", ErrorCodes::CANNOT_PRINT_FLOAT_OR_DOUBLE_NUMBER);
|
||||
@ -48,10 +48,10 @@ inline UInt64 floatWidth(const double x)
|
||||
|
||||
inline UInt64 floatWidth(const float x)
|
||||
{
|
||||
char tmp[25];
|
||||
double_conversion::StringBuilder builder{tmp, sizeof(tmp)};
|
||||
DoubleConverter<false>::BufferType buffer;
|
||||
double_conversion::StringBuilder builder{buffer, sizeof(buffer)};
|
||||
|
||||
const auto result = getDoubleToStringConverter<false>().ToShortestSingle(x, &builder);
|
||||
const auto result = DoubleConverter<false>::instance().ToShortestSingle(x, &builder);
|
||||
|
||||
if (!result)
|
||||
throw Exception("Cannot print float number", ErrorCodes::CANNOT_PRINT_FLOAT_OR_DOUBLE_NUMBER);
|
||||
|
Loading…
Reference in New Issue
Block a user