/* Caching of GDB/DWARF index files.

   Copyright (C) 2018 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 "dwarf-index-common.h"
#include "common/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 (struct dwarf2_per_objfile *dwarf2_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 */
