//===-- FormatCache.cpp ------------------------------------------*- C++
//-*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//




#include "lldb/DataFormatters/FormatCache.h"

using namespace lldb;
using namespace lldb_private;

FormatCache::Entry::Entry()
    : m_format_cached(false), m_summary_cached(false),
      m_synthetic_cached(false), m_validator_cached(false), m_format_sp(),
      m_summary_sp(), m_synthetic_sp(), m_validator_sp() {}

FormatCache::Entry::Entry(lldb::TypeFormatImplSP format_sp)
    : m_summary_cached(false), m_synthetic_cached(false),
      m_validator_cached(false), m_summary_sp(), m_synthetic_sp(),
      m_validator_sp() {
  SetFormat(format_sp);
}

FormatCache::Entry::Entry(lldb::TypeSummaryImplSP summary_sp)
    : m_format_cached(false), m_synthetic_cached(false),
      m_validator_cached(false), m_format_sp(), m_synthetic_sp(),
      m_validator_sp() {
  SetSummary(summary_sp);
}

FormatCache::Entry::Entry(lldb::SyntheticChildrenSP synthetic_sp)
    : m_format_cached(false), m_summary_cached(false),
      m_validator_cached(false), m_format_sp(), m_summary_sp(),
      m_validator_sp() {
  SetSynthetic(synthetic_sp);
}

FormatCache::Entry::Entry(lldb::TypeValidatorImplSP validator_sp)
    : m_format_cached(false), m_summary_cached(false),
      m_synthetic_cached(false), m_format_sp(), m_summary_sp(),
      m_synthetic_sp() {
  SetValidator(validator_sp);
}

FormatCache::Entry::Entry(lldb::TypeFormatImplSP format_sp,
                          lldb::TypeSummaryImplSP summary_sp,
                          lldb::SyntheticChildrenSP synthetic_sp,
                          lldb::TypeValidatorImplSP validator_sp) {
  SetFormat(format_sp);
  SetSummary(summary_sp);
  SetSynthetic(synthetic_sp);
  SetValidator(validator_sp);
}

bool FormatCache::Entry::IsFormatCached() { return m_format_cached; }

bool FormatCache::Entry::IsSummaryCached() { return m_summary_cached; }

bool FormatCache::Entry::IsSyntheticCached() { return m_synthetic_cached; }

bool FormatCache::Entry::IsValidatorCached() { return m_validator_cached; }

lldb::TypeFormatImplSP FormatCache::Entry::GetFormat() { return m_format_sp; }

lldb::TypeSummaryImplSP FormatCache::Entry::GetSummary() {
  return m_summary_sp;
}

lldb::SyntheticChildrenSP FormatCache::Entry::GetSynthetic() {
  return m_synthetic_sp;
}

lldb::TypeValidatorImplSP FormatCache::Entry::GetValidator() {
  return m_validator_sp;
}

void FormatCache::Entry::SetFormat(lldb::TypeFormatImplSP format_sp) {
  m_format_cached = true;
  m_format_sp = format_sp;
}

void FormatCache::Entry::SetSummary(lldb::TypeSummaryImplSP summary_sp) {
  m_summary_cached = true;
  m_summary_sp = summary_sp;
}

void FormatCache::Entry::SetSynthetic(lldb::SyntheticChildrenSP synthetic_sp) {
  m_synthetic_cached = true;
  m_synthetic_sp = synthetic_sp;
}

void FormatCache::Entry::SetValidator(lldb::TypeValidatorImplSP validator_sp) {
  m_validator_cached = true;
  m_validator_sp = validator_sp;
}

FormatCache::FormatCache()
    : m_map(), m_mutex()
#ifdef LLDB_CONFIGURATION_DEBUG
      ,
      m_cache_hits(0), m_cache_misses(0)
#endif
{
}

FormatCache::Entry &FormatCache::GetEntry(const ConstString &type) {
  auto i = m_map.find(type), e = m_map.end();
  if (i != e)
    return i->second;
  m_map[type] = FormatCache::Entry();
  return m_map[type];
}

bool FormatCache::GetFormat(const ConstString &type,
                            lldb::TypeFormatImplSP &format_sp) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  auto entry = GetEntry(type);
  if (entry.IsFormatCached()) {
#ifdef LLDB_CONFIGURATION_DEBUG
    m_cache_hits++;
#endif
    format_sp = entry.GetFormat();
    return true;
  }
#ifdef LLDB_CONFIGURATION_DEBUG
  m_cache_misses++;
#endif
  format_sp.reset();
  return false;
}

bool FormatCache::GetSummary(const ConstString &type,
                             lldb::TypeSummaryImplSP &summary_sp) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  auto entry = GetEntry(type);
  if (entry.IsSummaryCached()) {
#ifdef LLDB_CONFIGURATION_DEBUG
    m_cache_hits++;
#endif
    summary_sp = entry.GetSummary();
    return true;
  }
#ifdef LLDB_CONFIGURATION_DEBUG
  m_cache_misses++;
#endif
  summary_sp.reset();
  return false;
}

bool FormatCache::GetSynthetic(const ConstString &type,
                               lldb::SyntheticChildrenSP &synthetic_sp) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  auto entry = GetEntry(type);
  if (entry.IsSyntheticCached()) {
#ifdef LLDB_CONFIGURATION_DEBUG
    m_cache_hits++;
#endif
    synthetic_sp = entry.GetSynthetic();
    return true;
  }
#ifdef LLDB_CONFIGURATION_DEBUG
  m_cache_misses++;
#endif
  synthetic_sp.reset();
  return false;
}

bool FormatCache::GetValidator(const ConstString &type,
                               lldb::TypeValidatorImplSP &validator_sp) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  auto entry = GetEntry(type);
  if (entry.IsValidatorCached()) {
#ifdef LLDB_CONFIGURATION_DEBUG
    m_cache_hits++;
#endif
    validator_sp = entry.GetValidator();
    return true;
  }
#ifdef LLDB_CONFIGURATION_DEBUG
  m_cache_misses++;
#endif
  validator_sp.reset();
  return false;
}

void FormatCache::SetFormat(const ConstString &type,
                            lldb::TypeFormatImplSP &format_sp) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  GetEntry(type).SetFormat(format_sp);
}

void FormatCache::SetSummary(const ConstString &type,
                             lldb::TypeSummaryImplSP &summary_sp) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  GetEntry(type).SetSummary(summary_sp);
}

void FormatCache::SetSynthetic(const ConstString &type,
                               lldb::SyntheticChildrenSP &synthetic_sp) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  GetEntry(type).SetSynthetic(synthetic_sp);
}

void FormatCache::SetValidator(const ConstString &type,
                               lldb::TypeValidatorImplSP &validator_sp) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  GetEntry(type).SetValidator(validator_sp);
}

void FormatCache::Clear() {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  m_map.clear();
}
