From 52c1c8a7641430f15b925198556cbdeee8fae4d4 Mon Sep 17 00:00:00 2001 From: Alexey Arno Date: Tue, 19 May 2015 15:39:15 +0300 Subject: [PATCH] dbms: Server: Refactoring. [#METR-15210] --- dbms/include/DB/Functions/FunctionsRound.h | 223 +++++++++------------ 1 file changed, 93 insertions(+), 130 deletions(-) diff --git a/dbms/include/DB/Functions/FunctionsRound.h b/dbms/include/DB/Functions/FunctionsRound.h index 187c83c8563..3762585431e 100644 --- a/dbms/include/DB/Functions/FunctionsRound.h +++ b/dbms/include/DB/Functions/FunctionsRound.h @@ -92,87 +92,19 @@ namespace DB } }; - /// Определение функцией для использования в шаблоне FunctionRounding. + /// Реализация функций округления на низком уровне. template - struct FunctionRoundingImpl + struct RoundingComputation { - static inline void apply(const PODArray & in, size_t scale, typename ColumnVector::Container_t & out) - { - size_t size = in.size(); - for (size_t i = 0; i < size; ++i) - out[i] = in[i]; - } - - static inline T apply(T val, size_t scale) - { - return val; - } }; template - class FunctionRoundingImpl + struct RoundingComputation { - private: using Data = std::array; using Scale = __m128; - public: - static inline void apply(const PODArray & in, size_t scale, typename ColumnVector::Container_t & out) - { - Scale mm_scale; - prepareScale(scale, mm_scale); - - const size_t size = in.size(); - const size_t data_size = std::tuple_size(); - - size_t i; - for (i = 0; i < (size - data_size + 1); i += data_size) - { - Data tmp; - for (size_t j = 0; j < data_size; ++j) - tmp[j] = in[i + j]; - - Data res; - compute(tmp, mm_scale, res); - - for (size_t j = 0; j < data_size; ++j) - out[i + j] = res[j]; - } - - if (i <= (size - 1)) - { - Data tmp{0}; - for (size_t j = 0; (j < data_size) && (i + j) < size; ++j) - tmp[j] = in[i + j]; - - Data res; - compute(tmp, mm_scale, res); - - for (size_t j = 0; (j < data_size) && (i + j) < size; ++j) - out[i + j] = in[i + j]; - } - } - - static inline Float32 apply(Float32 val, size_t scale) - { - if (val == 0) - return val; - else - { - Scale mm_scale; - prepareScale(scale, mm_scale); - - Data tmp{0}; - tmp[0] = val; - - Data res; - compute(tmp, mm_scale, res); - return res[0]; - } - } - - private: static inline void prepareScale(size_t scale, Scale & mm_scale) { Float32 fscale = static_cast(scale); @@ -195,68 +127,11 @@ namespace DB }; template - struct FunctionRoundingImpl + struct RoundingComputation { - private: using Data = std::array; using Scale = __m128d; - public: - static inline void apply(const PODArray & in, size_t scale, typename ColumnVector::Container_t & out) - { - Scale mm_scale; - prepareScale(scale, mm_scale); - - const size_t size = in.size(); - const size_t data_size = std::tuple_size(); - - size_t i; - for (i = 0; i < (size - data_size + 1); i += data_size) - { - Data tmp; - for (size_t j = 0; j < data_size; ++j) - tmp[j] = in[i + j]; - - Data res; - compute(tmp, mm_scale, res); - - for (size_t j = 0; j < data_size; ++j) - out[i + j] = res[j]; - } - - if (i <= (size - 1)) - { - Data tmp{0}; - for (size_t j = 0; (j < data_size) && (i + j) < size; ++j) - tmp[j] = in[i + j]; - - Data res; - compute(tmp, mm_scale, res); - - for (size_t j = 0; (j < data_size) && (i + j) < size; ++j) - out[i + j] = in[i + j]; - } - } - - static inline Float64 apply(Float64 val, size_t scale) - { - if (val == 0) - return val; - else - { - Scale mm_scale; - prepareScale(scale, mm_scale); - - Data tmp{0}; - tmp[0] = val; - - Data res; - compute(tmp, mm_scale, res); - return res[0]; - } - } - - private: static inline void prepareScale(size_t scale, Scale & mm_scale) { Float64 fscale = static_cast(scale); @@ -278,6 +153,94 @@ namespace DB } }; + /// Реализация функций округления на высоком уровне. + + template + struct FunctionRoundingImpl + { + }; + + /// В случае целочисленных значений не выполяется округления. + template + struct FunctionRoundingImpl::value>::type> + { + static inline void apply(const PODArray & in, size_t scale, typename ColumnVector::Container_t & out) + { + size_t size = in.size(); + for (size_t i = 0; i < size; ++i) + out[i] = in[i]; + } + + static inline T apply(T val, size_t scale) + { + return val; + } + }; + + template + struct FunctionRoundingImpl::value>::type> + { + private: + using Op = RoundingComputation; + using Data = typename Op::Data; + using Scale = typename Op::Scale; + + public: + static inline void apply(const PODArray & in, size_t scale, typename ColumnVector::Container_t & out) + { + Scale mm_scale; + Op::prepareScale(scale, mm_scale); + + const size_t size = in.size(); + const size_t data_size = std::tuple_size(); + + size_t i; + for (i = 0; i < (size - data_size + 1); i += data_size) + { + Data tmp; + for (size_t j = 0; j < data_size; ++j) + tmp[j] = in[i + j]; + + Data res; + Op::compute(tmp, mm_scale, res); + + for (size_t j = 0; j < data_size; ++j) + out[i + j] = res[j]; + } + + if (i <= (size - 1)) + { + Data tmp{0}; + for (size_t j = 0; (j < data_size) && (i + j) < size; ++j) + tmp[j] = in[i + j]; + + Data res; + Op::compute(tmp, mm_scale, res); + + for (size_t j = 0; (j < data_size) && (i + j) < size; ++j) + out[i + j] = in[i + j]; + } + } + + static inline T apply(T val, size_t scale) + { + if (val == 0) + return val; + else + { + Scale mm_scale; + Op::prepareScale(scale, mm_scale); + + Data tmp{0}; + tmp[0] = val; + + Data res; + Op::compute(tmp, mm_scale, res); + return res[0]; + } + } + }; + template struct PrecisionForType { @@ -369,7 +332,7 @@ namespace using result = typename FillArrayImpl::result; }; - /** Шаблон для функцией, которые вычисляют приближенное значение входного параметра + /** Шаблон для функций, которые вычисляют приближенное значение входного параметра * типа (U)Int8/16/32/64 или Float32/64 и принимают дополнительный необязятельный * параметр указывающий сколько знаков после запятой оставить (по умолчанию - 0). * Op - функция (round/floor/ceil)