blob: 66f4c029e7ee7842094f957e0b3b5cc85fa1f44a [file] [log] [blame]
/**
* Copyright 2011-2015 Quickstep Technologies LLC.
* Copyright 2015-2016 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.
**/
#include "catalog/PartitionSchemeHeader.hpp"
#include <cstddef>
#include <utility>
#include <vector>
#include "catalog/Catalog.pb.h"
#include "types/TypedValue.hpp"
#include "types/TypedValue.pb.h"
#include "glog/logging.h"
namespace quickstep {
PartitionSchemeHeader::PartitionSchemeHeader(const PartitionType type,
const std::size_t num_partitions,
const attribute_id attr_id)
: partition_type_(type),
num_partitions_(num_partitions),
partition_attribute_id_(attr_id) {
DCHECK_GT(num_partitions, 0u);
DCHECK_GE(attr_id, 0);
}
bool PartitionSchemeHeader::ProtoIsValid(
const serialization::PartitionSchemeHeader &proto) {
// Check that proto is fully initialized.
if (!proto.IsInitialized()) {
return false;
}
// Check if the partitioning attribute exists in the relation.
// TODO(gerald): Figure out how to find the max_attr_id of the
// relation so that we can check that partitioning attribute
// is not greater than the max_attr_id.
// Check that the proto has a valid partition type.
switch (proto.partition_type()) {
case serialization::PartitionSchemeHeader::HASH:
return true;
case serialization::PartitionSchemeHeader::RANGE: {
const std::size_t num_ranges =
proto.ExtensionSize(serialization::RangePartitionSchemeHeader::partition_range_boundaries);
return num_ranges == proto.num_partitions() - 1;
}
default:
// Partition type is unknown.
return false;
}
}
PartitionSchemeHeader* PartitionSchemeHeader::ReconstructFromProto(
const serialization::PartitionSchemeHeader &proto, const Type &attr_type) {
DCHECK(ProtoIsValid(proto))
<< "Attempted to create PartitionSchemeHeader from an invalid proto description:\n"
<< proto.DebugString();
switch (proto.partition_type()) {
case serialization::PartitionSchemeHeader::HASH: {
return new HashPartitionSchemeHeader(proto.num_partitions(), proto.partition_attribute_id());
}
case serialization::PartitionSchemeHeader::RANGE: {
std::vector<TypedValue> partition_ranges;
for (int i = 0;
i < proto.ExtensionSize(serialization::RangePartitionSchemeHeader::partition_range_boundaries);
++i) {
partition_ranges.emplace_back(
TypedValue::ReconstructFromProto(
proto.GetExtension(serialization::RangePartitionSchemeHeader::partition_range_boundaries, i)));
}
return new RangePartitionSchemeHeader(attr_type,
proto.num_partitions(),
proto.partition_attribute_id(),
std::move(partition_ranges));
}
default:
LOG(FATAL) << "Invalid partition scheme header.";
}
}
serialization::PartitionSchemeHeader PartitionSchemeHeader::getProto() const {
serialization::PartitionSchemeHeader proto;
switch (partition_type_) {
case PartitionType::kHash:
proto.set_partition_type(serialization::PartitionSchemeHeader::HASH);
break;
case PartitionType::kRange:
LOG(FATAL) << "RangePartitionSchemeHeader should call the overridden method.";
default:
LOG(FATAL) << "Invalid Partition Type.";
}
proto.set_num_partitions(num_partitions_);
proto.set_partition_attribute_id(partition_attribute_id_);
return proto;
}
serialization::PartitionSchemeHeader RangePartitionSchemeHeader::getProto() const {
serialization::PartitionSchemeHeader proto;
proto.set_partition_type(serialization::PartitionSchemeHeader::RANGE);
proto.set_num_partitions(num_partitions_);
proto.set_partition_attribute_id(partition_attribute_id_);
for (std::size_t i = 0; i < partition_range_boundaries_.size(); ++i) {
proto.AddExtension(serialization::RangePartitionSchemeHeader::partition_range_boundaries)
->MergeFrom(partition_range_boundaries_[i].getProto());
}
return proto;
}
} // namespace quickstep