// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef BASE_METRICS_HISTOGRAM_PERSISTENCE_H_
#define BASE_METRICS_HISTOGRAM_PERSISTENCE_H_

#include <map>
#include <memory>

#include "base/atomicops.h"
#include "base/base_export.h"
#include "base/feature_list.h"
#include "base/memory/shared_memory.h"
#include "base/metrics/histogram_base.h"
#include "base/metrics/persistent_memory_allocator.h"
#include "base/process/process_handle.h"
#include "base/strings/string_piece.h"
#include "base/synchronization/lock.h"

namespace base {

class BucketRanges;
class FilePath;
class PersistentSampleMapRecords;
class PersistentSparseHistogramDataManager;

// Feature definition for enabling histogram persistence.
BASE_EXPORT extern const Feature kPersistentHistogramsFeature;


// A data manager for sparse histograms so each instance of such doesn't have
// to separately iterate over the entire memory segment. Though this class
// will generally be accessed through the PersistentHistogramAllocator above,
// it can be used independently on any PersistentMemoryAllocator (making it
// useable for testing). This object supports only one instance of a sparse
// histogram for a given id. Tests that create multiple identical histograms,
// perhaps to simulate multiple processes, should create a separate manager
// for each.
class BASE_EXPORT PersistentSparseHistogramDataManager {
 public:
  // Constructs the data manager. The allocator must live longer than any
  // managers that reference it.
  explicit PersistentSparseHistogramDataManager(
      PersistentMemoryAllocator* allocator);

  ~PersistentSparseHistogramDataManager();

  // Returns the object that manages the persistent-sample-map records for a
  // given |id|. Only one |user| of this data is allowed at a time. This does
  // an automatic Acquire() on the records. The user must call Release() on
  // the returned object when it is finished with it. Ownership of the records
  // object stays with this manager.
  PersistentSampleMapRecords* UseSampleMapRecords(uint64_t id,
                                                  const void* user);

  // Convenience method that gets the object for a given reference so callers
  // don't have to also keep their own pointer to the appropriate allocator.
  template <typename T>
  T* GetAsObject(PersistentMemoryAllocator::Reference ref) {
    return allocator_->GetAsObject<T>(ref);
  }

 private:
  friend class PersistentSampleMapRecords;

  // Gets the object holding records for a given sample-map id when |lock_|
  // has already been acquired.
  PersistentSampleMapRecords* GetSampleMapRecordsWhileLocked(uint64_t id);

  // Loads sample-map records looking for those belonging to the specified
  // |load_id|. Records found for other sample-maps are held for later use
  // without having to iterate again. This should be called only from a
  // PersistentSampleMapRecords object because those objects have a contract
  // that there are no other threads accessing the internal records_ field
  // of the object that is passed in.
  bool LoadRecords(PersistentSampleMapRecords* sample_map_records);

  // Weak-pointer to the allocator used by the sparse histograms.
  PersistentMemoryAllocator* allocator_;

  // Iterator within the allocator for finding sample records.
  PersistentMemoryAllocator::Iterator record_iterator_;

  // Mapping of sample-map IDs to their sample records.
  std::map<uint64_t, std::unique_ptr<PersistentSampleMapRecords>>
      sample_records_;

  // A lock used for synchronizing changes to sample_records_.
  base::Lock lock_;

  DISALLOW_COPY_AND_ASSIGN(PersistentSparseHistogramDataManager);
};


// This class manages sample-records used by a PersistentSampleMap container
// that underlies a persistent SparseHistogram object. It is broken out into a
// top-level class so that it can be forward-declared in other header files
// rather than include this entire file as would be necessary if it were
// declared within the PersistentSparseHistogramDataManager class above.
class BASE_EXPORT PersistentSampleMapRecords {
 public:
  // Constructs an instance of this class. The manager object must live longer
  // than all instances of this class that reference it, which is not usually
  // a problem since these objects are generally managed from within that
  // manager instance.
  PersistentSampleMapRecords(PersistentSparseHistogramDataManager* data_manager,
                             uint64_t sample_map_id);

