/**
 * 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_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 managed by Shiftboss in the distributed version.
 *        During the runtime, it contains all the referenced relation schemas
 *        to execute a query. For a SELECT query, the temporary query
 *        result relation will be dropped after the CLI finishes processing the
 *        result and notifies Shiftboss.
 *
 * @note A CatalogRelationSchema should be kept unless all associated blocks
 *       have been deleted.
 **/
class CatalogDatabaseCache final : 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_
