From 5e1b1d4c48e3b5df13c989e1d20ab03d6fd5042c Mon Sep 17 00:00:00 2001 From: Alexey Arno Date: Wed, 8 Jul 2015 20:30:42 +0300 Subject: [PATCH] dbms: Server: Performance improvements. [#METR-15618] --- .../DB/Functions/FunctionsConversion.h | 59 +++++++++++++++++-- dbms/include/DB/Functions/FunctionsDateTime.h | 29 ++++++--- libs/libcommon/src/DateLUT.cpp | 4 +- 3 files changed, 77 insertions(+), 15 deletions(-) diff --git a/dbms/include/DB/Functions/FunctionsConversion.h b/dbms/include/DB/Functions/FunctionsConversion.h index a9ca352ed0c..cc3074c2df4 100644 --- a/dbms/include/DB/Functions/FunctionsConversion.h +++ b/dbms/include/DB/Functions/FunctionsConversion.h @@ -323,6 +323,25 @@ struct DateTimeToStringConverter data_to.resize(write_buffer.count()); } + static void vector_constant(const PODArray & vec_from, ColumnString & vec_to) + { + ColumnString::Chars_t & data_to = vec_to.getChars(); + ColumnString::Offsets_t & offsets_to = vec_to.getOffsets(); + size_t size = vec_from.size(); + data_to.resize(size * 2); + offsets_to.resize(size); + + WriteBufferFromVector write_buffer(data_to); + + for (size_t i = 0; i < size; ++i) + { + formatImpl(vec_from[i], write_buffer); + writeChar(0, write_buffer); + offsets_to[i] = write_buffer.count(); + } + data_to.resize(write_buffer.count()); + } + static void constant_vector(FromFieldType from, const ColumnString::Chars_t & data, const ColumnString::Offsets_t & offsets, ColumnString & vec_to) @@ -366,6 +385,14 @@ struct DateTimeToStringConverter formatImpl(ti, write_buffer); to = std::string(&buf[0], write_buffer.count()); } + + static void constant_constant(FromFieldType from, std::string & to) + { + std::vector buf; + WriteBufferFromVector > write_buffer(buf); + formatImpl(from, write_buffer); + to = std::string(&buf[0], write_buffer.count()); + } }; }} @@ -392,12 +419,12 @@ struct ConvertImpl auto & vec_from = sources->getData(); auto & vec_to = *col_to; - Op::vector_constant(vec_from, "", vec_to); + Op::vector_constant(vec_from, vec_to); } else if (const_source) { std::string res; - Op::constant_constant(const_source->getData(), "", res); + Op::constant_constant(const_source->getData(), res); block.getByPosition(result).column = new ColumnConstString(const_source->size(), res); } else @@ -581,6 +608,22 @@ struct StringToTimestampConverter } } + static void vector_constant(const ColumnString::Chars_t & vec_from, PODArray & vec_to) + { + ReadBuffer read_buffer(const_cast(reinterpret_cast(&vec_from[0])), vec_from.size(), 0); + + char zero = 0; + for (size_t i = 0; i < vec_to.size(); ++i) + { + DataTypeDateTime::FieldType x = 0; + parseImpl(x, read_buffer); + vec_to[i] = x; + readChar(zero, read_buffer); + if (zero != 0) + throw Exception("Cannot parse from string.", ErrorCodes::CANNOT_PARSE_NUMBER); + } + } + static void constant_vector(const std::string & from, const ColumnString::Chars_t & data, const ColumnString::Offsets_t & offsets, PODArray & vec_to) { @@ -616,6 +659,14 @@ struct StringToTimestampConverter to = convertTimestamp(x, local_date_lut, remote_date_lut); } + + static void constant_constant(const std::string & from, ToFieldType & to) + { + ReadBufferFromString read_buffer(from); + DataTypeDateTime::FieldType x = 0; + parseImpl(x, read_buffer); + to = x; + } }; }} @@ -646,12 +697,12 @@ struct ConvertImpl size_t size = sources->size(); vec_to.resize(size); - Op::vector_constant(vec_from, "", vec_to); + Op::vector_constant(vec_from, vec_to); } else if (const_source) { ToFieldType res; - Op::constant_constant(const_source->getData(), "", res); + Op::constant_constant(const_source->getData(), res); block.getByPosition(result).column = new ColumnConst(const_source->size(), res); } else diff --git a/dbms/include/DB/Functions/FunctionsDateTime.h b/dbms/include/DB/Functions/FunctionsDateTime.h index 52f7eae57a7..6b30efd1e33 100644 --- a/dbms/include/DB/Functions/FunctionsDateTime.h +++ b/dbms/include/DB/Functions/FunctionsDateTime.h @@ -130,17 +130,17 @@ struct ToTimeImpl /// При переводе во время, дату будем приравнивать к 1970-01-02. static inline UInt32 execute(UInt32 t, const DateLUTImpl & remote_date_lut, const DateLUTImpl & local_date_lut) { - time_t remote_t = remote_date_lut.toTimeInaccurate(t) + 86400; + time_t remote_ts = remote_date_lut.toTimeInaccurate(t) + 86400; if (&remote_date_lut == &local_date_lut) - return remote_t; + return remote_ts; else { - const auto & values = remote_date_lut.getValues(remote_t); + const auto & values = remote_date_lut.getValues(remote_ts); return local_date_lut.makeDateTime(values.year, values.month, values.day_of_month, - remote_date_lut.toHourInaccurate(remote_t), - remote_date_lut.toMinuteInaccurate(remote_t), - remote_date_lut.toSecondInaccurate(remote_t)); + remote_date_lut.toHourInaccurate(remote_ts), + remote_date_lut.toMinuteInaccurate(remote_ts), + remote_date_lut.toSecondInaccurate(remote_ts)); } } @@ -257,6 +257,13 @@ struct Transformer vec_to[i] = Transform::execute(vec_from[i], remote_date_lut, local_date_lut); } + static void vector_constant(const PODArray & vec_from, PODArray & vec_to) + { + const auto & local_date_lut = DateLUT::instance(); + for (size_t i = 0; i < vec_from.size(); ++i) + vec_to[i] = Transform::execute(vec_from[i], local_date_lut, local_date_lut); + } + static void constant_vector(const FromType & from, const ColumnString::Chars_t & data, const ColumnString::Offsets_t & offsets, PODArray & vec_to) { @@ -279,6 +286,12 @@ struct Transformer const auto & remote_date_lut = DateLUT::instance(data); to = Transform::execute(from, remote_date_lut, local_date_lut); } + + static void constant_constant(const FromType & from, ToType & to) + { + const auto & local_date_lut = DateLUT::instance(); + to = Transform::execute(from, local_date_lut, local_date_lut); + } }; template @@ -304,12 +317,12 @@ struct DateTimeTransformImpl size_t size = vec_from.size(); vec_to.resize(size); - Op::vector_constant(vec_from, "", vec_to); + Op::vector_constant(vec_from, vec_to); } else if (const_source) { ToType res; - Op::constant_constant(const_source->getData(), "", res); + Op::constant_constant(const_source->getData(), res); block.getByPosition(result).column = new ColumnConst(const_source->size(), res); } else diff --git a/libs/libcommon/src/DateLUT.cpp b/libs/libcommon/src/DateLUT.cpp index 24a0604125d..c14834e92e6 100644 --- a/libs/libcommon/src/DateLUT.cpp +++ b/libs/libcommon/src/DateLUT.cpp @@ -91,9 +91,7 @@ DateLUT::DateLUT() const DateLUTImpl & DateLUT::getImplementation(const std::string & time_zone, size_t group_id) const { - static auto & date_lut_table = *date_lut_impl_list; - - auto & wrapper = date_lut_table[group_id]; + auto & wrapper = (*date_lut_impl_list)[group_id]; DateLUTImpl * tmp = wrapper.load(std::memory_order_acquire); if (tmp == nullptr)