  ~PersistentSampleMapRecords();

  // Resets the internal state for a new object using this data. The return
  // value is "this" as a convenience.
  PersistentSampleMapRecords* Acquire(const void* user);

  // Indicates that the using object is done with this data.
  void Release(const void* user);

  // Gets the next reference to a persistent sample-map record. The type and
  // layout of the data being referenced is defined entirely within the
  // PersistentSampleMap class.
  PersistentMemoryAllocator::Reference GetNext();

  // Creates a new persistent sample-map record for sample |value| and returns
  // a reference to it.
  PersistentMemoryAllocator::Reference CreateNew(HistogramBase::Sample value);

  // Convenience method that gets the object for a given reference so callers
  // don't have to also keep their own pointer to the appropriate allocator.
  // This is expected to be used with the SampleRecord structure defined inside
  // the persistent_sample_map.cc file but since that isn't exported (for
  // cleanliness of the interface), a template is defined that will be
  // resolved when used inside that file.
  template <typename T>
  T* GetAsObject(PersistentMemoryAllocator::Reference ref) {
    return data_manager_->GetAsObject<T>(ref);
  }

 private:
  friend PersistentSparseHistogramDataManager;

  // Weak-pointer to the parent data-manager object.
  PersistentSparseHistogramDataManager* data_manager_;

  // ID of PersistentSampleMap to which these records apply.
  const uint64_t sample_map_id_;

  // The current user of this set of records. It is used to ensure that no
  // more than one object is using these records at a given time.
  const void* user_ = nullptr;

  // This is the count of how many "records" have already been read by the
  // owning sample-map.
  size_t seen_ = 0;

  // This is the set of records previously found for a sample map. Because
  // there is ever only one object with a given ID (typically a hash of a
  // histogram name) and because the parent SparseHistogram has acquired
  // its own lock before accessing the PersistentSampleMap it controls, this
  // list can be accessed without acquiring any additional lock.
  std::vector<PersistentMemoryAllocator::Reference> records_;

  // This is the set of records found during iteration through memory. It
  // is appended in bulk to "records". Access to this vector can be done
  // only while holding the parent manager's lock.
  std::vector<PersistentMemoryAllocator::Reference> found_;

  DISALLOW_COPY_AND_ASSIGN(PersistentSampleMapRecords);
};


// This class manages histograms created within a PersistentMemoryAllocator.
class BASE_EXPORT PersistentHistogramAllocator {
 public:
  // A reference to a histogram. While this is implemented as PMA::Reference,
  // it is not conceptually the same thing. Outside callers should always use
  // a Reference matching the class it is for and not mix the two.
  using Reference = PersistentMemoryAllocator::Reference;

  // Iterator used for fetching persistent histograms from an allocator.
  // It is lock-free and thread-safe.
  // See PersistentMemoryAllocator::Iterator for more information.
  class BASE_EXPORT Iterator {
   public:
    // Constructs an iterator on a given |allocator|, starting at the beginning.
    // The allocator must live beyond the lifetime of the iterator.
    explicit Iterator(PersistentHistogramAllocator* allocator);

    // Gets the next histogram from persistent memory; returns null if there
    // are no more histograms to be found. This may still be called again
    // later to retrieve any new histograms added in the meantime.
    std::unique_ptr<HistogramBase> GetNext() { return GetNextWithIgnore(0); }

    // Gets the next histogram from persistent memory, ignoring one particular
    // reference in the process. Pass |ignore| of zero (0) to ignore nothing.
    std::unique_ptr<HistogramBase> GetNextWithIgnore(Reference ignore);

   private:
    // Weak-pointer to histogram allocator being iterated over.
    PersistentHistogramAllocator* allocator_;

    // The iterator used for stepping through objects in persistent memory.
    // It is lock-free and thread-safe which is why this class is also such.
    PersistentMemoryAllocator::Iterator memory_iter_;

    DISALLOW_COPY_AND_ASSIGN(Iterator);
  };

