blob: 6237d549a67a70127554981799d588b83c2eb120 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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/CompositeHash.hpp"
#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();
}
/**
* @brief Get the hash value of the tuple.
**/
std::size_t getTupleHash() const {
return HashCompositeKey(attribute_values_);
}
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_