| /** |
| * Copyright 2011-2015 Quickstep Technologies LLC. |
| * Copyright 2015 Pivotal Software, Inc. |
| * |
| * 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. |
| **/ |
| |
| #ifndef QUICKSTEP_TYPES_CONTAINERS_TUPLE_HPP_ |
| #define QUICKSTEP_TYPES_CONTAINERS_TUPLE_HPP_ |
| |
| #include <cstddef> |
| #include <memory> |
| #include <utility> |
| #include <vector> |
| |
| #include "catalog/CatalogTypedefs.hpp" |
| #include "types/TypedValue.hpp" |
| #include "types/containers/Tuple.pb.h" |
| #include "utility/Macros.hpp" |
| |
| #include "glog/logging.h" |
| |
| namespace quickstep { |
| |
| /** \addtogroup Types |
| * @{ |
| */ |
| |
| /** |
| * @brief A representation of a single tuple, i.e. a list of values |
| * corresponding to the attributes of a relation. |
| **/ |
| class Tuple { |
| public: |
| typedef std::vector<TypedValue>::const_iterator const_iterator; |
| typedef std::vector<TypedValue>::size_type size_type; |
| |
| /** |
| * @brief Constructor which creates a Tuple by taking ownership of existing |
| * TypedValues. |
| * |
| * @param attribute_values A vector of TypedValues, which are the attribute |
| * values, in order, of the Tuple to be constructed. Will be moved |
| * from. |
| **/ |
| explicit Tuple(std::vector<TypedValue> &&attribute_values) |
| : attribute_values_(std::move(attribute_values)) { |
| } |
| |
| /** |
| * @brief Move constructor. |
| **/ |
| Tuple(Tuple &&original) |
| : attribute_values_(std::move(original.attribute_values_)) { |
| } |
| |
| /** |
| * @brief Destructor. |
| **/ |
| ~Tuple() { |
| } |
| |
| /** |
| * @brief Check whether a serialization::Tuple is fully-formed and all parts |
| * are valid. |
| * |
| * @param proto A serialized Protocol Buffer description of a Tuple, |
| * originally generated by the optimizer. |
| * |
| * @return Whether proto is fully-formed and valid. |
| **/ |
| static bool ProtoIsValid(const serialization::Tuple &proto) { |
| for (int i = 0; i < proto.attribute_values_size(); ++i) { |
| if (!TypedValue::ProtoIsValid(proto.attribute_values(i))) { |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| /** |
| * @brief Generate the tuple from the serialized Protocol Buffer |
| * representation. |
| * |
| * @param proto A serialized Protocol Buffer representation of a Tuple, |
| * originally generated by the optimizer. |
| * |
| * @return The generated Tuple. |
| **/ |
| static Tuple* ReconstructFromProto(const serialization::Tuple &proto) { |
| DCHECK(ProtoIsValid(proto)) |
| << "Attempted to create Tuple from an invalid proto description:\n" |
| << proto.DebugString(); |
| |
| std::vector<TypedValue> attribute_values; |
| for (int i = 0; i < proto.attribute_values_size(); ++i) { |
| attribute_values.emplace_back(TypedValue::ReconstructFromProto(proto.attribute_values(i))); |
| } |
| |
| return new Tuple(std::move(attribute_values)); |
| } |
| |
| /** |
| * @brief Move-assignment. |
| **/ |
| Tuple& operator=(Tuple &&other) { |
| if (&other != this) { |
| attribute_values_ = std::move(other.attribute_values_); |
| } |
| return *this; |
| } |
| |
| /** |
| * @brief Ensure that every value contained in this tuple is a literal, |
| * copying references as neccesary. |
| **/ |
| void ensureLiteral() { |
| for (std::vector<TypedValue>::iterator value_it = attribute_values_.begin(); |
| value_it != attribute_values_.end(); |
| ++value_it) { |
| value_it->ensureNotReference(); |
| } |
| } |
| |
| /** |
| * @brief Make a complete copy of this Tuple, forcing a literal copy of each |
| * attribute value. |
| * |
| * @return A deep copy of this Tuple. |
| **/ |
| Tuple* clone() const { |
| std::unique_ptr<Tuple> clone(new Tuple()); |
| clone->attribute_values_ = attribute_values_; |
| clone->ensureLiteral(); |
| return clone.release(); |
| } |
| |
| /** |
| * @brief Get the value of the specified attribute. |
| * @warning This is only safe if gapsInAttributeSequence() is false for the |
| * relation this tuple belongs to. |
| * |
| * @param attr The id of the attribute to get. |
| * @return The attribute's value in this tuple. |
| **/ |
| const TypedValue& getAttributeValue(const attribute_id attr) const { |
| DCHECK_GE(attr, 0); |
| // The cast supresses a warning about comparing signed and unsigned types. |
| DCHECK_LT(static_cast<std::vector<TypedValue>::size_type>(attr), attribute_values_.size()); |
| return attribute_values_[attr]; |
| } |
| |
| /** |
| * @brief Get the attribute values vector of the tuple. |
| * @warning This is only safe if gapsInAttributeSequence() is false for the |
| * relation this tuple belongs to. |
| * @return The attribute values vector of this tuple. |
| **/ |
| const std::vector<TypedValue>& getAttributeValueVector() const { |
| return attribute_values_; |
| } |
| |
| /** |
| * @brief Get the total size, in bytes, of all values in this Tuple. |
| * @note This method returns the sum of the storage space necessary to store |
| * all attribute values in this Tuple, NOT the space actually used to |
| * represent them at TypedValues. |
| * |
| * @return The storage size of this Tuple in bytes. |
| **/ |
| std::size_t getByteSize() const { |
| std::size_t total_size = 0; |
| for (const_iterator it = begin(); it != end(); ++it) { |
| total_size += it->isNull() ? 0 : it->getDataSize(); |
| } |
| return total_size; |
| } |
| |
| /** |
| * @brief Get an iterator at the beginning of the attribute values in this |
| * Tuple. |
| * |
| * @return An iterator at the beginning of this Tuple. |
| **/ |
| const_iterator begin() const { |
| return attribute_values_.begin(); |
| } |
| |
| /** |
| * @brief Get an iterator one-past-the-end of the attribute values in this |
| * Tuple. |
| * |
| * @return An iterator one-past-the-end of this Tuple. |
| **/ |
| const_iterator end() const { |
| return attribute_values_.end(); |
| } |
| |
| /** |
| * @brief Get the number of attributes in this Tuple. |
| * |
| * @return The number of attributes in this Tuple. |
| **/ |
| size_type size() const { |
| return attribute_values_.size(); |
| } |
| |
| private: |
| /** |
| * @brief Constructor which does not create any attributes, nor pre-reserve |
| * space. |
| * @warning This is only used by clone(), and should not otherwise be used. |
| **/ |
| Tuple() { |
| } |
| |
| std::vector<TypedValue> attribute_values_; |
| |
| DISALLOW_COPY_AND_ASSIGN(Tuple); |
| }; |
| |
| /** @} */ |
| |
| } // namespace quickstep |
| |
| #endif // QUICKSTEP_TYPES_CONTAINERS_TUPLE_HPP_ |