  // A PersistentHistogramAllocator is constructed from a PersistentMemory-
  // Allocator object of which it takes ownership.
  explicit PersistentHistogramAllocator(
      std::unique_ptr<PersistentMemoryAllocator> memory);
  virtual ~PersistentHistogramAllocator();

  // Direct access to underlying memory allocator. If the segment is shared
  // across threads or processes, reading data through these values does
  // not guarantee consistency. Use with care. Do not write.
  PersistentMemoryAllocator* memory_allocator() {
    return memory_allocator_.get();
  }

  // Implement the "metadata" API of a PersistentMemoryAllocator, forwarding
  // those requests to the real one.
  uint64_t Id() const { return memory_allocator_->Id(); }
  const char* Name() const { return memory_allocator_->Name(); }
  const void* data() const { return memory_allocator_->data(); }
  size_t length() const { return memory_allocator_->length(); }
  size_t size() const { return memory_allocator_->size(); }
  size_t used() const { return memory_allocator_->used(); }

  // Recreate a Histogram from data held in persistent memory. Though this
  // object will be local to the current process, the sample data will be
  // shared with all other threads referencing it. This method takes a |ref|
  // to where the top-level histogram data may be found in this allocator.
  // This method will return null if any problem is detected with the data.
  std::unique_ptr<HistogramBase> GetHistogram(Reference ref);

  // Allocate a new persistent histogram. The returned histogram will not
  // be able to be located by other allocators until it is "finalized".
  std::unique_ptr<HistogramBase> AllocateHistogram(
      HistogramType histogram_type,
      const std::string& name,
      int minimum,
      int maximum,
      const BucketRanges* bucket_ranges,
      int32_t flags,
      Reference* ref_ptr);

  // Finalize the creation of the histogram, making it available to other
  // processes if |registered| (as in: added to the StatisticsRecorder) is
  // True, forgetting it otherwise.
  void FinalizeHistogram(Reference ref, bool registered);

  // Merges the data in a persistent histogram with one held globally by the
  // StatisticsRecorder, updating the "logged" samples within the passed
  // object so that repeated merges are allowed. Don't call this on a "global"
  // allocator because histograms created there will already be in the SR.
  void MergeHistogramDeltaToStatisticsRecorder(HistogramBase* histogram);

  // As above but merge the "final" delta. No update of "logged" samples is
  // done which means it can operate on read-only objects. It's essential,
  // however, not to call this more than once or those final samples will
  // get recorded again.
  void MergeHistogramFinalDeltaToStatisticsRecorder(
      const HistogramBase* histogram);

  // Returns the object that manages the persistent-sample-map records for a
  // given |id|. Only one |user| of this data is allowed at a time. This does
  // an automatic Acquire() on the records. The user must call Release() on
  // the returned object when it is finished with it. Ownership stays with
  // this allocator.
  PersistentSampleMapRecords* UseSampleMapRecords(uint64_t id,
                                                  const void* user);

  // Create internal histograms for tracking memory use and allocation sizes
  // for allocator of |name| (which can simply be the result of Name()). This
  // is done seperately from construction for situations such as when the
  // histograms will be backed by memory provided by this very allocator.
  //
  // IMPORTANT: Callers must update tools/metrics/histograms/histograms.xml
  // with the following histograms:
  //    UMA.PersistentAllocator.name.Allocs
  //    UMA.PersistentAllocator.name.UsedPct
  void CreateTrackingHistograms(StringPiece name);
  void UpdateTrackingHistograms();

  // Clears the internal |last_created_| reference so testing can validate
  // operation without that optimization.
  void ClearLastCreatedReferenceForTesting();

 protected:
  // The structure used to hold histogram data in persistent memory. It is
  // defined and used entirely within the .cc file.
  struct PersistentHistogramData;

  // Gets the reference of the last histogram created, used to avoid
  // trying to import what was just created.
  PersistentHistogramAllocator::Reference last_created() {
    return subtle::NoBarrier_Load(&last_created_);
  }

  // Gets the next histogram in persistent data based on iterator while
  // ignoring a particular reference if it is found.
  std::unique_ptr<HistogramBase> GetNextHistogramWithIgnore(Iterator* iter,
                                                            Reference ignore);

