[Enhancement] function hour_from_unixtime (#60331)

Signed-off-by: Murphy <mofei@starrocks.com>
This commit is contained in:
Murphy 2025-07-10 16:16:51 +08:00 committed by GitHub
parent 31168b0ac1
commit d9b23cffb4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 445 additions and 3 deletions

View File

@ -17,11 +17,16 @@
#include <gtest/gtest.h>
#include <testutil/assert.h>
#include <chrono>
#include <memory>
#include <random>
#include <vector>
#include "bench/bench_util.h"
#include "exprs/hash_functions.h"
#include "exprs/time_functions.h"
#include "runtime/runtime_state.h"
#include "testutil/function_utils.h"
#include "util/hash.h"
#include "util/phmap/phmap.h"
@ -201,6 +206,88 @@ BENCHMARK(BM_PhmapFlatHashSet_CrcHash64_Insert_Unmixed)->Arg(10 * 1000)->Arg(100
BENCHMARK(BM_PhmapFlatHashSet_CrcHash64_Lookup)->Arg(10 * 1000)->Arg(100 * 1000)->Arg(1000 * 1000);
BENCHMARK(BM_PhmapFlatHashSet_CrcHash64_Lookup_Unmixed)->Arg(10 * 1000)->Arg(100 * 1000)->Arg(1000 * 1000);
class HourFromUnixtimeBench {
public:
HourFromUnixtimeBench(int N = 4096)
: N(N), min_ts(946684800), max_ts(1893456000), rng(12345), dist(min_ts, max_ts) {
// Generate N random unix timestamps
timestamps.reserve(N);
for (int i = 0; i < N; ++i) {
timestamps.push_back(dist(rng));
}
// Construct Column
col = Int64Column::create();
for (int i = 0; i < N; ++i) {
col->append(timestamps[i]);
}
columns.emplace_back(col);
// Construct context
globals.__set_now_string("2020-01-01 00:00:00");
globals.__set_timestamp_ms(1577836800000);
globals.__set_time_zone("UTC");
state = std::make_unique<starrocks::RuntimeState>(globals);
utils = std::make_unique<starrocks::FunctionUtils>(state.get());
}
void bench_hour_from_unixtime(benchmark::State& state_bench) {
for (auto _ : state_bench) {
auto result = starrocks::TimeFunctions::hour_from_unixtime(utils->get_fn_ctx(), columns).value();
benchmark::DoNotOptimize(result);
}
}
void bench_from_unixtime_extract_hour(benchmark::State& state_bench) {
for (auto _ : state_bench) {
auto dt_col_ptr = starrocks::TimeFunctions::from_unix_to_datetime_64(utils->get_fn_ctx(), columns).value();
auto dt_col = starrocks::ColumnHelper::cast_to<starrocks::TYPE_DATETIME>(dt_col_ptr);
int64_t sum = 0;
for (int i = 0; i < N; ++i) {
int year, month, day, hour, minute, second, usec;
dt_col->get_data()[i].to_timestamp(&year, &month, &day, &hour, &minute, &second, &usec);
sum += hour;
}
benchmark::DoNotOptimize(sum);
}
}
private:
int N;
int64_t min_ts, max_ts;
std::mt19937_64 rng;
std::uniform_int_distribution<int64_t> dist;
std::vector<int64_t> timestamps;
starrocks::Int64Column::Ptr col;
starrocks::Columns columns;
starrocks::TQueryGlobals globals;
std::unique_ptr<starrocks::RuntimeState> state;
std::unique_ptr<starrocks::FunctionUtils> utils;
};
static void BM_HourFromUnixtime(benchmark::State& state) {
static HourFromUnixtimeBench suite;
suite.bench_hour_from_unixtime(state);
}
static void BM_FromUnixtime_HourExtract(benchmark::State& state) {
static HourFromUnixtimeBench suite;
suite.bench_from_unixtime_extract_hour(state);
}
// Run on (104 X 3200 MHz CPU s)
// CPU Caches:
// L1 Data 32 KiB (x52)
// L1 Instruction 32 KiB (x52)
// L2 Unified 1024 KiB (x52)
// L3 Unified 36608 KiB (x2)
// Load Average: 36.03, 17.40, 21.87
// ----------------------------------------------------------------------
// Benchmark Time CPU Iterations
// ----------------------------------------------------------------------
// BM_HourFromUnixtime 147895 ns 147841 ns 4147
// BM_FromUnixtime_HourExtract 656650 ns 651969 ns 1445
BENCHMARK(BM_HourFromUnixtime);
BENCHMARK(BM_FromUnixtime_HourExtract);
} // namespace starrocks
BENCHMARK_MAIN();

View File

@ -14,7 +14,11 @@
#include "exprs/time_functions.h"
#include <cctz/time_zone.h>
#include <libdivide.h>
#include <algorithm>
#include <mutex>
#include <string_view>
#include <unordered_map>
@ -22,7 +26,6 @@
#include "column/column_viewer.h"
#include "exprs/binary_function.h"
#include "exprs/unary_function.h"
#include "gen_cpp/InternalService_types.h"
#include "runtime/datetime_value.h"
#include "runtime/runtime_state.h"
#include "types/date_value.h"
@ -1489,7 +1492,6 @@ StatusOr<ColumnPtr> TimeFunctions::_t_from_unix_to_datetime(FunctionContext* con
DCHECK_EQ(columns.size(), 1);
RETURN_IF_COLUMNS_ONLY_NULL(columns);
ColumnViewer<TIMESTAMP_TYPE> data_column(columns[0]);
auto size = columns[0]->size();
@ -1566,6 +1568,55 @@ StatusOr<ColumnPtr> TimeFunctions::from_unix_to_datetime_ms_64(FunctionContext*
return _t_from_unix_to_datetime_ms<TYPE_BIGINT>(context, columns);
}
static inline int64_t impl_hour_from_unixtime(int64_t unixtime) {
// return (unixtime % 86400) / 3600;
static const libdivide::divider<int64_t> fast_div_3600(3600);
static const libdivide::divider<int64_t> fast_div_86400(86400);
int64_t hour = (unixtime - unixtime / fast_div_86400 * 86400) / fast_div_3600;
return hour;
}
StatusOr<ColumnPtr> TimeFunctions::hour_from_unixtime(FunctionContext* context, const Columns& columns) {
DCHECK_EQ(columns.size(), 1);
RETURN_IF_COLUMNS_ONLY_NULL(columns);
static const auto epoch =
std::chrono::time_point_cast<cctz::sys_seconds>(std::chrono::system_clock::from_time_t(0));
auto ctz = context->state()->timezone_obj();
auto size = columns[0]->size();
ColumnViewer<TYPE_BIGINT> data_column(columns[0]);
ColumnBuilder<TYPE_INT> result(size);
std::vector<int64_t> batch;
for (int row = 0; row < size; ++row) {
if (data_column.is_null(row)) {
result.append_null();
continue;
}
auto date = data_column.value(row);
if (date < 0 || date > MAX_UNIX_TIMESTAMP) {
result.append_null();
continue;
}
batch.push_back(date);
if (batch.size() == 16 || row == size - 1) {
for (int i = 0; i < batch.size(); i++) {
int64_t dt = batch[i];
cctz::time_point<cctz::sys_seconds> t = epoch + cctz::seconds(dt);
int offset = ctz.lookup_offset(t).offset;
int hour = impl_hour_from_unixtime(dt + offset);
result.append(hour);
}
batch.clear();
}
}
return result.build(ColumnHelper::is_all_const(columns));
}
std::string TimeFunctions::convert_format(const Slice& format) {
switch (format.get_size()) {
case 8:

View File

@ -705,6 +705,14 @@ public:
DEFINE_VECTORIZED_FN(from_unix_to_datetime_32);
DEFINE_VECTORIZED_FN(from_unix_to_datetime_ms_64);
// TODO
// DEFINE_VECTORIZED_FN(year_from_unixtime);
// DEFINE_VECTORIZED_FN(month_from_unixtime);
// DEFINE_VECTORIZED_FN(day_from_unixtime);
DEFINE_VECTORIZED_FN(hour_from_unixtime);
// DEFINE_VECTORIZED_FN(minute_from_unixtime);
// DEFINE_VECTORIZED_FN(second_from_unixtime);
// from_unix_datetime with format's auxiliary method
static Status from_unix_prepare(FunctionContext* context, FunctionContext::FunctionStateScope scope);

View File

@ -201,6 +201,15 @@ void RuntimeState::_init(const TUniqueId& fragment_instance_id, const TQueryOpti
_runtime_filter_port = _obj_pool->add(new RuntimeFilterPort(this));
}
bool RuntimeState::set_timezone(const std::string& tz) {
if (TimezoneUtils::find_cctz_time_zone(tz, _timezone_obj)) {
_timezone = tz;
return true;
} else {
return false;
}
}
void RuntimeState::init_mem_trackers(const TUniqueId& query_id, MemTracker* parent) {
bool has_query_mem_tracker = _query_options.__isset.mem_limit && (_query_options.mem_limit > 0);
int64_t bytes_limit = has_query_mem_tracker ? _query_options.mem_limit : -1;

View File

@ -137,6 +137,7 @@ public:
int64_t timestamp_us() const { return _timestamp_us; }
const std::string& timezone() const { return _timezone; }
const cctz::time_zone& timezone_obj() const { return _timezone_obj; }
bool set_timezone(const std::string& tz);
const std::string& user() const { return _user; }
const std::string& last_query_id() const { return _last_query_id; }
const TUniqueId& query_id() const { return _query_id; }

View File

View File

@ -38,6 +38,7 @@
#include "testutil/function_utils.h"
#include "types/date_value.h"
#include "types/logical_type.h"
#include "util/defer_op.h"
namespace starrocks {
@ -4103,4 +4104,40 @@ TEST_F(TimeFunctionsTest, IcbergTransTest) {
ASSERT_EQ(1, v->get_data()[0]);
}
}
TEST_F(TimeFunctionsTest, hourFromUnixtimeTest) {
Int64Column::Ptr tc = Int64Column::create();
// 1970-01-01 00:00:00 UTC
tc->append(0); // hour = 0
// 1970-01-01 01:00:00 UTC
tc->append(3600); // hour = 1
// 1970-01-01 12:34:56 UTC
tc->append(45296); // hour = 12
// 1970-01-01 23:59:59 UTC
tc->append(86399); // hour = 23
// 1970-01-02 00:00:00 UTC
tc->append(86400); // hour = 0
// 2000-01-01 08:00:00 UTC (946713600)
tc->append(946713600); // hour = 8
int expected[] = {0, 1, 12, 23, 0, 8};
// Change timezone to UTC
RuntimeState* state = _utils->get_fn_ctx()->state();
std::string prev_timezone = state->timezone();
ASSERT_TRUE(state->set_timezone("UTC"));
DeferOp defer([&]() { state->set_timezone(prev_timezone); });
Columns columns;
columns.emplace_back(tc);
ColumnPtr result = TimeFunctions::hour_from_unixtime(_utils->get_fn_ctx(), columns).value();
ASSERT_TRUE(result->is_numeric());
ASSERT_FALSE(result->is_nullable());
auto hours = ColumnHelper::cast_to<TYPE_INT>(result);
for (size_t i = 0; i < sizeof(expected) / sizeof(expected[0]); ++i) {
EXPECT_EQ(expected[i], hours->get_data()[i]);
}
}
} // namespace starrocks

View File

@ -586,6 +586,14 @@ vectorized_functions = [
'TimeFunctions::from_unix_to_datetime_with_format_32',
'TimeFunctions::from_unix_prepare', 'TimeFunctions::from_unix_close'],
# specialized version of from_unixtime to reduce the cost of datetime conversion
# TODO: 50380 year_from_unixtime
# TODO: 50381 month_from_unixtime
# TODO: 50382 day_from_unixtime
[50383, 'hour_from_unixtime', True, False, 'INT', ['BIGINT'], 'TimeFunctions::hour_from_unixtime'],
# TODO: 50384 minute_from_unixtime
# TODO: 50385 second_from_unixtime
[50310, 'dayname', True, False, 'VARCHAR', ['DATETIME'], 'TimeFunctions::day_name'],
[50311, 'monthname', True, False, 'VARCHAR', ['DATETIME'], 'TimeFunctions::month_name'],
[50320, 'convert_tz', True, False, 'DATETIME', ['DATETIME', 'VARCHAR', 'VARCHAR'], 'TimeFunctions::convert_tz',

View File

@ -1614,6 +1614,16 @@ build_azure() {
unset PKG_CONFIG_LIBDIR
}
build_libdivide() {
check_if_source_exist $LIBDIVIDE_SOURCE
cd $TP_SOURCE_DIR/$LIBDIVIDE_SOURCE
$CMAKE_CMD . -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX:PATH=$TP_INSTALL_DIR/
${BUILD_SYSTEM} -j "${PARALLEL}"
${BUILD_SYSTEM} install
}
# restore cxxflags/cppflags/cflags to default one
restore_compile_flags() {
# c preprocessor flags
@ -1715,6 +1725,7 @@ declare -a all_packages=(
xsimd
libxml2
azure
libdivide
)
# Machine specific packages

View File

@ -620,6 +620,7 @@ if [[ -d $TP_SOURCE_DIR/$CCTZ_SOURCE ]] ; then
cd $TP_SOURCE_DIR/$CCTZ_SOURCE
if [ ! -f "$PATCHED_MARK" ] && [[ $CCTZ_SOURCE == "cctz-2.3" ]] ; then
patch -p1 < "$TP_PATCH_DIR/cctz_civil_cache.patch"
patch -p1 < "$TP_PATCH_DIR/cctz_02_lookup_offset.patch"
touch "$PATCHED_MARK"
fi
cd -

View File

@ -0,0 +1,223 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e8b2f34..97b34ac 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -178,3 +178,5 @@ install(FILES cmake/${PROJECT_NAME}-config.cmake
)
feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
+
+SET(CMAKE_CXX_FLAGS "-fno-omit-frame-pointer -O3 -g -gdwarf-4 ${CMAKE_CXX_FLAGS}")
diff --git a/include/cctz/civil_time_detail.h b/include/cctz/civil_time_detail.h
index decc5f2..3f7d6c8 100644
--- a/include/cctz/civil_time_detail.h
+++ b/include/cctz/civil_time_detail.h
@@ -186,13 +186,13 @@ CONSTEXPR_F fields n_min(year_t y, diff_t m, diff_t d, diff_t hh, diff_t ch,
CONSTEXPR_F fields n_sec(year_t y, diff_t m, diff_t d, diff_t hh, diff_t mm,
diff_t ss) noexcept {
// Optimization for when (non-constexpr) fields are already normalized.
- if (0 <= ss && ss < 60) {
+ if (__builtin_expect(0 <= ss && ss < 60, 1)) {
const second_t nss = static_cast<second_t>(ss);
- if (0 <= mm && mm < 60) {
+ if (__builtin_expect(0 <= mm && mm < 60, 1)) {
const minute_t nmm = static_cast<minute_t>(mm);
- if (0 <= hh && hh < 24) {
+ if (__builtin_expect(0 <= hh && hh < 24, 1)) {
const hour_t nhh = static_cast<hour_t>(hh);
- if (1 <= d && d <= 28 && 1 <= m && m <= 12) {
+ if (__builtin_expect(1 <= d && d <= 28 && 1 <= m && m <= 12, 1)) {
const day_t nd = static_cast<day_t>(d);
const month_t nm = static_cast<month_t>(m);
return fields(y, nm, nd, nhh, nmm, nss);
diff --git a/include/cctz/time_zone.h b/include/cctz/time_zone.h
index f97ea26..cdbd6a9 100644
--- a/include/cctz/time_zone.h
+++ b/include/cctz/time_zone.h
@@ -104,6 +104,14 @@ class time_zone {
return lookup(detail::split_seconds(tp).first);
}
+ // Lookup the UTC offset for a timepoint
+ // The returned the lookup result doesn't contain valid cs
+ absolute_lookup lookup_offset(const time_point<seconds> &tp) const;
+ template <typename D>
+ absolute_lookup lookup_offset(const time_point<D> &tp) const {
+ return lookup_offset(detail::split_seconds(tp).first);
+ }
+
// A civil_lookup represents the absolute time(s) (time_point) that
// correspond to the given civil time (cctz::civil_second) within this
// time_zone. Usually the given civil time represents a unique instant
diff --git a/src/cctz_benchmark.cc b/src/cctz_benchmark.cc
index 179ae50..168cba5 100644
--- a/src/cctz_benchmark.cc
+++ b/src/cctz_benchmark.cc
@@ -797,6 +797,24 @@ void BM_Time_ToCivil_CCTZ(benchmark::State& state) {
}
BENCHMARK(BM_Time_ToCivil_CCTZ);
+void BM_Time_ToCivil_LookupOffset_Batch1024(benchmark::State &state) {
+ const cctz::time_zone tz = TestTimeZone();
+ std::chrono::system_clock::time_point tp =
+ std::chrono::system_clock::from_time_t(1750656243);
+ std::chrono::system_clock::time_point tp2 =
+ std::chrono::system_clock::from_time_t(1750656245);
+ while (state.KeepRunning()) {
+ std::swap(tp, tp2);
+ // benchmark::DoNotOptimize(tz.lookup(tp).cs);
+
+ for (int i = 0; i < 1024; i++) {
+ tp += std::chrono::seconds(1);
+ benchmark::DoNotOptimize(tz.lookup_offset(tp).cs);
+ }
+ }
+}
+BENCHMARK(BM_Time_ToCivil_LookupOffset_Batch1024);
+
void BM_Time_ToCivil_Libc(benchmark::State& state) {
// No timezone support, so just use localtime.
time_t t = 1384569027;
diff --git a/src/time_zone_if.h b/src/time_zone_if.h
index f925c6c..01af988 100644
--- a/src/time_zone_if.h
+++ b/src/time_zone_if.h
@@ -36,6 +36,10 @@ class TimeZoneIf {
virtual time_zone::absolute_lookup BreakTime(
const time_point<seconds>& tp) const = 0;
+ virtual time_zone::absolute_lookup
+ LookupOffset(const time_point<seconds> &tp) const {
+ return BreakTime(tp);
+ }
virtual time_zone::civil_lookup MakeTime(
const civil_second& cs) const = 0;
diff --git a/src/time_zone_impl.h b/src/time_zone_impl.h
index 23fcddb..16f26ec 100644
--- a/src/time_zone_impl.h
+++ b/src/time_zone_impl.h
@@ -50,6 +50,10 @@ class time_zone::Impl {
return zone_->BreakTime(tp);
}
+ time_zone::absolute_lookup LookupOffset(const time_point<seconds> &tp) const {
+ return zone_->LookupOffset(tp);
+ }
+
// Converts the civil-time components in this time zone into a time_point.
// That is, the opposite of BreakTime(). The requested civil time may be
// ambiguous or illegal due to a change of UTC offset.
diff --git a/src/time_zone_info.cc b/src/time_zone_info.cc
index eb1cd8a..031c8c4 100644
--- a/src/time_zone_info.cc
+++ b/src/time_zone_info.cc
@@ -751,6 +751,64 @@ time_zone::absolute_lookup TimeZoneInfo::LocalTime(
tt.utc_offset, tt.is_dst, &abbreviations_[tt.abbr_index]};
}
+time_zone::absolute_lookup
+TimeZoneInfo::Offset(std::int_fast64_t unix_time,
+ const TransitionType &tt) const {
+ return {{}, tt.utc_offset, tt.is_dst, &abbreviations_[tt.abbr_index]};
+}
+
+time_zone::absolute_lookup TimeZoneInfo::Offset(std::int_fast64_t unix_time,
+ const Transition &tr) const {
+ const TransitionType &tt = transition_types_[tr.type_index];
+ // std::int_fast64_t local_unix = unix_time + tt.utc_offset;
+ return {{}, tt.utc_offset, tt.is_dst, &abbreviations_[tt.abbr_index]};
+}
+
+time_zone::absolute_lookup
+TimeZoneInfo::LookupOffset(const time_point<seconds> &tp) const {
+ std::int_fast64_t unix_time = ToUnixSeconds(tp);
+ const std::size_t timecnt = transitions_.size();
+ assert(timecnt != 0); // We always add a transition.
+
+ const std::size_t hint = local_time_hint_.load(std::memory_order_relaxed);
+ // This branch is likely to be taken if the hint is valid and the unix_time
+ // falls within the hinted transition range.
+ if (0 < hint && hint < timecnt) [[likely]] {
+ if (transitions_[hint - 1].unix_time <= unix_time) [[likely]] {
+ if (unix_time < transitions_[hint].unix_time) [[likely]] {
+ return Offset(unix_time, transitions_[hint - 1]);
+ }
+ }
+ }
+
+ if ((unix_time < transitions_[0].unix_time)) {
+ return Offset(unix_time, transition_types_[default_transition_type_]);
+ }
+ if (unix_time >= transitions_.back().unix_time) {
+ // After the last transition. If we extended the transitions using
+ // future_spec_, shift back to a supported year using the 400-year
+ // cycle of calendaric equivalence and then compensate accordingly.
+ if (extended_) {
+ const std::int_fast64_t diff =
+ unix_time - transitions_[timecnt - 1].unix_time;
+ const year_t shift = diff / kSecsPer400Years + 1;
+ const auto d = seconds(shift * kSecsPer400Years);
+ time_zone::absolute_lookup al = BreakTime(tp - d);
+ al.cs = YearShift(al.cs, shift * 400);
+ return al;
+ }
+ return Offset(unix_time, transitions_[timecnt - 1]);
+ }
+
+ const Transition target = {unix_time, 0, civil_second(), civil_second()};
+ const Transition *begin = &transitions_[0];
+ const Transition *tr = std::upper_bound(begin, begin + timecnt, target,
+ Transition::ByUnixTime());
+ local_time_hint_.store(static_cast<std::size_t>(tr - begin),
+ std::memory_order_relaxed);
+ return Offset(unix_time, *--tr);
+}
+
// BreakTime() translation for a particular transition.
time_zone::absolute_lookup TimeZoneInfo::LocalTime(
std::int_fast64_t unix_time, const Transition& tr) const {
diff --git a/src/time_zone_info.h b/src/time_zone_info.h
index 4657a2d..dea4431 100644
--- a/src/time_zone_info.h
+++ b/src/time_zone_info.h
@@ -70,6 +70,8 @@ class TimeZoneInfo : public TimeZoneIf {
// TimeZoneIf implementations.
time_zone::absolute_lookup BreakTime(
const time_point<seconds>& tp) const override;
+ time_zone::absolute_lookup
+ LookupOffset(const time_point<seconds> &tp) const override;
time_zone::civil_lookup MakeTime(
const civil_second& cs) const override;
bool NextTransition(const time_point<seconds>& tp,
@@ -103,8 +105,13 @@ class TimeZoneInfo : public TimeZoneIf {
bool Load(const std::string& name, ZoneInfoSource* zip);
// Helpers for BreakTime() and MakeTime().
+ time_zone::absolute_lookup Offset(std::int_fast64_t unix_time,
+ const Transition &tr) const;
+ time_zone::absolute_lookup Offset(std::int_fast64_t unix_time,
+ const TransitionType &tt) const;
+
time_zone::absolute_lookup LocalTime(std::int_fast64_t unix_time,
- const TransitionType& tt) const;
+ const TransitionType &tt) const;
time_zone::absolute_lookup LocalTime(std::int_fast64_t unix_time,
const Transition& tr) const;
time_zone::civil_lookup TimeLocal(const civil_second& cs,
diff --git a/src/time_zone_lookup.cc b/src/time_zone_lookup.cc
index 2a38a9b..a97ac2f 100644
--- a/src/time_zone_lookup.cc
+++ b/src/time_zone_lookup.cc
@@ -73,6 +73,11 @@ time_zone::absolute_lookup time_zone::lookup(
return effective_impl().BreakTime(tp);
}
+time_zone::absolute_lookup
+time_zone::lookup_offset(const time_point<seconds> &tp) const {
+ return effective_impl().LookupOffset(tp);
+}
+
time_zone::civil_lookup time_zone::lookup(const civil_second& cs) const {
return effective_impl().MakeTime(cs);
}

8
thirdparty/vars.sh vendored
View File

@ -470,9 +470,15 @@ AZURE_NAME="azure-storage-files-shares_12.12.0.tar.gz"
AZURE_SOURCE="azure-storage-files-shares_12.12.0"
AZURE_MD5SUM="cb38786198aa103295d4d670604a9a60"
# libdivide
LIBDIVIDE_DOWNLOAD="https://github.com/ridiculousfish/libdivide/archive/refs/tags/v5.2.0.tar.gz"
LIBDIVIDE_NAME="libdivide-v5.2.0.tar.gz"
LIBDIVIDE_SOURCE="libdivide-v5.2.0"
LIBDIVIDE_MD5SUM="4ba77777192c295d6de2b86d88f3239a"
# all thirdparties which need to be downloaded is set in array TP_ARCHIVES
TP_ARCHIVES="CLUCENE LIBEVENT OPENSSL THRIFT PROTOBUF GFLAGS GLOG GTEST RAPIDJSON SIMDJSON SNAPPY GPERFTOOLS ZLIB LZ4 BZIP CURL \
RE2 BOOST LEVELDB BRPC ROCKSDB KRB5 SASL LIBRDKAFKA PULSAR FLATBUFFERS ARROW BROTLI ZSTD S2 BITSHUFFLE CROARINGBITMAP \
JEMALLOC CCTZ FMT RYU BREAK_PAD HADOOP JDK RAGEL HYPERSCAN MARIADB JINDOSDK AWS_SDK_CPP VPACK OPENTELEMETRY \
BENCHMARK FAST_FLOAT STARCACHE STREAMVBYTE JANSSON AVRO SERDES GCS_CONNECTOR LZO2 DATASKETCHES \
ASYNC_PROFILER FIU LIBDEFLATE LLVM ABSL CARES GRPC SIMDUTF TENANN POCO ICU XSIMD LIBXML2 AZURE"
ASYNC_PROFILER FIU LIBDEFLATE LLVM ABSL CARES GRPC SIMDUTF TENANN POCO ICU XSIMD LIBXML2 AZURE LIBDIVIDE"