/**
 *   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_CATALOG_DATABASE_CACHE_HPP_
#define QUICKSTEP_CATALOG_CATALOG_DATABASE_CACHE_HPP_

#include <cstddef>
#include <memory>
#include <unordered_map>
#include <utility>

#include "catalog/CatalogDatabaseLite.hpp"
#include "catalog/CatalogTypedefs.hpp"
#include "storage/StorageConstants.hpp"
#include "threading/SharedMutex.hpp"
#include "threading/SpinSharedMutex.hpp"
#include "utility/Macros.hpp"

#include "glog/logging.h"

namespace quickstep {

class CatalogRelationSchema;

namespace serialization { class CatalogDatabase; }

/** \addtogroup Catalog
 *  @{
 */

/**
 * @brief A database cache used in the distributed version and managed by
 *        Shiftboss.
 **/
class CatalogDatabaseCache : public CatalogDatabaseLite {
 public:
  /**
   * @brief Constructor.
   **/
  CatalogDatabaseCache() {
  }

  /**
   * @brief Constructor. Reconstruct a database cache from its serialized
   *        Protocol Buffer form.
   *
   * @param proto The Protocol Buffer serialization of a database, previously
   *        produced by the optimizer.
   **/
  explicit CatalogDatabaseCache(const serialization::CatalogDatabase &proto);

  /**
   * @brief Destructor which recursively destroys children.
   **/
  ~CatalogDatabaseCache() override {
  }

  bool hasRelationWithId(const relation_id id) const override {
    SpinSharedMutexSharedLock<false> lock(relations_mutex_);
    return rel_map_.find(id) != rel_map_.end();
  }

  const CatalogRelationSchema& getRelationSchemaById(const relation_id id) const override {
    SpinSharedMutexSharedLock<false> lock(relations_mutex_);
    const auto cit = rel_map_.find(id);

    DCHECK(cit != rel_map_.end());
    return *(cit->second);
  }

  void dropRelationById(const relation_id id) override;

  /**
   * @brief Get the number of child relations.
   *
   * @return The number of child relations.
   **/
  std::size_t size() const {
    SpinSharedMutexSharedLock<false> lock(relations_mutex_);
    return rel_map_.size();
  }

  /**
   * @brief Update the cache from its serialized Protocol Buffer form. If the
   *        relation schema exists, it will be ignored.
   *
   * @param proto The Protocol Buffer serialization of a catalog cache,
   *        previously produced in optimizer.
   **/
  void update(const serialization::CatalogDatabase &proto);

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

  /**
   * @brief Map from relation id to the pointer to the corresponding relation schema.
   */
  std::unordered_map<relation_id, std::unique_ptr<const CatalogRelationSchema>> rel_map_;

  // Concurrency protection for 'rel_map_'.
  alignas(kCacheLineBytes) mutable SpinSharedMutex<false> relations_mutex_;

  DISALLOW_COPY_AND_ASSIGN(CatalogDatabaseCache);
};

/** @} */

}  // namespace quickstep

#endif  // QUICKSTEP_CATALOG_CATALOG_DATABASE_CACHE_HPP_
