//===-- 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(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(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(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(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(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(ConstString type,
                            lldb::TypeFormatImplSP &format_sp) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  GetEntry(type).SetFormat(format_sp);
}

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

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

void FormatCache::SetValidator(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();
}
