/**
 *   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_PLACEMENT_SCHEME_HPP_
#define QUICKSTEP_CATALOG_PARTITION_PLACEMENT_SCHEME_HPP_

#include <numa.h>

#include <cstddef>
#include <ostream>
#include <unordered_map>
#include <utility>

#include "catalog/Catalog.pb.h"
#include "catalog/CatalogTypedefs.hpp"
#include "storage/StorageBlockInfo.hpp"
#include "utility/Macros.hpp"

#include "glog/logging.h"

namespace quickstep {

/** \addtogroup Catalog
 *  @{
 */

/**
 * @brief A NUMAPlacementScheme object which stores the mapping between the
 * blocks in a partition and the NUMA nodes corresponding to those partitions.
 *
 * @note NUMA stands for Non-Uniform Memory Access.
 *
 * @note There is always only a one-on-one mapping between the partitions and
 * the NUMA nodes. This means that the blocks of a relation that belong to a
 * particular partition can be placed on ONLY one NUMA node. Earlier we had a
 * design where we can place the blocks in a single partition on multiple
 * NUMA nodes but we later decided that there wouldn't be any scenario where
 * we would want to place the blocks belonging to a single partition on more
 * than one NUMA node and hence that earlier design has been discarded.
 *
 * @note The terms node and socket would be used interchangeably in the
 * context of NUMA. A NUMA node or a NUMA socket would essentially mean
 * the same.
 **/
class NUMAPlacementScheme {
 public:
  /**
   * @brief Constructor.
   *
   * @param num_partitions The number of partitions of the Catalog Relation.
   *                       This would be the same as the number of partitions
   *                       in the Partition Scheme of the relation.
   **/
  explicit NUMAPlacementScheme(const std::size_t num_partitions)
      : num_numa_nodes_(numa_num_configured_nodes()),
        num_partitions_(num_partitions) {
    // Assign each partition to exactly one NUMA node.
    // Partitions are assigned in a round robin way to NUMA nodes.
    for (std::size_t part_id = 0;
         part_id < num_partitions_;
         ++part_id) {
      partition_to_numa_node_map_[part_id] = part_id % num_numa_nodes_;
    }
  }

  /**
   * @brief Destructor.
   **/
  ~NUMAPlacementScheme() {}

  /**
   * @brief Get the number of partitions.
   *
   * @return Number of partitions in the Catalog Relation.
   **/
  inline std::size_t getNumPartitions() const {
    return num_partitions_;
  }

  /**
   * @brief Get the total number of NUMA nodes available in the system.
   *
   * @return Total number of NUMA nodes available in the system.
   **/
  inline std::size_t getNumNUMANodes() const {
    return num_numa_nodes_;
  }

  /**
   * @brief Get the NUMA node on which a partition is placed.
   *
   * @param part_id The partition id for which to find the NUMA node.
   *
   * @return The NUMA node on which the partition is placed.
   **/
  inline numa_node_id getNUMANodeForPartition(const partition_id part_id)
      const {
    auto partition_to_numa_node_map_iter =
        partition_to_numa_node_map_.find(part_id);
    DCHECK(partition_to_numa_node_map_iter != partition_to_numa_node_map_.end());
    return partition_to_numa_node_map_iter->second;
  }

  /**
   * @brief Add a mapping between a block and the NUMA node on which the block
   *        is placed.
   *
   * @param block The block_id of the block for which the NUMA node mapping is
   *              added.
   * @param numa_node The numa node id on which the block is placed.
   **/
  void addBlockToNUMANodeMap(const block_id block, const int numa_node) {
    // Make sure that the block doesn't have a mapping already.
    // A block will be mapped to only one NUMA node.
    // A NUMA node will be associated with a block only once.
    DCHECK(block_to_numa_node_map_.find(block) == block_to_numa_node_map_.end());
    DCHECK_GT(numa_num_configured_nodes(), numa_node)
        << "NUMA node above the valid value.";
    block_to_numa_node_map_[block] = numa_node;
  }

  /**
   * @brief Get the NUMA node associated with a block.
   *
   * @param block The block_id of the block for which the associated NUMA node
   *              id is to be found.
   *
   * @return The NUMA node id associated with the block.
   **/
  inline numa_node_id getNUMANodeForBlock(const block_id block) const {
    auto block_to_numa_node_map_iter = block_to_numa_node_map_.find(block);
    DCHECK(block_to_numa_node_map_iter != block_to_numa_node_map_.end());
    return block_to_numa_node_map_iter->second;
  }

  /**
   * @brief Check whether a serialization::NUMAPlacementScheme is fully-formed
   *        and all parts are valid.
   *
   * @param proto A serialized Protocol Buffer representation of a
   *              NUMAPlacementScheme, originally generated by getProto().
   *
   * @return Whether proto is fully-formed and valid.
   **/
  static bool ProtoIsValid(const serialization::NUMAPlacementScheme &proto);

  /**
   * @brief Serialize the NUMA Placement Scheme as Protocol Buffer.
   *
   * @return The Protocol Buffer representation of NUMA Placement Scheme.
   **/
  serialization::NUMAPlacementScheme getProto() const;

  /**
   * @brief Reconstruct a NUMA Placement Scheme from its serialized
   *        Protocol Buffer form.
   *
   * @param proto The Protocol Buffer serialization of a NUMA Placement Scheme,
   *              previously produced by getProto().
   * @param partition_proto The Protocol Buffer serialization of a
   *                        ParitionScheme. This is needed for number of
   *                        partitions.
   *
   * @return The deserialized NUMA Placement Scheme object.
   **/
  static NUMAPlacementScheme* ReconstructFromProto(
      const serialization::NUMAPlacementScheme &proto,
      const std::size_t num_partitions);

 private:
  // Number of NUMA nodes available in the system.
  const std::size_t num_numa_nodes_;

  // Number of partitions in the Catalog Relation.
  const std::size_t num_partitions_;

  // A map between the partition ids and NUMA node ids.
  // All the blocks that belong to a particular partition are placed on only
  // one NUMA node.
  std::unordered_map<partition_id, numa_node_id> partition_to_numa_node_map_;

  // A map between the block ids and the NUMA node ids.
  std::unordered_map<block_id, numa_node_id> block_to_numa_node_map_;

  DISALLOW_COPY_AND_ASSIGN(NUMAPlacementScheme);
};

/** @} */

}  // namespace quickstep

#endif  // QUICKSTEP_CATALOG_PARTITION_PLACEMENT_SCHEME_HPP_
