| /** |
| * 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 |