| /** |
| * 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. |
| **/ |
| |
| #ifndef QUICKSTEP_CATALOG_PARTITION_SCHEME_HPP_ |
| #define QUICKSTEP_CATALOG_PARTITION_SCHEME_HPP_ |
| |
| #include <cstddef> |
| #include <memory> |
| #include <unordered_set> |
| #include <utility> |
| #include <vector> |
| |
| #include "catalog/Catalog.pb.h" |
| #include "catalog/CatalogTypedefs.hpp" |
| #include "catalog/PartitionSchemeHeader.hpp" |
| #include "storage/StorageBlockInfo.hpp" |
| #include "threading/Mutex.hpp" |
| #include "threading/SharedMutex.hpp" |
| #include "threading/SpinSharedMutex.hpp" |
| #include "utility/Macros.hpp" |
| |
| #include "glog/logging.h" |
| |
| namespace quickstep { |
| |
| class Type; |
| |
| /** \addtogroup Catalog |
| * @{ |
| */ |
| |
| /** |
| * @brief The class which stores the partitioning information and partitioned |
| * blocks for a particular relation. |
| **/ |
| class PartitionScheme { |
| public: |
| /** |
| * @brief Constructor. |
| * @note The constructor takes ownership of \c header. |
| * |
| * @param header The partition header. |
| * @param blocks_in_partition All blocks in partitions. |
| **/ |
| explicit PartitionScheme(PartitionSchemeHeader *header) |
| : header_(DCHECK_NOTNULL(header)), |
| blocks_in_partition_(header_->getNumPartitions()), |
| blocks_in_partition_mutexes_(header_->getNumPartitions()) {} |
| |
| /** |
| * @brief Constructor. |
| * @note The constructor takes ownership of \c header. |
| * |
| * @param header The partition header. |
| * @param blocks_in_partition All blocks in partitions. |
| **/ |
| PartitionScheme(PartitionSchemeHeader *header, |
| std::vector<std::unordered_set<block_id>> &&blocks_in_partition) |
| : header_(DCHECK_NOTNULL(header)), |
| blocks_in_partition_(std::move(blocks_in_partition)), |
| blocks_in_partition_mutexes_(header_->getNumPartitions()) {} |
| |
| /** |
| * @brief Reconstruct a Partition Scheme from its serialized |
| * Protocol Buffer form. |
| * |
| * @param proto The Protocol Buffer serialization of a Partition Scheme, |
| * previously produced by getProto(). |
| * @param attr_type The attribute type of the partitioning attribute. |
| * @return The deserialized partition scheme object. |
| **/ |
| static PartitionScheme* ReconstructFromProto(const serialization::PartitionScheme &proto, |
| const Type &attr_type); |
| |
| /** |
| * @brief Check whether a serialization::PartitionScheme is fully-formed and |
| * all parts are valid. |
| * |
| * @param proto A serialized Protocol Buffer representation of a |
| * PartitionScheme, originally generated by getProto(). |
| * @return Whether proto is fully-formed and valid. |
| **/ |
| static bool ProtoIsValid(const serialization::PartitionScheme &proto); |
| |
| /** |
| * @brief Get the partitioning attribute for the relation. |
| * |
| * @return The partitioning attribute with which the relation |
| * is partitioned into. |
| **/ |
| const PartitionSchemeHeader& getPartitionSchemeHeader() const { |
| return *header_; |
| } |
| |
| /** |
| * @brief Add a block to a partition. |
| * |
| * @param block_id The id of the block to be added to the partition. |
| * @param part_id The id of the partition to add the block to. |
| **/ |
| inline void addBlockToPartition(const block_id block, |
| const partition_id part_id) { |
| DCHECK_LT(part_id, header_->getNumPartitions()); |
| SpinSharedMutexExclusiveLock<false> lock( |
| blocks_in_partition_mutexes_[part_id]); |
| blocks_in_partition_[part_id].insert(block); |
| } |
| |
| /** |
| * @brief Remove a block from a partition. |
| * |
| * @param block_id The id of the block to be removed from the partition. |
| * @param part_id The id of the partition to remove the block from. |
| **/ |
| inline void removeBlockFromPartition(const block_id block, |
| const partition_id part_id) { |
| DCHECK_LT(part_id, header_->getNumPartitions()); |
| SpinSharedMutexExclusiveLock<false> lock( |
| blocks_in_partition_mutexes_[part_id]); |
| std::unordered_set<block_id> &blocks_in_partition = |
| blocks_in_partition_[part_id]; |
| blocks_in_partition.erase(block); |
| } |
| |
| /** |
| * @brief Get all the blocks from a particular partition. |
| * |
| * @param part_id The id of the partition to retrieve the blocks from. |
| * @return The block_ids of blocks belonging to this partition at the moment |
| * when this method is called. |
| **/ |
| inline std::vector<block_id> getBlocksInPartition( |
| const partition_id part_id) const { |
| DCHECK_LT(part_id, header_->getNumPartitions()); |
| SpinSharedMutexSharedLock<false> lock( |
| blocks_in_partition_mutexes_[part_id]); |
| return std::vector<block_id>(blocks_in_partition_[part_id].begin(), |
| blocks_in_partition_[part_id].end()); |
| } |
| |
| /** |
| * @brief Serialize the Partition Scheme as Protocol Buffer. |
| * |
| * @return The Protocol Buffer representation of Partition Scheme. |
| **/ |
| serialization::PartitionScheme getProto() const; |
| |
| /** |
| * @brief Get the partition id for a block. |
| * |
| * @param block The id of the block. |
| * |
| * @return The partition id to which the block belongs. If the block is not |
| * found in any partition, then the maximum finite value for the type |
| * std::size_t is returned. |
| **/ |
| partition_id getPartitionForBlock(const block_id block) const; |
| |
| private: |
| std::unique_ptr<const PartitionSchemeHeader> header_; |
| |
| // The unordered set of blocks per partition. |
| std::vector<std::unordered_set<block_id>> blocks_in_partition_; |
| // Mutexes for locking each partition separately. |
| mutable std::vector<SpinSharedMutex<false>> blocks_in_partition_mutexes_; |
| |
| DISALLOW_COPY_AND_ASSIGN(PartitionScheme); |
| }; |
| |
| /** @} */ |
| |
| } // namespace quickstep |
| |
| #endif // QUICKSTEP_CATALOG_PARTITION_SCHEME_HPP_ |