/* Caching of GDB/DWARF index files.

   Copyright (C) 2018-2021 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#ifndef DWARF_INDEX_CACHE_H
#define DWARF_INDEX_CACHE_H

#include "dwarf2/index-common.h"
#include "gdbsupport/array-view.h"
#include "symfile.h"

/* Base of the classes used to hold the resources of the indices loaded from
   the cache (e.g. mmapped files).  */

struct index_cache_resource
{
  virtual ~index_cache_resource () = 0;
};

/* Class to manage the access to the DWARF index cache.  */

class index_cache
{
public:
  /* Change the directory used to save/load index files.  */
  void set_directory (std::string dir);

  /* Return true if the usage of the cache is enabled.  */
  bool enabled () const
  {
    return m_enabled;
  }

  /* Enable the cache.  */
  void enable ();

  /* Disable the cache.  */
  void disable ();

  /* Store an index for the specified object file in the cache.  */
  void store (dwarf2_per_objfile *per_objfile);

  /* Look for an index file matching BUILD_ID.  If found, return the contents
     as an array_view and store the underlying resources (allocated memory,
     mapped file, etc) in RESOURCE.  The returned array_view is valid as long
     as RESOURCE is not destroyed.

     If no matching index file is found, return an empty array view.  */
  gdb::array_view<const gdb_byte>
  lookup_gdb_index (const bfd_build_id *build_id,
		    std::unique_ptr<index_cache_resource> *resource);

  /* Return the number of cache hits.  */
  unsigned int n_hits () const
  { return m_n_hits; }

  /* Record a cache hit.  */
  void hit ()
  {
    if (enabled ())
      m_n_hits++;
  }

  /* Return the number of cache misses.  */
  unsigned int n_misses () const
  { return m_n_misses; }

  /* Record a cache miss.  */
  void miss ()
  {
    if (enabled ())
      m_n_misses++;
  }

private:

  /* Compute the absolute filename where the index of the objfile with build
     id BUILD_ID will be stored.  SUFFIX is appended at the end of the
     filename.  */
  std::string make_index_filename (const bfd_build_id *build_id,
				   const char *suffix) const;

  /* The base directory where we are storing and looking up index files.  */
  std::string m_dir;

  /* Whether the cache is enabled.  */
  bool m_enabled = false;

  /* Number of cache hits and misses during this GDB session.  */
  unsigned int m_n_hits = 0;
  unsigned int m_n_misses = 0;
};

/* The global instance of the index cache.  */
extern index_cache global_index_cache;

#endif /* DWARF_INDEX_CACHE_H */