 private:
  // Create a histogram based on saved (persistent) information about it.
  std::unique_ptr<HistogramBase> CreateHistogram(
      PersistentHistogramData* histogram_data_ptr);

  // Gets or creates an object in the global StatisticsRecorder matching
  // the |histogram| passed. Null is returned if one was not found and
  // one could not be created.
  HistogramBase* GetOrCreateStatisticsRecorderHistogram(
      const HistogramBase* histogram);

  // The memory allocator that provides the actual histogram storage.
  std::unique_ptr<PersistentMemoryAllocator> memory_allocator_;

  // The data-manager used to improve performance of sparse histograms.
  PersistentSparseHistogramDataManager sparse_histogram_data_manager_;

  // A reference to the last-created histogram in the allocator, used to avoid
  // trying to import what was just created.
  // TODO(bcwhite): Change this to std::atomic<PMA::Reference> when available.
  subtle::Atomic32 last_created_ = 0;

  DISALLOW_COPY_AND_ASSIGN(PersistentHistogramAllocator);
};


// A special case of the PersistentHistogramAllocator that operates on a
// global scale, collecting histograms created through standard macros and
// the FactoryGet() method.
class BASE_EXPORT GlobalHistogramAllocator
    : public PersistentHistogramAllocator {
 public:
  ~GlobalHistogramAllocator() override;

  // Create a global allocator using the passed-in memory |base|, |size|, and
  // other parameters. Ownership of the memory segment remains with the caller.
  static void CreateWithPersistentMemory(void* base,
                                         size_t size,
                                         size_t page_size,
                                         uint64_t id,
                                         StringPiece name);

  // Create a global allocator using an internal block of memory of the
  // specified |size| taken from the heap.
  static void CreateWithLocalMemory(size_t size, uint64_t id, StringPiece name);

#if !defined(OS_NACL) && !defined(STARBOARD)
  // Create a global allocator by memory-mapping a |file|. If the file does
  // not exist, it will be created with the specified |size|. If the file does
  // exist, the allocator will use and add to its contents, ignoring the passed
  // size in favor of the existing size. Returns whether the global allocator
  // was set.
  static bool CreateWithFile(const FilePath& file_path,
                             size_t size,
                             uint64_t id,
                             StringPiece name);

  // Creates a new file at |active_path|. If it already exists, it will first be
  // moved to |base_path|. In all cases, any old file at |base_path| will be
  // removed. If |spare_path| is non-empty and exists, that will be renamed and
  // used as the active file. Otherwise, the file will be created using the
  // given size, id, and name. Returns whether the global allocator was set.
  static bool CreateWithActiveFile(const FilePath& base_path,
                                   const FilePath& active_path,
                                   const FilePath& spare_path,
                                   size_t size,
                                   uint64_t id,
                                   StringPiece name);

  // Uses ConstructBaseActivePairFilePaths() to build a pair of file names which
  // are then used for CreateWithActiveFile(). |name| is used for both the
  // internal name for the allocator and also for the name of the file inside
  // |dir|.
  static bool CreateWithActiveFileInDir(const FilePath& dir,
                                        size_t size,
                                        uint64_t id,
                                        StringPiece name);

  // Constructs a filename using a name.
  static FilePath ConstructFilePath(const FilePath& dir, StringPiece name);

  // Like above but with timestamp and pid for use in upload directories.
  static FilePath ConstructFilePathForUploadDir(const FilePath& dir,
                                                StringPiece name,
                                                base::Time stamp,
                                                ProcessId pid);

  // Parses a filename to extract name, timestamp, and pid.
  static bool ParseFilePath(const FilePath& path,
                            std::string* out_name,
                            Time* out_stamp,
                            ProcessId* out_pid);

  // Constructs a set of names in |dir| based on name that can be used for a
  // base + active persistent memory mapped location for CreateWithActiveFile().
  // The spare path is a file that can be pre-created and moved to be active
  // without any startup penalty that comes from constructing the file. |name|
  // will be used as the basename of the file inside |dir|. |out_base_path|,
  // |out_active_path|, or |out_spare_path| may be null if not needed.
  static void ConstructFilePaths(const FilePath& dir,
                                 StringPiece name,
                                 FilePath* out_base_path,
                                 FilePath* out_active_path,
                                 FilePath* out_spare_path);

  // As above but puts the base files in a different "upload" directory. This
  // is useful when moving all completed files into a single directory for easy
  // upload management.
  static void ConstructFilePathsForUploadDir(const FilePath& active_dir,
                                             const FilePath& upload_dir,
                                             const std::string& name,
                                             FilePath* out_upload_path,
                                             FilePath* out_active_path,
                                             FilePath* out_spare_path);

  // Create a "spare" file that can later be made the "active" file. This
  // should be done on a background thread if possible.
  static bool CreateSpareFile(const FilePath& spare_path, size_t size);

  // Same as above but uses standard names. |name| is the name of the allocator
  // and is also used to create the correct filename.
  static bool CreateSpareFileInDir(const FilePath& dir_path,
                                   size_t size,
                                   StringPiece name);
#endif

#if !defined(STARBOARD)
  // Create a global allocator using a block of shared memory accessed
  // through the given |handle| and |size|. The allocator takes ownership
  // of the handle and closes it upon destruction, though the memory will
  // continue to live if other processes have access to it.
  static void CreateWithSharedMemoryHandle(const SharedMemoryHandle& handle,
                                           size_t size);
#endif

  // Sets a GlobalHistogramAllocator for globally storing histograms in
  // a space that can be persisted or shared between processes. There is only
  // ever one allocator for all such histograms created by a single process.
  // This takes ownership of the object and should be called as soon as
  // possible during startup to capture as many histograms as possible and
  // while operating single-threaded so there are no race-conditions.
  static void Set(std::unique_ptr<GlobalHistogramAllocator> allocator);

  // Gets a pointer to the global histogram allocator. Returns null if none
  // exists.
  static GlobalHistogramAllocator* Get();

  // This access to the persistent allocator is only for testing; it extracts
  // the current allocator completely. This allows easy creation of histograms
  // within persistent memory segments which can then be extracted and used in
  // other ways.
  static std::unique_ptr<GlobalHistogramAllocator> ReleaseForTesting();

  // Stores a pathname to which the contents of this allocator should be saved
  // in order to persist the data for a later use.
  void SetPersistentLocation(const FilePath& location);

  // Retrieves a previously set pathname to which the contents of this allocator
  // are to be saved.
  const FilePath& GetPersistentLocation() const;

  // Writes the internal data to a previously set location. This is generally
  // called when a process is exiting from a section of code that may not know
  // the filesystem. The data is written in an atomic manner. The return value
  // indicates success.
  bool WriteToPersistentLocation();

  // If there is a global metrics file being updated on disk, mark it to be
  // deleted when the process exits.
  void DeletePersistentLocation();

 private:
  friend class StatisticsRecorder;

  // Creates a new global histogram allocator.
  explicit GlobalHistogramAllocator(
      std::unique_ptr<PersistentMemoryAllocator> memory);

  // Import new histograms from the global histogram allocator. It's possible
  // for other processes to create histograms in the active memory segment;
  // this adds those to the internal list of known histograms to avoid creating
  // duplicates that would have to be merged during reporting. Every call to
  // this method resumes from the last entry it saw; it costs nothing if
  // nothing new has been added.
  void ImportHistogramsToStatisticsRecorder();

  // Builds a FilePath for a metrics file.
  static FilePath MakeMetricsFilePath(const FilePath& dir, StringPiece name);

  // Import always continues from where it left off, making use of a single
  // iterator to continue the work.
  Iterator import_iterator_;

  // The location to which the data should be persisted.
  FilePath persistent_location_;

  DISALLOW_COPY_AND_ASSIGN(GlobalHistogramAllocator);
};

}  // namespace base

#endif  // BASE_METRICS_HISTOGRAM_PERSISTENCE_H_
