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

Reply via email to