Updates for array type
Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/1e69fb18 Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/1e69fb18 Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/1e69fb18 Branch: refs/heads/refactor-type Commit: 1e69fb18eb9e7f31c48d85aaef781dca1ba8290a Parents: b6fd31f Author: Jianqiao Zhu <[email protected]> Authored: Mon Oct 2 23:46:48 2017 -0500 Committer: Jianqiao Zhu <[email protected]> Committed: Wed Oct 11 13:37:54 2017 -0500 ---------------------------------------------------------------------- query_optimizer/expressions/CMakeLists.txt | 1 + query_optimizer/expressions/ScalarLiteral.hpp | 3 +- query_optimizer/resolver/CMakeLists.txt | 4 + query_optimizer/resolver/Resolver.cpp | 70 ++- types/GenericValue.hpp | 18 +- types/Type.cpp | 18 + types/Type.hpp | 23 +- types/Type.proto | 2 +- types/TypeSynthesizer.hpp | 479 ++++++++++++--------- utility/CharStream.hpp | 34 +- utility/meta/Common.hpp | 58 ++- validate_cmakelists.py | 8 +- 12 files changed, 450 insertions(+), 268 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e69fb18/query_optimizer/expressions/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/query_optimizer/expressions/CMakeLists.txt b/query_optimizer/expressions/CMakeLists.txt index dc722e7..cf2727f 100644 --- a/query_optimizer/expressions/CMakeLists.txt +++ b/query_optimizer/expressions/CMakeLists.txt @@ -97,6 +97,7 @@ target_link_libraries(quickstep_queryoptimizer_expressions_BinaryExpression quickstep_queryoptimizer_expressions_PatternMatcher quickstep_queryoptimizer_expressions_Scalar quickstep_queryoptimizer_expressions_ScalarLiteral + quickstep_types_GenericValue quickstep_types_operations_OperationSignature quickstep_types_operations_binaryoperations_BinaryOperation quickstep_utility_HashPair http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e69fb18/query_optimizer/expressions/ScalarLiteral.hpp ---------------------------------------------------------------------- diff --git a/query_optimizer/expressions/ScalarLiteral.hpp b/query_optimizer/expressions/ScalarLiteral.hpp index 180ae39..f6a14f4 100644 --- a/query_optimizer/expressions/ScalarLiteral.hpp +++ b/query_optimizer/expressions/ScalarLiteral.hpp @@ -108,7 +108,8 @@ class ScalarLiteral : public Scalar { ScalarLiteral(const GenericValue &literal_value) : value_(literal_value) {} - const GenericValue &value_; + const GenericValue value_; + DISALLOW_COPY_AND_ASSIGN(ScalarLiteral); }; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e69fb18/query_optimizer/resolver/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/query_optimizer/resolver/CMakeLists.txt b/query_optimizer/resolver/CMakeLists.txt index a759ce3..8a1116a 100644 --- a/query_optimizer/resolver/CMakeLists.txt +++ b/query_optimizer/resolver/CMakeLists.txt @@ -120,7 +120,11 @@ target_link_libraries(quickstep_queryoptimizer_resolver_Resolver quickstep_queryoptimizer_resolver_NameResolver quickstep_storage_StorageBlockLayout_proto quickstep_storage_StorageConstants + quickstep_types_ArrayType + quickstep_types_GenericValue quickstep_types_IntType + quickstep_types_MetaType + quickstep_types_NullType quickstep_types_Type quickstep_types_TypeUtil quickstep_types_TypedValue http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e69fb18/query_optimizer/resolver/Resolver.cpp ---------------------------------------------------------------------- diff --git a/query_optimizer/resolver/Resolver.cpp b/query_optimizer/resolver/Resolver.cpp index 2cd24bd..d4ff5c6 100644 --- a/query_optimizer/resolver/Resolver.cpp +++ b/query_optimizer/resolver/Resolver.cpp @@ -115,8 +115,11 @@ #include "query_optimizer/resolver/NameResolver.hpp" #include "storage/StorageBlockLayout.pb.h" #include "storage/StorageConstants.hpp" +#include "types/ArrayType.hpp" #include "types/GenericValue.hpp" #include "types/IntType.hpp" +#include "types/MetaType.hpp" +#include "types/NullType.hpp" #include "types/Type.hpp" #include "types/TypeFactory.hpp" #include "types/TypeUtil.hpp" @@ -2492,21 +2495,58 @@ E::ScalarPtr Resolver::resolveArray( const ParseArray &parse_array, const Type *type_hint, ExpressionResolutionInfo *expression_resolution_info) { -// std::vector<E::ScalarPtr> elements; -// const auto &parse_elements = parse_array.elements(); -// if (parse_elements.empty()) { -// // TODO(jianqiao): Figure out how to handle empty array. -// -// } else { -// elements.reserve(parse_elements.size()); -// for (const auto &parse_element : parse_elements) { -// elements.emplace_back( -// resolveExpression(*parse_element, nullptr, expression_resolution_info)); -// } -// -// // Currently we only support homogeneous array with literal values. -// } - LOG(FATAL) << "Not supported"; + const auto &parse_elements = parse_array.elements(); + if (parse_elements.empty()) { + // TODO(jianqiao): Figure out how to handle empty array. + const GenericValue meta_null_type_value( + MetaType::InstanceNonNullable(), &NullType::InstanceNullable()); + return E::ScalarLiteral::Create( + GenericValue(ArrayType::InstanceNonNullable({meta_null_type_value}), + ArrayLiteral())); + } else { + // Currently we only support homogeneous array with literal values. + std::vector<E::ScalarLiteralPtr> literals; + const Type *element_type = nullptr; + for (const auto &parse_element : parse_elements) { + const E::ScalarPtr scalar = + resolveExpression(*parse_element, nullptr, expression_resolution_info); + E::ScalarLiteralPtr literal; + if (E::SomeScalarLiteral::MatchesWithConditionalCast(scalar, &literal)) { + const GenericValue &value = literal->value(); + if (element_type == nullptr) { + element_type = &value.getType(); + } else { + if (!element_type->equals(value.getType())) { + THROW_SQL_ERROR_AT(parse_element) + << "Heterogeneous array is not supported: " + << "array contains elements of at least two types " + << element_type->getName() << " and " + << value.getType().getName(); + } + } + literals.emplace_back(literal); + } else { + THROW_SQL_ERROR_AT(parse_element) + << "Non-static array element is not supported yet"; + } + } + DCHECK(element_type != nullptr); + + const GenericValue meta_element_type_value( + MetaType::InstanceNonNullable(), element_type); + const Type &array_type = + ArrayType::InstanceNonNullable({meta_element_type_value}); + + // NOTE(refactor-type): Possibly memory leak region, noexcept. + std::unique_ptr<ArrayLiteral> array_literal = std::make_unique<ArrayLiteral>(); + for (const auto &literal : literals) { + array_literal->emplace_back( + element_type->cloneValue(literal->value().getValue())); + } + return E::ScalarLiteral::Create(GenericValue(array_type, + array_literal.release(), + true /* take_ownership */)); + } } http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e69fb18/types/GenericValue.hpp ---------------------------------------------------------------------- diff --git a/types/GenericValue.hpp b/types/GenericValue.hpp index 1fcdcd6..62dd9a3 100644 --- a/types/GenericValue.hpp +++ b/types/GenericValue.hpp @@ -46,8 +46,10 @@ class GenericValue { GenericValue(const Type &type) : type_(type), value_(nullptr), owns_(true) {} - GenericValue(const Type &type, const UntypedLiteral *value, const bool owns) - : type_(type), value_(value), owns_(owns) {} + GenericValue(const Type &type, + const UntypedLiteral *value, + const bool take_ownership) + : type_(type), value_(value), owns_(take_ownership) {} GenericValue(const Type &type, const TypedValue &value) : type_(type), value_(type.unmarshallTypedValue(value)), owns_(true) {} @@ -76,7 +78,13 @@ class GenericValue { } serialization::GenericValue getProto() const { - LOG(FATAL) << "Not implemented"; + serialization::GenericValue proto; + proto.mutable_type()->MergeFrom(type_.getProto()); + if (!isNull()) { + TypedValue tv = type_.marshallValue(value_); + proto.set_data(tv.getDataPtr(), tv.getDataSize()); + } + return proto; } inline bool isNull() const { @@ -131,7 +139,9 @@ class GenericValue { } inline GenericValue coerce(const Type &other_type) const { - LOG(FATAL) << "Not implemented"; + return GenericValue(other_type, + other_type.coerceValue(value_, type_), + true /* take_ownership */); } inline TypedValue toTypedValue() const { http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e69fb18/types/Type.cpp ---------------------------------------------------------------------- diff --git a/types/Type.cpp b/types/Type.cpp index b0b781a..41780f8 100644 --- a/types/Type.cpp +++ b/types/Type.cpp @@ -77,4 +77,22 @@ TypedValue Type::coerceTypedValue(const TypedValue &original_value, return original_value; } +UntypedLiteral* Type::coerceValue(const UntypedLiteral *original_value, + const Type &original_type) const { + DCHECK(isCoercibleFrom(original_type)) + << "Can't coerce value of Type " << original_type.getName() + << " to Type " << getName(); + + if (original_type.getTypeID() == kNullType) { + return nullptr; + } + + DCHECK(equals(original_type) || equals(original_type.getNullableVersion())) + << "Base version of Type::coerceValue() called for a non-trivial " + << "coercion from Type " << original_type.getName() + << " to Type " << getName(); + + return cloneValue(original_value); +} + } // namespace quickstep http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e69fb18/types/Type.hpp ---------------------------------------------------------------------- diff --git a/types/Type.hpp b/types/Type.hpp index d4ed993..e5d5528 100644 --- a/types/Type.hpp +++ b/types/Type.hpp @@ -401,42 +401,33 @@ class Type { virtual TypedValue coerceTypedValue(const TypedValue &original_value, const Type &original_type) const; - virtual std::size_t getHash() const = 0; virtual bool checkValuesEqual(const UntypedLiteral *lhs, const UntypedLiteral *rhs, - const Type &rhs_type) const { - LOG(FATAL) << "Not implemented"; - } + const Type &rhs_type) const = 0; inline bool checkValuesEqual(const UntypedLiteral *lhs, const UntypedLiteral *rhs) const { return checkValuesEqual(lhs, rhs, *this); } + virtual UntypedLiteral* coerceValue(const UntypedLiteral *original_value, + const Type &original_type) const; + virtual UntypedLiteral* cloneValue(const UntypedLiteral *value) const = 0; virtual void destroyValue(UntypedLiteral *value) const = 0; - virtual std::size_t hashValue(const UntypedLiteral *value) const { - LOG(FATAL) << "Not implemented"; - } + virtual std::size_t hashValue(const UntypedLiteral *value) const = 0; - virtual TypedValue marshallValue(const UntypedLiteral *value) const { - LOG(FATAL) << "Not implemented"; - } + virtual TypedValue marshallValue(const UntypedLiteral *value) const = 0; virtual UntypedLiteral* unmarshallValue(const void *data, - const std::size_t length) const { - LOG(FATAL) << "Not implemented"; - - } + const std::size_t length) const = 0; virtual UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const = 0; - virtual UntypedLiteral* unmarshallTypedValue(TypedValue &&value) const = 0; - protected: Type(const SuperTypeID super_type_id, const TypeID type_id, http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e69fb18/types/Type.proto ---------------------------------------------------------------------- diff --git a/types/Type.proto b/types/Type.proto index b93f894..e449ee6 100644 --- a/types/Type.proto +++ b/types/Type.proto @@ -32,5 +32,5 @@ message Type { message GenericValue { required Type type = 1; - required bytes data = 2; + optional bytes data = 2; } http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e69fb18/types/TypeSynthesizer.hpp ---------------------------------------------------------------------- diff --git a/types/TypeSynthesizer.hpp b/types/TypeSynthesizer.hpp index 08ab67a..cebbd6b 100644 --- a/types/TypeSynthesizer.hpp +++ b/types/TypeSynthesizer.hpp @@ -38,6 +38,9 @@ #include "types/TypedValue.hpp" #include "utility/HashPair.hpp" #include "utility/Macros.hpp" +#include "utility/meta/Common.hpp" + +#include "third_party/src/farmhash/farmhash.h" #include "glog/logging.h" @@ -51,142 +54,13 @@ template <TypeID type_id, typename Enable = void> class TypeSynthesizePolicy; -template <TypeID type_id> -class TypeSynthesizer - : public Type, - public TypeSynthesizePolicy<type_id> { - private: - using Trait = TypeIDTrait<type_id>; - using SynthesizePolicy = TypeSynthesizePolicy<type_id>; - - public: - static constexpr SuperTypeID kStaticSuperTypeID = Trait::kStaticSuperTypeID; - static constexpr TypeID kStaticTypeID = Trait::kStaticTypeID; - static constexpr bool kIsParPod = Trait::kIsParPod; - static constexpr MemoryLayout kMemoryLayout = Trait::kMemoryLayout; - - using TypeClass = typename Trait::TypeClass; - using cpptype = typename Trait::cpptype; - - serialization::Type getProto() const override { - serialization::Type proto; - - proto.mutable_type_id()->CopyFrom(TypeIDFactory::GetProto(type_id_)); - proto.set_nullable(nullable_); - SynthesizePolicy::mergeIntoProto(&proto); - - return proto; - } - - const Type& getNullableVersion() const override { - return SynthesizePolicy::getInstance(true); - } - - const Type& getNonNullableVersion() const override { - return SynthesizePolicy::getInstance(false); - } - - std::size_t getHash() const override { - return SynthesizePolicy::getHash(); - } - - UntypedLiteral* cloneValue(const UntypedLiteral *value) const override { - return SynthesizePolicy::cloneValue(value); - } - - void destroyValue(UntypedLiteral *value) const override { - return SynthesizePolicy::destroyValue(value); - } - - UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const override { - return SynthesizePolicy::unmarshallTypedValue(value); - } - - UntypedLiteral* unmarshallTypedValue(TypedValue &&value) const override { - return SynthesizePolicy::unmarshallTypedValue(std::move(value)); - } - - std::string printTypedValueToString(const TypedValue &value) const override { - return SynthesizePolicy::invokeOnUnmarshalledTypedValue( - value, - [&](const UntypedLiteral *value) -> std::string { - return this->printValueToString(value); - }); - } - - void printTypedValueToFile(const TypedValue &value, - FILE *file, - const int padding = 0) const override { - SynthesizePolicy::invokeOnUnmarshalledTypedValue( - value, - [&](const UntypedLiteral *value) -> void { - this->printValueToFile(value, file, padding); - }); - } - - const cpptype& castValueToLiteral(const UntypedLiteral *value) const { - return *static_cast<const cpptype*>(value); - } - - cpptype& castValueToLiteral(UntypedLiteral *value) const { - return *static_cast<cpptype*>(value); - } - - protected: - template <MemoryLayout layout = kMemoryLayout> - explicit TypeSynthesizer(const bool nullable, - std::enable_if_t<layout == kCxxInlinePod>* = 0) - : Type(kStaticSuperTypeID, kStaticTypeID, nullable, - sizeof(cpptype), sizeof(cpptype)), - TypeSynthesizePolicy<type_id>(this) { - } - - template <MemoryLayout layout = kMemoryLayout> - TypeSynthesizer(const bool nullable, - const std::size_t minimum_byte_length, - const std::size_t maximum_byte_length, - const std::size_t parameter, - std::enable_if_t<layout == kParInlinePod || - layout == kParOutOfLinePod>* = 0) - : Type(kStaticSuperTypeID, kStaticTypeID, nullable, - minimum_byte_length, maximum_byte_length), - TypeSynthesizePolicy<type_id>(this, parameter) { - } - - template <MemoryLayout layout = kMemoryLayout> - TypeSynthesizer(const bool nullable, - const std::size_t minimum_byte_length, - const std::size_t maximum_byte_length, - const std::vector<GenericValue> ¶meters = {}, - std::enable_if_t<layout == kCxxGeneric>* = 0) - : Type(kStaticSuperTypeID, kStaticTypeID, nullable, - minimum_byte_length, maximum_byte_length), - TypeSynthesizePolicy<type_id>(this, parameters) { - } - - private: - template <TypeID, typename> friend class TypeSynthesizePolicy; - - DISALLOW_COPY_AND_ASSIGN(TypeSynthesizer); -}; - -template <TypeID type_id> -constexpr SuperTypeID TypeSynthesizer<type_id>::kStaticSuperTypeID; - -template <TypeID type_id> -constexpr TypeID TypeSynthesizer<type_id>::kStaticTypeID; - -template <TypeID type_id> -constexpr bool TypeSynthesizer<type_id>::kIsParPod; - -template <TypeID type_id> -constexpr MemoryLayout TypeSynthesizer<type_id>::kMemoryLayout; - - +//////////////////////////////////////////////////////////////////////////////// +///////////////////////////////// CxxInlinePod /////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// template <TypeID type_id> class TypeSynthesizePolicy< type_id, - std::enable_if_t<TypeIDTrait<type_id>::kMemoryLayout == kCxxInlinePod>> { + std::enable_if_t<TypeIDTrait<type_id>::kMemoryLayout == kCxxInlinePod>> : public Type { private: using Trait = TypeIDTrait<type_id>; using TypeClass = typename Trait::TypeClass; @@ -209,34 +83,63 @@ class TypeSynthesizePolicy< } } - protected: - explicit TypeSynthesizePolicy(const Type *base) - : base_(*base) {} - - inline const Type& getInstance(const bool nullable) const { - return nullable ? InstanceNullable() : InstanceNonNullable(); + std::size_t getHash() const override { + return static_cast<std::size_t>(getTypeID()); } - inline void mergeIntoProto(serialization::Type *proto) const {} - - inline std::size_t getHash() const { - return static_cast<std::size_t>(base_.getTypeID()); + bool checkValuesEqual(const UntypedLiteral *lhs, + const UntypedLiteral *rhs, + const Type &rhs_type) const override { + // TODO(refactor-type): Operator == overloading. + if (type_id_ != rhs_type.getTypeID()) { + return false; + } + return !std::memcmp(lhs, rhs, sizeof(cpptype)); } - inline UntypedLiteral* cloneValue(const UntypedLiteral *value) const { + UntypedLiteral* cloneValue(const UntypedLiteral *value) const override { DCHECK(value != nullptr); UntypedLiteral* clone = std::malloc(sizeof(cpptype)); std::memcpy(clone, value, sizeof(cpptype)); return clone; } - inline void destroyValue(UntypedLiteral *value) const { + void destroyValue(UntypedLiteral *value) const override { DCHECK(value != nullptr); std::free(value); } - inline UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const { - return base_.cloneValue(value.getDataPtr()); + std::size_t hashValue(const UntypedLiteral *value) const override { + return hashValueInl<sizeof(cpptype)>(value); + } + + TypedValue marshallValue(const UntypedLiteral *value) const override { + TypedValue ret = makeValue(value, sizeof(cpptype)); + ret.ensureNotReference(); + return ret; + } + + UntypedLiteral* unmarshallValue(const void *data, + const std::size_t length) const override { + DCHECK_EQ(sizeof(cpptype), length); + UntypedLiteral *value = std::malloc(sizeof(cpptype)); + std::memcpy(value, data, sizeof(cpptype)); + return value; + } + + protected: + explicit TypeSynthesizePolicy(const bool nullable) + : Type(Trait::kStaticSuperTypeID, type_id, nullable, + sizeof(cpptype), sizeof(cpptype)) {} + + inline const Type& getInstance(const bool nullable) const { + return nullable ? InstanceNullable() : InstanceNonNullable(); + } + + inline void mergeIntoProto(serialization::Type *proto) const {} + + inline UntypedLiteral* unmarshallTypedValueInl(const TypedValue &value) const { + return cloneValue(value.getDataPtr()); } template <typename Functor> @@ -252,14 +155,35 @@ class TypeSynthesizePolicy< return instance; } - const Type &base_; + template <std::size_t size> + inline std::size_t hashValueInl( + const UntypedLiteral *value, + std::enable_if_t<meta::CxxSupportedIntegerSizes + ::template contains<size>::value> * = 0) const { + using CxxUIntType = typename meta::UnsignedInteger<size>::type; + CxxUIntType buffer; + std::memcpy(&buffer, value, size); + return buffer; + } + + template <std::size_t size> + inline std::size_t hashValueInl( + const UntypedLiteral *value, + std::enable_if_t<!meta::CxxSupportedIntegerSizes + ::template contains<size>::value> * = 0) const { + return util::Hash(static_cast<const char*>(value), size); + } }; + +//////////////////////////////////////////////////////////////////////////////// +/////////////////////// ParInlinePod & ParOutOfLinePod /////////////////////// +//////////////////////////////////////////////////////////////////////////////// template <TypeID type_id> class TypeSynthesizePolicy< type_id, std::enable_if_t<TypeIDTrait<type_id>::kMemoryLayout == kParInlinePod || - TypeIDTrait<type_id>::kMemoryLayout == kParOutOfLinePod>> { + TypeIDTrait<type_id>::kMemoryLayout == kParOutOfLinePod>> : public Type { private: using Trait = TypeIDTrait<type_id>; using TypeClass = typename Trait::TypeClass; @@ -285,45 +209,70 @@ class TypeSynthesizePolicy< } } - inline std::size_t length() const { + std::size_t length() const { return length_; } - protected: - TypeSynthesizePolicy(const Type *base, const std::size_t length) - : length_(length), - base_(*base) {} - - const std::size_t length_; - - inline const Type& getInstance(const bool nullable) const { - return nullable ? InstanceNullable(length_) : InstanceNonNullable(length_); + std::size_t getHash() const override { + return CombineHashes(static_cast<std::size_t>(type_id), length_); } - inline void mergeIntoProto(serialization::Type *proto) const { - proto->set_length(length_); + std::size_t hashValue(const UntypedLiteral *value) const override { + // TODO(refactor-type): Better implementation. + return static_cast<const TypedValue*>(value)->getHash(); } - inline std::size_t getHash() const { - return CombineHashes(static_cast<std::size_t>(base_.getTypeID()), length_); + bool checkValuesEqual(const UntypedLiteral *lhs, + const UntypedLiteral *rhs, + const Type &rhs_type) const override { + // TODO(refactor-type): Better implementation. + const TypedValue *lhs_value = static_cast<const TypedValue*>(lhs); + const TypedValue *rhs_value = static_cast<const TypedValue*>(rhs); + return lhs_value->fastEqualCheck(*rhs_value); } - inline UntypedLiteral* cloneValue(const UntypedLiteral *value) const { + UntypedLiteral* cloneValue(const UntypedLiteral *value) const override { DCHECK(value != nullptr); return new TypedValue(*static_cast<const TypedValue*>(value)); } - inline void destroyValue(UntypedLiteral *value) const { + void destroyValue(UntypedLiteral *value) const override { DCHECK(value != nullptr); delete static_cast<TypedValue*>(value); } - inline UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const { - return base_.cloneValue(&value); + TypedValue marshallValue(const UntypedLiteral *value) const override { + return *static_cast<const TypedValue*>(value); } - inline UntypedLiteral* unmarshallTypedValue(TypedValue &&value) const { - return new TypedValue(std::move(value)); + UntypedLiteral* unmarshallValue(const void *data, + const std::size_t length) const override { + TypedValue *value = new TypedValue(makeValue(data, length)); + value->ensureNotReference(); + return value; + } + + protected: + TypeSynthesizePolicy(const bool nullable, + const std::size_t minimum_byte_length, + const std::size_t maximum_byte_length, + const std::size_t length) + : Type(Trait::kStaticSuperTypeID, type_id, nullable, + minimum_byte_length, maximum_byte_length), + length_(length) {} + + const std::size_t length_; + + inline const Type& getInstance(const bool nullable) const { + return nullable ? InstanceNullable(length_) : InstanceNonNullable(length_); + } + + inline void mergeIntoProto(serialization::Type *proto) const { + proto->set_length(length_); + } + + inline UntypedLiteral* unmarshallTypedValueInl(const TypedValue &value) const { + return new TypedValue(value); } template <typename Functor> @@ -343,14 +292,16 @@ class TypeSynthesizePolicy< } return *(imit->second); } - - const Type &base_; }; + +//////////////////////////////////////////////////////////////////////////////// +////////////////////////////////// CxxGeneric //////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// template <TypeID type_id> class TypeSynthesizePolicy< type_id, - std::enable_if_t<TypeIDTrait<type_id>::kMemoryLayout == kCxxGeneric>> { + std::enable_if_t<TypeIDTrait<type_id>::kMemoryLayout == kCxxGeneric>> : public Type { private: using Trait = TypeIDTrait<type_id>; using TypeClass = typename Trait::TypeClass; @@ -377,15 +328,53 @@ class TypeSynthesizePolicy< } } - inline const std::vector<GenericValue>& parameters() const { + const std::vector<GenericValue>& parameters() const { return parameters_; } + std::size_t getHash() const override { + return CombineHashes(static_cast<std::size_t>(type_id_), + ParametersHasher::ComputeHash(parameters_)); + } + + bool checkValuesEqual(const UntypedLiteral *lhs, + const UntypedLiteral *rhs, + const Type &rhs_type) const override { + LOG(FATAL) << "Not implemented"; + } + + UntypedLiteral* cloneValue(const UntypedLiteral *value) const override { + DCHECK(value != nullptr); + return new cpptype(*static_cast<const cpptype*>(value)); + } + + void destroyValue(UntypedLiteral *value) const override { + DCHECK(value != nullptr); + delete static_cast<cpptype*>(value); + } + + std::size_t hashValue(const UntypedLiteral *value) const override { + // TODO(refactor-type): Add note that it is a shallow hash. + return util::Hash(static_cast<const char*>(value), sizeof(cpptype)); + } + + TypedValue marshallValue(const UntypedLiteral *value) const override { + LOG(FATAL) << "Not implemented"; + } + + UntypedLiteral* unmarshallValue(const void *data, + const std::size_t length) const override { + LOG(FATAL) << "Not implemented"; + } + protected: - TypeSynthesizePolicy(const Type *base, + TypeSynthesizePolicy(const bool nullable, + const std::size_t minimum_byte_length, + const std::size_t maximum_byte_length, const std::vector<GenericValue> ¶meters) - : parameters_(parameters), - base_(*base) {} + : Type(Trait::kStaticSuperTypeID, type_id, nullable, + minimum_byte_length, maximum_byte_length), + parameters_(parameters) {} inline const Type& getInstance(const bool nullable) const { return nullable ? InstanceNullable(parameters_) @@ -398,32 +387,16 @@ class TypeSynthesizePolicy< } } - inline std::size_t getHash() const { - return CombineHashes(static_cast<std::size_t>(base_.getTypeID()), - ParametersHasher::ComputeHash(parameters_)); - } - - inline UntypedLiteral* cloneValue(const UntypedLiteral *value) const { - DCHECK(value != nullptr); - return new cpptype(*static_cast<const cpptype*>(value)); - } - - inline void destroyValue(UntypedLiteral *value) const { - DCHECK(value != nullptr); - delete static_cast<cpptype*>(value); - } - - inline UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const { - return base_.unmarshallValue(value.getOutOfLineData(), value.getDataSize()); + inline UntypedLiteral* unmarshallTypedValueInl(const TypedValue &value) const { + return unmarshallValue(value.getOutOfLineData(), value.getDataSize()); } template <typename Functor> inline auto invokeOnUnmarshalledTypedValue(const TypedValue &value, const Functor &functor) const { - std::unique_ptr<typename Trait::cpptype> literal( - static_cast<typename Trait::cpptype*>( - base_.unmarshallValue(value.getOutOfLineData(), - value.getDataSize()))); + std::unique_ptr<cpptype> literal( + static_cast<cpptype*>(unmarshallValue(value.getOutOfLineData(), + value.getDataSize()))); return functor(literal.get()); } @@ -477,10 +450,120 @@ class TypeSynthesizePolicy< } return *(imit->second); } +}; + + +//////////////////////////////////////////////////////////////////////////////// +/////////////////////////////// TypeSynthesizer ////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +template <TypeID type_id> +class TypeSynthesizer : public TypeSynthesizePolicy<type_id> { + private: + using Trait = TypeIDTrait<type_id>; + using SynthesizePolicy = TypeSynthesizePolicy<type_id>; + + public: + static constexpr SuperTypeID kStaticSuperTypeID = Trait::kStaticSuperTypeID; + static constexpr TypeID kStaticTypeID = Trait::kStaticTypeID; + static constexpr bool kIsParPod = Trait::kIsParPod; + static constexpr MemoryLayout kMemoryLayout = Trait::kMemoryLayout; + + using TypeClass = typename Trait::TypeClass; + using cpptype = typename Trait::cpptype; + + serialization::Type getProto() const override { + serialization::Type proto; + proto.mutable_type_id()->CopyFrom(TypeIDFactory::GetProto(Type::type_id_)); + proto.set_nullable(Type::nullable_); + SynthesizePolicy::mergeIntoProto(&proto); + return proto; + } + + const Type& getNullableVersion() const override { + return SynthesizePolicy::getInstance(true); + } + + const Type& getNonNullableVersion() const override { + return SynthesizePolicy::getInstance(false); + } + + UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const override { + return SynthesizePolicy::unmarshallTypedValueInl(value); + } + + std::string printTypedValueToString(const TypedValue &value) const override { + return SynthesizePolicy::invokeOnUnmarshalledTypedValue( + value, + [&](const UntypedLiteral *value) -> std::string { + return this->printValueToString(value); + }); + } + + void printTypedValueToFile(const TypedValue &value, + FILE *file, + const int padding = 0) const override { + SynthesizePolicy::invokeOnUnmarshalledTypedValue( + value, + [&](const UntypedLiteral *value) -> void { + this->printValueToFile(value, file, padding); + }); + } + + const cpptype& castValueToLiteral(const UntypedLiteral *value) const { + return *static_cast<const cpptype*>(value); + } + + cpptype& castValueToLiteral(UntypedLiteral *value) const { + return *static_cast<cpptype*>(value); + } + + protected: + template <MemoryLayout layout = kMemoryLayout> + explicit TypeSynthesizer(const bool nullable, + std::enable_if_t<layout == kCxxInlinePod>* = 0) + : TypeSynthesizePolicy<type_id>(nullable) { + } + + template <MemoryLayout layout = kMemoryLayout> + TypeSynthesizer(const bool nullable, + const std::size_t minimum_byte_length, + const std::size_t maximum_byte_length, + const std::size_t parameter, + std::enable_if_t<layout == kParInlinePod || + layout == kParOutOfLinePod>* = 0) + : TypeSynthesizePolicy<type_id>(nullable, minimum_byte_length, + maximum_byte_length, parameter) { + } + + template <MemoryLayout layout = kMemoryLayout> + TypeSynthesizer(const bool nullable, + const std::size_t minimum_byte_length, + const std::size_t maximum_byte_length, + const std::vector<GenericValue> ¶meters = {}, + std::enable_if_t<layout == kCxxGeneric>* = 0) + : TypeSynthesizePolicy<type_id>(nullable, minimum_byte_length, + maximum_byte_length, parameters) { + } + + private: + template <TypeID, typename> friend class TypeSynthesizePolicy; - const Type &base_; + DISALLOW_COPY_AND_ASSIGN(TypeSynthesizer); }; +template <TypeID type_id> +constexpr SuperTypeID TypeSynthesizer<type_id>::kStaticSuperTypeID; + +template <TypeID type_id> +constexpr TypeID TypeSynthesizer<type_id>::kStaticTypeID; + +template <TypeID type_id> +constexpr bool TypeSynthesizer<type_id>::kIsParPod; + +template <TypeID type_id> +constexpr MemoryLayout TypeSynthesizer<type_id>::kMemoryLayout; + + #define QUICKSTEP_SYNTHESIZE_TYPE(type) \ template <TypeID, typename> friend class TypeSynthesizePolicy; \ DISALLOW_COPY_AND_ASSIGN(type) http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e69fb18/utility/CharStream.hpp ---------------------------------------------------------------------- diff --git a/utility/CharStream.hpp b/utility/CharStream.hpp index 060b1a6..5d6ed0b 100644 --- a/utility/CharStream.hpp +++ b/utility/CharStream.hpp @@ -40,32 +40,45 @@ class CharStream { template <typename T> CharStream(const T &value, std::enable_if_t<std::is_pod<T>::value && sizeof(T) <= sizeof(std::uint64_t)> * = 0) - : length_(sizeof(T)), + : object_(nullptr), + length_(sizeof(T)), delete_function_(nullptr) { std::memcpy(&value_union_.inline_data, &value, sizeof(T)); } - CharStream(std::vector<char> &&value) - : length_(value.size()), + CharStream(const std::vector<char> *value) + : object_(const_cast<std::vector<char>*>(value)), + length_(value->size()), delete_function_(&DeleteObject<std::vector<char>>) { - value_union_.out_of_line_data = new std::vector<char>(std::move(value)); + value_union_.out_of_line_data = value->data(); } - CharStream(const void *value, const std::size_t length, const bool take_ownership) + CharStream(const void *value, + const std::size_t length, + const bool take_ownership) : length_(length), delete_function_(std::free) { if (take_ownership) { - value_union_.out_of_line_data = value; + object_ = const_cast<void*>(value); } else { - void *copy_of_value = std::malloc(length); - std::memcpy(copy_of_value, value, length); - value_union_.out_of_line_data = copy_of_value; + object_ = std::malloc(length); + std::memcpy(object_, value, length); } + value_union_.out_of_line_data = object_; + } + + CharStream(CharStream &&other) + : object_(other.object_), + length_(other.length_), + value_union_(other.value_union_), + delete_function_(other.delete_function_) { + other.delete_function_ = nullptr; } ~CharStream() { if (delete_function_ != nullptr) { - delete_function_(const_cast<void*>(value_union_.out_of_line_data)); + DCHECK(object_ != nullptr); + delete_function_(object_); } } @@ -91,6 +104,7 @@ class CharStream { delete static_cast<T*>(object); } + void *object_; std::size_t length_; ValueUnion value_union_; DeleterFunction delete_function_; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e69fb18/utility/meta/Common.hpp ---------------------------------------------------------------------- diff --git a/utility/meta/Common.hpp b/utility/meta/Common.hpp index 39c513e..901b65c 100644 --- a/utility/meta/Common.hpp +++ b/utility/meta/Common.hpp @@ -27,6 +27,22 @@ namespace meta { * @{ */ +template <typename ...> struct Conjunction : std::true_type {}; +template <typename B> struct Conjunction<B> : B {}; +template <typename B, typename ...Bs> +struct Conjunction<B, Bs...> + : std::conditional_t<B::value, Conjunction<Bs...>, B> {}; + +template <typename ...> struct Disjunction : std::false_type {}; +template <typename B> struct Disjunction<B> : B {}; +template <typename B, typename ...Bs> +struct Disjunction<B, Bs...> + : std::conditional_t<B::value, B, Disjunction<Bs...>> {}; + +template <typename check, typename ...cases> +struct EqualsAny : Disjunction<std::is_same<check, cases>...> {}; + + template <typename T, T ...s> struct Sequence { template <template <typename ...> class Host> @@ -38,6 +54,10 @@ struct Sequence { template <typename U> using cast_to = Sequence<U, static_cast<U>(s)...>; + template <T v> + using contains = EqualsAny<std::integral_constant<T, v>, + std::integral_constant<T, s>...>; + template <typename CollectionT> inline static CollectionT Instantiate() { return { s... }; @@ -57,25 +77,6 @@ struct MakeSequence<0, s...> { }; -template <typename ...> struct Conjunction : std::true_type {}; -template <typename B> struct Conjunction<B> : B {}; -template <typename B, typename ...Bs> -struct Conjunction<B, Bs...> - : std::conditional_t<B::value, Conjunction<Bs...>, B> {}; - -template <typename ...> struct Disjunction : std::false_type {}; -template <typename B> struct Disjunction<B> : B {}; -template <typename B, typename ...Bs> -struct Disjunction<B, Bs...> - : std::conditional_t<B::value, B, Disjunction<Bs...>> {}; - -template <typename check, typename ...cases> -struct EqualsAny { - static constexpr bool value = - Disjunction<std::is_same<check, cases>...>::value; -}; - - template <typename T, typename Enable = void> struct IsTrait { static constexpr bool value = false; @@ -135,6 +136,25 @@ struct TraitUnwrapper { using type = typename Op<ArgTypes...>::type; }; + +using CxxSupportedIntegerSizes = meta::IntegerSequence<1u, 2u, 4u, 8u>; + +template <std::size_t size> +struct UnsignedInteger; + +template <> struct UnsignedInteger<1u> { + using type = std::uint8_t; +}; +template <> struct UnsignedInteger<2u> { + using type = std::uint16_t; +}; +template <> struct UnsignedInteger<4u> { + using type = std::uint32_t; +}; +template <> struct UnsignedInteger<8u> { + using type = std::uint64_t; +}; + /** @} */ } // namespace meta http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e69fb18/validate_cmakelists.py ---------------------------------------------------------------------- diff --git a/validate_cmakelists.py b/validate_cmakelists.py index f5f2f89..4de44c9 100755 --- a/validate_cmakelists.py +++ b/validate_cmakelists.py @@ -415,7 +415,7 @@ def process_cmakelists_file(cmakelists_filename, qs_module_dirs): validation_failed_targets.add(target) print("Missing target_link_libraries() for " + target + ":") for dep in sorted(include_deps): - print("\t" + dep) + print(" " + dep) else: missing_deps = (include_deps - deps_in_cmake[target] @@ -424,7 +424,7 @@ def process_cmakelists_file(cmakelists_filename, qs_module_dirs): validation_failed_targets.add(target) print("Missing target_link_libraries() for " + target + ":") for dep in sorted(missing_deps): - print("\t" + dep) + print(" " + dep) elif target == module_targetname: # Special case hack for module all-in-one library missing_deps = (frozenset(deps_from_includes.keys()) @@ -438,7 +438,7 @@ def process_cmakelists_file(cmakelists_filename, qs_module_dirs): validation_failed_targets.add(target) print("Missing target_link_libraries() for " + target + ":") for dep in sorted(true_missing_deps): - print("\t" + dep) + print(" " + dep) # Also report possibly superfluous extra dependencies. for target, cmake_deps in iter(deps_in_cmake.items()): if (target not in skipped_targets) and (target in deps_from_includes): @@ -450,7 +450,7 @@ def process_cmakelists_file(cmakelists_filename, qs_module_dirs): print("Possibly superfluous target_link_libraries() for " + target + ":") for dep in sorted(extra_deps): - print("\t" + dep) + print(" " + dep) return (validation_failed_targets, skipped_targets, generated_targets) def main(cmakelists_to_process):
