Repository: incubator-quickstep Updated Branches: refs/heads/new-op 6941f903b -> 4005df6e3
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/types/operations/unary_operations/UnaryOperationWrapper.hpp ---------------------------------------------------------------------- diff --git a/types/operations/unary_operations/UnaryOperationWrapper.hpp b/types/operations/unary_operations/UnaryOperationWrapper.hpp index 417c752..c7e4ad5 100644 --- a/types/operations/unary_operations/UnaryOperationWrapper.hpp +++ b/types/operations/unary_operations/UnaryOperationWrapper.hpp @@ -27,26 +27,18 @@ #include "catalog/CatalogTypedefs.hpp" #include "storage/ValueAccessor.hpp" #include "storage/ValueAccessorUtil.hpp" -#include "types/CharType.hpp" -#include "types/IntType.hpp" -#include "types/LongType.hpp" #include "types/Type.hpp" #include "types/TypeFactory.hpp" #include "types/TypeID.hpp" #include "types/TypedValue.hpp" -#include "types/VarCharType.hpp" #include "types/containers/ColumnVector.hpp" -#include "types/operations/Operation.hpp" #include "types/operations/OperationSignature.hpp" -#include "types/operations/Operation.pb.h" +#include "types/operations/OperationUtil.hpp" +#include "types/operations/unary_operations/UnaryOperation.hpp" #include "utility/Macros.hpp" namespace quickstep { -class ColumnVector; -class Type; -class ValueAccessor; - /** \addtogroup Types * @{ */ @@ -55,6 +47,9 @@ template <typename ArgumentT, typename ResultT> struct UnaryFunctor { typedef ArgumentT ArgumentType; typedef ResultT ResultType; + + static constexpr Operation + ::OperationSuperTypeID kOperationSuperTypeID = Operation::kUnaryOperation; }; template <typename FunctorT, typename ...SpecArgs> @@ -65,42 +60,94 @@ class UncheckedUnaryOperatorWrapperCodegen : public UncheckedUnaryOperator { const Type &result_type, ConstructorArgs &&...args) : functor_(std::forward<ConstructorArgs>(args)...), - impl_(argument_type, result_type) {} + impl_(functor_, argument_type, result_type) {} TypedValue applyToTypedValue(const TypedValue &argument) const override { - return impl_.applyToTypedValue(argument, functor_); + return impl_.applyToTypedValue(argument); } ColumnVector* applyToColumnVector(const ColumnVector &argument) const override { - return impl_.applyToColumnVector(argument, functor_); + using ArgumentCVT = typename ArgumentGen::ColumnVectorType; + DCHECK_EQ(argument.isNative(), ArgumentCVT::kNative); + + using ArgumentAccessorT = ColumnVectorValueAccessor<ArgumentCVT>; + ArgumentAccessorT accessor(static_cast<const ArgumentCVT&>(argument)); + return impl_.applyToValueAccessor(&accessor, 0); } ColumnVector* applyToValueAccessor(ValueAccessor *accessor, - const attribute_id argument_attr_id) const override { - return impl_.applyToValueAccessor(accessor, argument_attr_id, functor_); + const attribute_id attr_id) const override { + return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter( + accessor, + [&](auto *accessor) -> ColumnVector* { // NOLINT(build/c++11) + return impl_.applyToValueAccessor(accessor, attr_id); + }); } private: using ArgumentType = typename FunctorT::ArgumentType; using ResultType = typename FunctorT::ResultType; - template <bool specialize, typename EnableT = void> - struct FunctorSpecializer; + using FuncSpec = typename FunctorSpecializer<FunctorT, SpecArgs...>::type; + using ArgumentGen = Codegen<FuncSpec, ArgumentType>; + using ResultGen = Codegen<FuncSpec, ResultType>; - template <typename T, typename EnableT = void> - struct Codegen; - - template <bool argument_nullable, - typename ArgumentGen, typename ResultGen> + template <bool argument_nullable> struct Implementation; - using FuncSpec = FunctorSpecializer<sizeof...(SpecArgs) != 0>; - using Impl = Implementation<false, - Codegen<ArgumentType>, - Codegen<ResultType>>; - const FunctorT functor_; - const Impl impl_; + const Implementation<true> impl_; + + DISALLOW_COPY_AND_ASSIGN(UncheckedUnaryOperatorWrapperCodegen); +}; + +template <typename FunctorT, typename ...SpecArgs> +template <bool argument_nullable> +struct UncheckedUnaryOperatorWrapperCodegen<FunctorT, SpecArgs...> + ::Implementation { + Implementation(const FunctorT &functor_in, + const Type &argument_type_in, + const Type &result_type_in) + : functor(functor_in), + argument_type(argument_type_in), + result_type(result_type_in) {} + + inline TypedValue applyToTypedValue(const TypedValue &argument) const { + if (argument_nullable && argument.isNull()) { + return TypedValue(ResultType::kStaticTypeID); + } + + return ResultGen::template ApplyUnaryTypedValue<ArgumentGen>( + ArgumentGen::ToNativeValueConst(argument), + result_type, + functor); + } + + template <typename AccessorT> + inline ColumnVector* applyToValueAccessor(AccessorT *accessor, + const attribute_id attr_id) const { + using ResultCVT = typename ResultGen::ColumnVectorType; + ResultCVT *result_cv = new ResultCVT(result_type, accessor->getNumTuples()); + + accessor->beginIteration(); + while (accessor->next()) { + typename ArgumentGen::NativeTypeConstPtr arg_value = + ArgumentGen::template GetValuePtr< + argument_nullable, AccessorT>(accessor, attr_id); + + if (argument_nullable && ArgumentGen::IsNull(arg_value)) { + result_cv->appendNullValue(); + } else { + ResultGen::template ApplyUnaryColumnVector<ArgumentGen>( + ArgumentGen::Dereference(arg_value), functor, result_cv); + } + } + return result_cv; + } + + const FunctorT &functor; + const Type &argument_type; + const Type &result_type; }; template <typename FunctorT> @@ -108,7 +155,7 @@ class UnaryOperationWrapper : public UnaryOperation { public: UnaryOperationWrapper() : UnaryOperation(), - operation_name_(FunctorT().getName()) {} + operation_name_(FunctorT::GetName()) {} std::string getName() const override { return operation_name_; @@ -120,7 +167,7 @@ class UnaryOperationWrapper : public UnaryOperation { std::vector<OperationSignaturePtr> getSignatures() const override { return { - OperationSignature::Create(getName(), {ArgumentType::kStaticTypeID}, 0) + OperationSignature::Create(getName(), {ArgumentType::kStaticTypeID}, 0) }; } @@ -137,7 +184,8 @@ class UnaryOperationWrapper : public UnaryOperation { const std::vector<TypedValue> &static_arguments) const override { DCHECK(argument_type.getTypeID() == ArgumentType::kStaticTypeID); DCHECK(static_arguments.empty()); - return &TypeFactory::GetType(ResultType::kStaticTypeID); + return getResultTypeImpl<ResultType::kParameterized>( + argument_type, static_arguments); } UncheckedUnaryOperator* makeUncheckedUnaryOperator( @@ -145,293 +193,53 @@ class UnaryOperationWrapper : public UnaryOperation { const std::vector<TypedValue> &static_arguments) const override { DCHECK(argument_type.getTypeID() == ArgumentType::kStaticTypeID); DCHECK(static_arguments.empty()); - return new UncheckedUnaryOperatorWrapperCodegen<FunctorT>( - argument_type, *getResultType(argument_type, static_arguments)); + return makeUncheckedUnaryOperatorImpl< + std::is_default_constructible<FunctorT>::value>( + argument_type, static_arguments); } private: using ArgumentType = typename FunctorT::ArgumentType; using ResultType = typename FunctorT::ResultType; - // TODO - static constexpr bool kCanAutoDerive = !ResultType::kParameterized; - - const std::string operation_name_; -}; - - -template <typename FunctorT, typename ...SpecArgs> -template <bool specialize> -struct UncheckedUnaryOperatorWrapperCodegen<FunctorT, SpecArgs...> - ::FunctorSpecializer<specialize, std::enable_if_t<specialize>> { - template <typename ...FuncArgs> - inline static auto Invoke(const FunctorT &functor, FuncArgs &&...args) { - return functor.template apply<SpecArgs...>(std::forward<FuncArgs>(args)...); - } -}; - -template <typename FunctorT, typename ...SpecArgs> -template <bool specialize> -struct UncheckedUnaryOperatorWrapperCodegen<FunctorT, SpecArgs...> - ::FunctorSpecializer<specialize, std::enable_if_t<!specialize>> { - template <typename ...FuncArgs> - inline static auto Invoke(const FunctorT &functor, FuncArgs &&...args) { - return functor.apply(std::forward<FuncArgs>(args)...); - } -}; - -template <typename FunctorT, typename ...SpecArgs> -template <typename T> -struct UncheckedUnaryOperatorWrapperCodegen<FunctorT, SpecArgs...> - ::Codegen<T, std::enable_if_t<T::kLayout == kNativeEmbedded>> { - using NativeType = typename T::cpptype; - using NativeTypeConstRef = const NativeType&; - using NativeTypeConstPtr = const NativeType*; - using ColumnVectorType = NativeColumnVector; - - template <typename ArgumentGen> - inline static TypedValue ApplyGenericTypedValue( - typename ArgumentGen::NativeTypeConstRef argument, - const Type &result_type, - const FunctorT &functor) { - return TypedValue(FuncSpec::Invoke(functor, argument)); - } - - template <typename ArgumentGen> - inline static void ApplyGenericColumnVector( - const typename ArgumentGen::NativeTypeConstPtr &argument, - const FunctorT &functor, - ColumnVectorType *cv) { - *static_cast<NativeType *>(cv->getPtrForDirectWrite()) = - FuncSpec::Invoke(functor, ArgumentGen::Dereference(argument)); - } - - template <bool nullable> - inline static NativeTypeConstPtr GetValuePtrColumnVector( - const ColumnVectorType &cv, - const std::size_t pos) { - return static_cast<NativeTypeConstPtr>( - cv.template getUntypedValue<nullable>(pos)); - } - - template <bool nullable, typename ValueAccessorT> - inline static NativeTypeConstPtr GetValuePtrValueAccessor( - ValueAccessorT *va, - const attribute_id argument_attr_id) { - return static_cast<NativeTypeConstPtr>( - va->template getUntypedValue<nullable>(argument_attr_id)); - } - - // Dereference: NativeTypeConstPtr& -> bool - inline static bool IsNull(const NativeType *value) { - return value == nullptr; - } - - // Dereference: NativeTypeConstPtr& -> const NativeType& - inline static const NativeType& Dereference(const NativeType *value) { - return *value; - } - - inline static const NativeType ToNativeValue(const TypedValue &value) { - return value.getLiteral<NativeType>(); - } -}; - -template <typename FunctorT, typename ...SpecArgs> -template <typename T> -struct UncheckedUnaryOperatorWrapperCodegen<FunctorT, SpecArgs...> - ::Codegen<T, std::enable_if_t<T::kLayout == kNonNativeInline>> { - using NativeType = void*; - using NativeTypeConstRef = const void*; - using NativeTypeConstPtr = const void*; - using ColumnVectorType = NativeColumnVector; - - template <typename ArgumentGen> - inline static TypedValue ApplyGenericTypedValue( - typename ArgumentGen::NativeTypeConstRef argument, - const Type &result_type, - const FunctorT &functor) { - void *result = std::malloc(result_type.maximumByteLength()); - FuncSpec::Invoke(functor, argument, result); - return TypedValue::CreateWithOwnedData(T::kStaticTypeID, - result, - result_type.maximumByteLength()); - } - - template <typename ArgumentGen> - inline static void ApplyGenericColumnVector( - const typename ArgumentGen::NativeTypeConstPtr &argument, - const FunctorT &functor, - ColumnVectorType *cv) { - FuncSpec::Invoke(functor, - ArgumentGen::Dereference(argument), - cv->getPtrForDirectWrite()); - } - - template <bool nullable> - inline static NativeTypeConstPtr GetValuePtrColumnVector( - const ColumnVectorType &cv, - const std::size_t pos) { - return cv.template getUntypedValue<nullable>(pos); - } - - template <bool nullable, typename ValueAccessorT> - inline static NativeTypeConstPtr GetValuePtrValueAccessor( - ValueAccessorT *va, - const attribute_id argument_attr_id) { - return va->template getUntypedValue<nullable>(argument_attr_id); - } - - inline static bool IsNull(const void *value) { - return value == nullptr; - } - - // Dereference: NativeTypeConstPtr& -> const NativeType& - inline static const void* Dereference(const void *value) { - return value; - } - - inline static const void* ToNativeValue(const TypedValue &value) { - return value.getDataPtr(); - } -}; - -template <typename FunctorT, typename ...SpecArgs> -template <typename T> -struct UncheckedUnaryOperatorWrapperCodegen<FunctorT, SpecArgs...> - ::Codegen<T, std::enable_if_t<T::kLayout == kOutOfLine>> { - using NativeType = TypedValue; - using NativeTypeConstRef = const TypedValue&; - using NativeTypeConstPtr = const TypedValue; - using ColumnVectorType = IndirectColumnVector; - - template <typename ArgumentGen> - inline static TypedValue ApplyGenericTypedValue( - typename ArgumentGen::NativeTypeConstRef argument, - const Type &result_type, - const FunctorT &functor) { - return FuncSpec::Invoke(functor, argument); - } - - template <typename ArgumentGen> - inline static void ApplyGenericColumnVector( - const typename ArgumentGen::NativeTypeConstPtr &argument, - const FunctorT &functor, - ColumnVectorType *cv) { - cv->appendTypedValue( - FuncSpec::Invoke(functor, ArgumentGen::Dereference(argument))); - } - - template <bool nullable> - inline static NativeTypeConstPtr GetValuePtrColumnVector( - const ColumnVectorType &cv, - const std::size_t pos) { - return cv.getTypedValue(pos); - } - - template <bool nullable, typename ValueAccessorT> - inline static NativeTypeConstPtr GetValuePtrValueAccessor( - ValueAccessorT *va, - const attribute_id argument_attr_id) { - return va->getTypedValue(argument_attr_id); - } - - inline static bool IsNull(NativeTypeConstPtr &value) { - return value.isNull(); - } - - // Dereference: NativeTypeConstPtr& -> const NativeType& - inline static const NativeType& Dereference(NativeTypeConstPtr &value) { - return value; + template <bool functor_use_default_constructor> + inline UncheckedUnaryOperator* makeUncheckedUnaryOperatorImpl( + const Type &argument_type, + const std::vector<TypedValue> &static_arguments, + std::enable_if_t<functor_use_default_constructor>* = 0) const { + return new UncheckedUnaryOperatorWrapperCodegen<FunctorT>( + argument_type, *getResultType(argument_type, static_arguments)); } - inline static const NativeType& ToNativeValue(const TypedValue &value) { - return value; - } -}; - -template <typename FunctorT, typename ...SpecArgs> -template <bool argument_nullable, - typename ArgumentGen, typename ResultGen> -struct UncheckedUnaryOperatorWrapperCodegen<FunctorT, SpecArgs...> - ::Implementation { - Implementation(const Type &argument_type_in, const Type &result_type_in) - : argument_type(argument_type_in), - result_type(result_type_in) {} - - inline TypedValue applyToTypedValue(const TypedValue &argument, - const FunctorT &functor) const { - if (argument_nullable && argument.isNull()) { - return TypedValue(result_type.getTypeID()); - } - - return ResultGen::template ApplyGenericTypedValue<ArgumentGen>( - ArgumentGen::ToNativeValue(argument), - result_type, - functor); + template <bool functor_use_default_constructor> + inline UncheckedUnaryOperator* makeUncheckedUnaryOperatorImpl( + const Type &argument_type, + const std::vector<TypedValue> &static_arguments, + std::enable_if_t<!functor_use_default_constructor>* = 0) const { + return new UncheckedUnaryOperatorWrapperCodegen<FunctorT>( + argument_type, *getResultType(argument_type, static_arguments), + static_cast<const ArgumentType&>(argument_type)); } - inline ColumnVector* applyToColumnVector(const ColumnVector &argument, - const FunctorT &functor) const { - using ArgumentCVT = typename ArgumentGen::ColumnVectorType; - using ResultCVT = typename ResultGen::ColumnVectorType; - - const ArgumentCVT &argument_cv = static_cast<const ArgumentCVT&>(argument); - ResultCVT *result_cv = new ResultCVT(result_type, argument_cv.size()); - - for (std::size_t pos = 0; pos < argument_cv.size(); ++pos) { - typename ArgumentGen::NativeTypeConstPtr scalar_arg = - ArgumentGen::template GetValuePtrColumnVector<argument_nullable>( - argument_cv, pos); - - if (argument_nullable && ArgumentGen::IsNull(scalar_arg)) { - result_cv->appendNullValue(); - } else { - ResultGen::template ApplyGenericColumnVector<ArgumentGen>( - scalar_arg, functor, result_cv); - } - } - return result_cv; + template <bool result_type_has_parameter> + inline const Type* getResultTypeImpl( + const Type &argument_type, + const std::vector<TypedValue> &static_arguments, + std::enable_if_t<!result_type_has_parameter>* = 0) const { + return &TypeFactory::GetType(ResultType::kStaticTypeID); } - inline ColumnVector* applyToValueAccessor(ValueAccessor *accessor, - const attribute_id argument_attr_id, - const FunctorT &functor) const { - using ResultCVT = typename ResultGen::ColumnVectorType; - - return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter( - accessor, - [&](auto *accessor) -> ColumnVector* { // NOLINT(build/c++11) - ResultCVT *result_cv = new ResultCVT(result_type, accessor->getNumTuples()); - - accessor->beginIteration(); - while (accessor->next()) { - typename ArgumentGen::NativeTypeConstPtr scalar_arg = - ArgumentGen::template GetValuePtrValueAccessor<argument_nullable>( - accessor, argument_attr_id); - - if (argument_nullable && ArgumentGen::IsNull(scalar_arg)) { - result_cv->appendNullValue(); - } else { - ResultGen::template ApplyGenericColumnVector<ArgumentGen>( - scalar_arg, functor, result_cv); - } - } - return result_cv; - }); + template <bool result_type_has_parameter> + inline const Type* getResultTypeImpl( + const Type &argument_type, + const std::vector<TypedValue> &static_arguments, + std::enable_if_t<result_type_has_parameter>* = 0) const { + return FunctorT::GetResultType(argument_type); } - const Type &argument_type; - const Type &result_type; -}; + const std::string operation_name_; -template <typename ...FunctorTypes> -struct UnaryFunctorPack { - static std::vector<UnaryOperationPtr> GenerateAll() { - return { - UnaryOperationPtr(new UnaryOperationWrapper<FunctorTypes>())... - }; - } + DISALLOW_COPY_AND_ASSIGN(UnaryOperationWrapper); }; /** @} */ http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/utility/TemplateUtil.hpp ---------------------------------------------------------------------- diff --git a/utility/TemplateUtil.hpp b/utility/TemplateUtil.hpp index f6baec2..40ebbcd 100644 --- a/utility/TemplateUtil.hpp +++ b/utility/TemplateUtil.hpp @@ -248,6 +248,17 @@ struct StringLiteral { } }; +template <typename LeftT, typename RightT> +struct PairSelectorLeft { + typedef LeftT type; +}; + +template <typename LeftT, typename RightT> +struct PairSelectorRight { + typedef RightT type; +}; + + /** @} */ } // namespace quickstep