Skip to content

Commit

Permalink
Split ArithmeticFunctions Registration
Browse files Browse the repository at this point in the history
  • Loading branch information
majetideepak committed May 2, 2024
1 parent 5ba1b62 commit cb785a6
Show file tree
Hide file tree
Showing 7 changed files with 326 additions and 211 deletions.
113 changes: 0 additions & 113 deletions velox/functions/prestosql/Arithmetic.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
#include <type_traits>

#include "folly/CPortability.h"
#include "velox/common/base/Doubles.h"
#include "velox/common/base/Exceptions.h"
#include "velox/functions/Macros.h"
#include "velox/functions/prestosql/ArithmeticImpl.h"
Expand All @@ -46,118 +45,6 @@ inline constexpr char digits[36] = {

namespace {

template <typename T>
struct PlusFunction {
template <typename TInput>
FOLLY_ALWAYS_INLINE void
call(TInput& result, const TInput& a, const TInput& b) {
result = plus(a, b);
}
};

template <typename T>
struct MinusFunction {
template <typename TInput>
FOLLY_ALWAYS_INLINE void
call(TInput& result, const TInput& a, const TInput& b) {
result = minus(a, b);
}
};

template <typename T>
struct MultiplyFunction {
template <typename TInput>
FOLLY_ALWAYS_INLINE void
call(TInput& result, const TInput& a, const TInput& b) {
result = multiply(a, b);
}
};

// Multiply function for IntervalDayTime * Double and Double * IntervalDayTime.
template <typename T>
struct IntervalMultiplyFunction {
FOLLY_ALWAYS_INLINE double sanitizeInput(double d) {
if UNLIKELY (std::isnan(d)) {
return 0;
}
return d;
}

template <
typename T1,
typename T2,
typename = std::enable_if_t<
(std::is_same_v<T1, int64_t> && std::is_same_v<T2, double>) ||
(std::is_same_v<T1, double> && std::is_same_v<T2, int64_t>)>>
FOLLY_ALWAYS_INLINE void call(int64_t& result, T1 a, T2 b) {
double resultDouble;
if constexpr (std::is_same_v<T1, double>) {
resultDouble = sanitizeInput(a) * b;
} else {
resultDouble = sanitizeInput(b) * a;
}

if LIKELY (
std::isfinite(resultDouble) && resultDouble >= kLongMin &&
resultDouble <= kMaxDoubleBelowInt64Max) {
result = int64_t(resultDouble);
} else {
result = resultDouble > 0 ? kLongMax : kLongMin;
}
}
};

template <typename T>
struct DivideFunction {
template <typename TInput>
FOLLY_ALWAYS_INLINE void
call(TInput& result, const TInput& a, const TInput& b)
// depend on compiler have correct behaviour for divide by zero
#if defined(__has_feature)
#if __has_feature(__address_sanitizer__)
__attribute__((__no_sanitize__("float-divide-by-zero")))
#endif
#endif
{
result = a / b;
}
};

template <typename T>
struct IntervalDivideFunction {
FOLLY_ALWAYS_INLINE void call(int64_t& result, int64_t a, double b)
// Depend on compiler have correct behaviour for divide by zero
#if defined(__has_feature)
#if __has_feature(__address_sanitizer__)
__attribute__((__no_sanitize__("float-divide-by-zero")))
__attribute__((__no_sanitize__("float-cast-overflow")))
#endif
#endif
{
if UNLIKELY (a == 0 || std::isnan(b) || !std::isfinite(b)) {
result = 0;
return;
}
double resultDouble = a / b;
if LIKELY (
std::isfinite(resultDouble) && resultDouble >= kLongMin &&
resultDouble <= kMaxDoubleBelowInt64Max) {
result = int64_t(resultDouble);
} else {
result = resultDouble > 0 ? kLongMax : kLongMin;
}
}
};

template <typename T>
struct ModulusFunction {
template <typename TInput>
FOLLY_ALWAYS_INLINE void
call(TInput& result, const TInput& a, const TInput& b) {
result = modulus(a, b);
}
};

template <typename T>
struct CeilFunction {
template <typename TOutput, typename TInput = TOutput>
Expand Down
157 changes: 157 additions & 0 deletions velox/functions/prestosql/ArithmeticOperators.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once

#include <cerrno>
#include <charconv>
#include <climits>
#include <cmath>
#include <cstdint>
#include <cstdlib>
#include <functional>
#include <limits>
#include <system_error>
#include <type_traits>

#include "folly/CPortability.h"
#include "velox/common/base/Doubles.h"
#include "velox/common/base/Exceptions.h"
#include "velox/functions/Macros.h"
#include "velox/functions/prestosql/ArithmeticImpl.h"

namespace facebook::velox::functions {

inline constexpr int kMinRadix = 2;
inline constexpr int kMaxRadix = 36;
inline constexpr long kLongMax = std::numeric_limits<int64_t>::max();
inline constexpr long kLongMin = std::numeric_limits<int64_t>::min();

namespace {

template <typename T>
struct PlusFunction {
template <typename TInput>
FOLLY_ALWAYS_INLINE void
call(TInput& result, const TInput& a, const TInput& b) {
result = plus(a, b);
}
};

template <typename T>
struct MinusFunction {
template <typename TInput>
FOLLY_ALWAYS_INLINE void
call(TInput& result, const TInput& a, const TInput& b) {
result = minus(a, b);
}
};

template <typename T>
struct MultiplyFunction {
template <typename TInput>
FOLLY_ALWAYS_INLINE void
call(TInput& result, const TInput& a, const TInput& b) {
result = multiply(a, b);
}
};

// Multiply function for IntervalDayTime * Double and Double * IntervalDayTime.
template <typename T>
struct IntervalMultiplyFunction {
FOLLY_ALWAYS_INLINE double sanitizeInput(double d) {
if UNLIKELY (std::isnan(d)) {
return 0;
}
return d;
}

template <
typename T1,
typename T2,
typename = std::enable_if_t<
(std::is_same_v<T1, int64_t> && std::is_same_v<T2, double>) ||
(std::is_same_v<T1, double> && std::is_same_v<T2, int64_t>)>>
FOLLY_ALWAYS_INLINE void call(int64_t& result, T1 a, T2 b) {
double resultDouble;
if constexpr (std::is_same_v<T1, double>) {
resultDouble = sanitizeInput(a) * b;
} else {
resultDouble = sanitizeInput(b) * a;
}

if LIKELY (
std::isfinite(resultDouble) && resultDouble >= kLongMin &&
resultDouble <= kMaxDoubleBelowInt64Max) {
result = int64_t(resultDouble);
} else {
result = resultDouble > 0 ? kLongMax : kLongMin;
}
}
};

template <typename T>
struct DivideFunction {
template <typename TInput>
FOLLY_ALWAYS_INLINE void
call(TInput& result, const TInput& a, const TInput& b)
// depend on compiler have correct behaviour for divide by zero
#if defined(__has_feature)
#if __has_feature(__address_sanitizer__)
__attribute__((__no_sanitize__("float-divide-by-zero")))
#endif
#endif
{
result = a / b;
}
};

template <typename T>
struct IntervalDivideFunction {
FOLLY_ALWAYS_INLINE void call(int64_t& result, int64_t a, double b)
// Depend on compiler have correct behaviour for divide by zero
#if defined(__has_feature)
#if __has_feature(__address_sanitizer__)
__attribute__((__no_sanitize__("float-divide-by-zero")))
__attribute__((__no_sanitize__("float-cast-overflow")))
#endif
#endif
{
if UNLIKELY (a == 0 || std::isnan(b) || !std::isfinite(b)) {
result = 0;
return;
}
double resultDouble = a / b;
if LIKELY (
std::isfinite(resultDouble) && resultDouble >= kLongMin &&
resultDouble <= kMaxDoubleBelowInt64Max) {
result = int64_t(resultDouble);
} else {
result = resultDouble > 0 ? kLongMax : kLongMin;
}
}
};

template <typename T>
struct ModulusFunction {
template <typename TInput>
FOLLY_ALWAYS_INLINE void
call(TInput& result, const TInput& a, const TInput& b) {
result = modulus(a, b);
}
};

} // namespace
} // namespace facebook::velox::functions
4 changes: 3 additions & 1 deletion velox/functions/prestosql/registration/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

add_library(
velox_functions_prestosql
ArithmeticFunctionsRegistration.cpp
ArrayConcatRegistration.cpp
ArrayFunctionsRegistration.cpp
ArrayNGramsRegistration.cpp
Expand All @@ -27,6 +26,9 @@ add_library(
HyperLogFunctionsRegistration.cpp
JsonFunctionsRegistration.cpp
MapFunctionsRegistration.cpp
MathematicalFunctionsRegistration.cpp
MathematicalOperatorsRegistration.cpp
ProbabilityTrigonometricFunctionsRegistration.cpp
RegistrationFunctions.cpp
StringFunctionsRegistration.cpp
URLFunctionsRegistration.cpp)
Expand Down
Loading

0 comments on commit cb785a6

Please sign in to comment.