This is an automated email from the ASF dual-hosted git repository. yiguolei pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push: new 93eedaff626 [opt](function) Use Dict to opt the function of time_round (#25029) 93eedaff626 is described below commit 93eedaff626af6f3e9e8a75944609614dfd3b489 Author: HappenLee <happen...@hotmail.com> AuthorDate: Wed Oct 4 23:34:24 2023 +0800 [opt](function) Use Dict to opt the function of time_round (#25029) Beforeļ¼ select hour_floor(`@timestamp`, 7) as t, count() as cnt from httplogs_date group by t order by t limit 10; +---------------------+--------+ | t | cnt | +---------------------+--------+ | 1998-04-30 21:00:00 | 324 | | 1998-05-01 04:00:00 | 286156 | | 1998-05-01 11:00:00 | 266130 | | 1998-05-01 18:00:00 | 483765 | | 1998-05-02 01:00:00 | 276706 | | 1998-05-02 08:00:00 | 169945 | | 1998-05-02 15:00:00 | 223593 | | 1998-05-02 22:00:00 | 272616 | | 1998-05-03 05:00:00 | 188689 | | 1998-05-03 12:00:00 | 184405 | +---------------------+--------+ 10 rows in set (3.39 sec) after: select hour_floor(`@timestamp`, 7) as t, count() as cnt from httplogs_date group by t order by t limit 10; +---------------------+--------+ | t | cnt | +---------------------+--------+ | 1998-04-30 21:00:00 | 324 | | 1998-05-01 04:00:00 | 286156 | | 1998-05-01 11:00:00 | 266130 | | 1998-05-01 18:00:00 | 483765 | | 1998-05-02 01:00:00 | 276706 | | 1998-05-02 08:00:00 | 169945 | | 1998-05-02 15:00:00 | 223593 | | 1998-05-02 22:00:00 | 272616 | | 1998-05-03 05:00:00 | 188689 | | 1998-05-03 12:00:00 | 184405 | +---------------------+--------+ 10 rows in set (2.19 sec) --- be/src/util/time_lut.cpp | 8 +++ .../vec/functions/function_datetime_floor_ceil.cpp | 2 +- be/src/vec/runtime/vdatetime_value.cpp | 76 +++++++++++++++------- be/src/vec/runtime/vdatetime_value.h | 19 +++++- 4 files changed, 79 insertions(+), 26 deletions(-) diff --git a/be/src/util/time_lut.cpp b/be/src/util/time_lut.cpp index bc37847fe18..bab5a6bdd55 100644 --- a/be/src/util/time_lut.cpp +++ b/be/src/util/time_lut.cpp @@ -18,6 +18,8 @@ #include "util/time_lut.h" +#include "vec/runtime/vdatetime_value.h" + namespace doris { TimeLUTImpl::TimeLUTImpl() { init_time_lut(); @@ -94,6 +96,12 @@ uint8_t calc_weekday(uint64_t day_nr, bool is_sunday_first_day) { } uint32_t calc_daynr(uint16_t year, uint8_t month, uint8_t day) { + // date_day_offet_dict range from [1900-01-01, 2039-10-24] + if (vectorized::date_day_offset_dict::can_speed_up_calc_daynr(year) && + LIKELY(vectorized::date_day_offset_dict::get_dict_init())) { + return vectorized::date_day_offset_dict::get().daynr(year, month, day); + } + uint32_t delsum = 0; int y = year; diff --git a/be/src/vec/functions/function_datetime_floor_ceil.cpp b/be/src/vec/functions/function_datetime_floor_ceil.cpp index b66cd5c0b60..6ef3bfce5c0 100644 --- a/be/src/vec/functions/function_datetime_floor_ceil.cpp +++ b/be/src/vec/functions/function_datetime_floor_ceil.cpp @@ -743,7 +743,7 @@ struct TimeRound { //round down/up inside time period(several time-units) int64_t count = period; - int64_t delta_inside_period = (diff % count + count) % count; + int64_t delta_inside_period = diff >= 0 ? diff % count : (diff % count + count) % count; int64_t step = diff - delta_inside_period + (Impl::Type == FLOOR ? 0 : delta_inside_period == 0 ? 0 diff --git a/be/src/vec/runtime/vdatetime_value.cpp b/be/src/vec/runtime/vdatetime_value.cpp index 5ff6d9163ba..44e2cc0a69e 100644 --- a/be/src/vec/runtime/vdatetime_value.cpp +++ b/be/src/vec/runtime/vdatetime_value.cpp @@ -2656,27 +2656,42 @@ typename DateV2Value<T>::underlying_value DateV2Value<T>::to_date_int_val() cons static std::array<DateV2Value<DateV2ValueType>, date_day_offset_dict::DICT_DAYS> DATE_DAY_OFFSET_ITEMS; + +static std::array<std::array<std::array<int, 31>, 12>, 140> DATE_DAY_OFFSET_DICT; + +static bool DATE_DAY_OFFSET_ITEMS_INIT = false; + date_day_offset_dict date_day_offset_dict::instance = date_day_offset_dict(); date_day_offset_dict& date_day_offset_dict::get() { return instance; } +bool date_day_offset_dict::get_dict_init() { + return DATE_DAY_OFFSET_ITEMS_INIT; +} + date_day_offset_dict::date_day_offset_dict() { DateV2Value<DateV2ValueType> d; d.set_time(1969, 12, 31, 0, 0, 0, 0); for (int i = 0; i < DAY_AFTER_EPOCH; ++i) { DATE_DAY_OFFSET_ITEMS[DAY_BEFORE_EPOCH + i] = d; + DATE_DAY_OFFSET_DICT[d.year() - START_YEAR][d.month() - 1][d.day() - 1] = + calc_daynr(d.year(), d.month(), d.day()); d += 1; } d.set_time(1969, 12, 31, 0, 0, 0, 0); for (int i = 0; i <= DAY_BEFORE_EPOCH; ++i) { DATE_DAY_OFFSET_ITEMS[DAY_BEFORE_EPOCH - i] = d; + DATE_DAY_OFFSET_DICT[d.year() - START_YEAR][d.month() - 1][d.day() - 1] = + calc_daynr(d.year(), d.month(), d.day()); d -= 1; } + + DATE_DAY_OFFSET_ITEMS_INIT = true; } -DateV2Value<DateV2ValueType> date_day_offset_dict::operator[](int day) { +DateV2Value<DateV2ValueType> date_day_offset_dict::operator[](int day) const { int index = day + DAY_BEFORE_EPOCH; if (LIKELY(index >= 0 && index < DICT_DAYS)) { return DATE_DAY_OFFSET_ITEMS[index]; @@ -2686,6 +2701,10 @@ DateV2Value<DateV2ValueType> date_day_offset_dict::operator[](int day) { } } +int date_day_offset_dict::daynr(int year, int month, int day) const { + return DATE_DAY_OFFSET_DICT[year - START_YEAR][month - 1][day - 1]; +} + template <typename T> uint32_t DateV2Value<T>::set_date_uint32(uint32_t int_val) { union DateV2UInt32Union { @@ -2756,34 +2775,43 @@ bool DateV2Value<T>::get_date_from_daynr(uint64_t daynr) { if (daynr <= 0 || daynr > DATE_MAX_DAYNR) { return false; } - auto [year, month, day] = std::tuple {0, 0, 0}; - year = daynr / 365; - uint32_t days_befor_year = 0; - while (daynr < (days_befor_year = doris::calc_daynr(year, 1, 1))) { - year--; - } - uint32_t days_of_year = daynr - days_befor_year + 1; - int leap_day = 0; - if (doris::is_leap(year)) { - if (days_of_year > 31 + 28) { - days_of_year--; - if (days_of_year == 31 + 28) { - leap_day = 1; + + if (date_day_offset_dict::can_speed_up_daynr_to_date(daynr) && + LIKELY(date_day_offset_dict::get_dict_init())) { + auto dt = date_day_offset_dict::get()[date_day_offset_dict::get_offset_by_daynr(daynr)]; + year = dt.year(); + month = dt.month(); + day = dt.day(); + } else { + year = daynr / 365; + uint32_t days_befor_year = 0; + while (daynr < (days_befor_year = doris::calc_daynr(year, 1, 1))) { + year--; + } + uint32_t days_of_year = daynr - days_befor_year + 1; + int leap_day = 0; + if (doris::is_leap(year)) { + if (days_of_year > 31 + 28) { + days_of_year--; + if (days_of_year == 31 + 28) { + leap_day = 1; + } } } - } - month = 1; - while (days_of_year > s_days_in_month[month]) { - days_of_year -= s_days_in_month[month]; - month++; - } - day = days_of_year + leap_day; + month = 1; + while (days_of_year > s_days_in_month[month]) { + days_of_year -= s_days_in_month[month]; + month++; + } + day = days_of_year + leap_day; - if (is_invalid(year, month, day, this->hour(), this->minute(), this->second(), - this->microsecond())) { - return false; + if (is_invalid(year, month, day, this->hour(), this->minute(), this->second(), + this->microsecond())) { + return false; + } } + set_time(year, month, day, this->hour(), this->minute(), this->second(), this->microsecond()); return true; } diff --git a/be/src/vec/runtime/vdatetime_value.h b/be/src/vec/runtime/vdatetime_value.h index 3367c2f7068..1aada274f5e 100644 --- a/be/src/vec/runtime/vdatetime_value.h +++ b/be/src/vec/runtime/vdatetime_value.h @@ -1524,9 +1524,26 @@ public: static constexpr int DAY_AFTER_EPOCH = 25500; // 2039-10-24 static constexpr int DICT_DAYS = DAY_BEFORE_EPOCH + DAY_AFTER_EPOCH; + static constexpr int START_YEAR = 1900; // 1900-01-01 + static constexpr int END_YEAR = 2039; // 2039-10-24 + static constexpr int DAY_OFFSET_CAL_START_POINT_DAYNR = 719527; // 1969-12-31 + + static bool can_speed_up_calc_daynr(int year) { return year >= START_YEAR && year < END_YEAR; } + + static int get_offset_by_daynr(int daynr) { return daynr - DAY_OFFSET_CAL_START_POINT_DAYNR; } + + static bool can_speed_up_daynr_to_date(int daynr) { + auto res = get_offset_by_daynr(daynr); + return res >= 0 ? res <= DAY_AFTER_EPOCH : -res <= DAY_BEFORE_EPOCH; + } + static date_day_offset_dict& get(); - DateV2Value<DateV2ValueType> operator[](int day); + static bool get_dict_init(); + + DateV2Value<DateV2ValueType> operator[](int day) const; + + int daynr(int year, int month, int day) const; }; template <typename T> --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org