//  Copyright (c) 2013, Facebook, Inc.  All rights reserved.
//  This source code is licensed under both the GPLv2 (found in the
//  COPYING file in the root directory) and Apache 2.0 License
//  (found in the LICENSE.Apache file in the root directory).
//
#ifndef ROCKSDB_LITE

#include "utilities/persistent_cache/volatile_tier_impl.h"

#include <string>

namespace rocksdb {

void VolatileCacheTier::DeleteCacheData(VolatileCacheTier::CacheData* data) {
  assert(data);
  delete data;
}

VolatileCacheTier::~VolatileCacheTier() { index_.Clear(&DeleteCacheData); }

PersistentCache::StatsType VolatileCacheTier::Stats() {
  std::map<std::string, double> stat;
  stat.insert({"persistent_cache.volatile_cache.hits",
               static_cast<double>(stats_.cache_hits_)});
  stat.insert({"persistent_cache.volatile_cache.misses",
               static_cast<double>(stats_.cache_misses_)});
  stat.insert({"persistent_cache.volatile_cache.inserts",
               static_cast<double>(stats_.cache_inserts_)});
  stat.insert({"persistent_cache.volatile_cache.evicts",
               static_cast<double>(stats_.cache_evicts_)});
  stat.insert({"persistent_cache.volatile_cache.hit_pct",
               static_cast<double>(stats_.CacheHitPct())});
  stat.insert({"persistent_cache.volatile_cache.miss_pct",
               static_cast<double>(stats_.CacheMissPct())});

  auto out = PersistentCacheTier::Stats();
  out.push_back(stat);
  return out;
}

Status VolatileCacheTier::Insert(const Slice& page_key, const char* data,
                                 const size_t size) {
  // precondition
  assert(data);
  assert(size);

  // increment the size
  size_ += size;

  // check if we have overshot the limit, if so evict some space
  while (size_ > max_size_) {
    if (!Evict()) {
      // unable to evict data, we give up so we don't spike read
      // latency
      assert(size_ >= size);
      size_ -= size;
      return Status::TryAgain("Unable to evict any data");
    }
  }

  assert(size_ >= size);

  // insert order: LRU, followed by index
  std::string key(page_key.data(), page_key.size());
  std::string value(data, size);
  std::unique_ptr<CacheData> cache_data(
      new CacheData(std::move(key), std::move(value)));
  bool ok = index_.Insert(cache_data.get());
  if (!ok) {
    // decrement the size that we incremented ahead of time
    assert(size_ >= size);
    size_ -= size;
    // failed to insert to cache, block already in cache
    return Status::TryAgain("key already exists in volatile cache");
  }

  cache_data.release();
  stats_.cache_inserts_++;
  return Status::OK();
}

Status VolatileCacheTier::Lookup(const Slice& page_key,
                                 std::unique_ptr<char[]>* result,
                                 size_t* size) {
  CacheData key(std::move(page_key.ToString()));
  CacheData* kv;
  bool ok = index_.Find(&key, &kv);
  if (ok) {
    // set return data
    result->reset(new char[kv->value.size()]);
    memcpy(result->get(), kv->value.c_str(), kv->value.size());
    *size = kv->value.size();
    // drop the reference on cache data
    kv->refs_--;
    // update stats
    stats_.cache_hits_++;
    return Status::OK();
  }

  stats_.cache_misses_++;

  if (next_tier()) {
    return next_tier()->Lookup(page_key, result, size);
  }

  return Status::NotFound("key not found in volatile cache");
}

bool VolatileCacheTier::Erase(const Slice& key) {
  assert(!"not supported");
  return true;
}

bool VolatileCacheTier::Evict() {
  CacheData* edata = index_.Evict();
  if (!edata) {
    // not able to evict any object
    return false;
  }

  stats_.cache_evicts_++;

  // push the evicted object to the next level
  if (next_tier()) {
    next_tier()->Insert(Slice(edata->key), edata->value.c_str(),
                        edata->value.size());
  }

  // adjust size and destroy data
  size_ -= edata->value.size();
  delete edata;

  return true;
}

}  // namespace rocksdb

#endif
