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