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

/** \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().
   * @return The deserialized partition scheme object.
   **/
  static PartitionScheme* ReconstructFromProto(const serialization::PartitionScheme &proto);

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