// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


#ifndef IMPALA_UTIL_RUNTIME_PROFILE_H
#define IMPALA_UTIL_RUNTIME_PROFILE_H

#include <boost/function.hpp>
#include <boost/thread/lock_guard.hpp>
#include <iostream>
#include <rapidjson/document.h>
#include "common/atomic.h"
#include "common/status.h"
#include "util/spinlock.h"

#include "gen-cpp/RuntimeProfile_types.h"

namespace impala {

class ObjectPool;

/// Runtime profile is a group of profiling counters.  It supports adding named counters
/// and being able to serialize and deserialize them.
/// The profiles support a tree structure to form a hierarchy of counters.
/// Runtime profiles supports measuring wall clock rate based counters.  There is a
/// single thread per process that will convert an amount (i.e. bytes) counter to a
/// corresponding rate based counter.  This thread wakes up at fixed intervals and updates
/// all of the rate counters.
///
/// Runtime profile counters can be of several types. See their definition in
/// runtime-profile-counters.h for more details.
///
/// - Counter: Tracks a single value or bitmap. Also serves as the base class for several
///   |   other counters.
///   |
///   - AveragedCounter: Maintains a set of child counters. Its current value is the
///   |     average of the current values of its children.
///   |
///   - ConcurrentTimerCounter: Wraps a ConcurrentStopWatch to track concurrent running
///   |     time for multiple threads.
///   |
///   - DerivedCounter: Computes its current value by calling a function passed during
///   |     construction.
///   |
///   - HighWaterMarkCounter: Keeps track of the highest value seen so far.
///   |
///   - SummaryStatsCounter: Keeps track of minimum, maximum, and average value of all
///         values seen so far.
///
/// - EventSequence: Captures a sequence of events, each added by calling MarkEvent().
///       Events have a text label and a time, relative to when the sequence was started.
///
/// - ThreadCounters: Tracks thread runtime information, such as total time, user time,
///       sys time.
///
/// - TimeSeriesCounter (abstract): Keeps track of a value over time. Has two
///   |   implementations.
///   |
///   - SamplingTimeSeriesCounter: Maintains a fixed array of 64 values and resamples if
///   |     more value than that are added.
///   |
///   - ChunkedTimeSeriesCounter: Maintains an unbounded vector of values. Supports
///         clearing its values after they have been retrieved, and will track the number
///         of previously retrieved values.
///
/// All methods are thread-safe unless otherwise mentioned.
class RuntimeProfile { // NOLINT: This struct is not packed, but there are not so many
                       // of them that it makes a performance difference
 public:
  class Counter {
   public:
    Counter(TUnit::type unit, int64_t value = 0) :
      value_(value),
      unit_(unit) {
    }
    virtual ~Counter(){}

    virtual void Add(int64_t delta) {
      value_.Add(delta);
    }

    /// Use this to update if the counter is a bitmap
    void BitOr(int64_t delta) {
      int64_t old;
      do {
        old = value_.Load();
        if (LIKELY((old | delta) == old)) return; // Bits already set, avoid atomic.
      } while (UNLIKELY(!value_.CompareAndSwap(old, old | delta)));
    }

    virtual void Set(int64_t value) { value_.Store(value); }

    virtual void Set(int value) { value_.Store(value); }

    virtual void Set(double value) {
      DCHECK_EQ(sizeof(value), sizeof(int64_t));
      value_.Store(*reinterpret_cast<int64_t*>(&value));
    }

    virtual int64_t value() const { return value_.Load(); }

    virtual double double_value() const {
      int64_t v = value_.Load();
      return *reinterpret_cast<const double*>(&v);
    }

    /// Builds a new Value into 'val', using (if required) the allocator from
    /// 'document'. Should set the following fields where appropriate:
    /// counter_name, value, kind, unit
    virtual void ToJson(rapidjson::Document& document, rapidjson::Value* val) const;

    ///  Return the name of the counter type
    virtual string CounterType() const {
      return "Counter";
    }

    TUnit::type unit() const { return unit_; }

   protected:
    friend class RuntimeProfile;

    AtomicInt64 value_;
    TUnit::type unit_;
  };

  class AveragedCounter;
  class ConcurrentTimerCounter;
  class DerivedCounter;
  class HighWaterMarkCounter;
  class SummaryStatsCounter;
  class EventSequence;
  class ThreadCounters;
  class TimeSeriesCounter;
  class SamplingTimeSeriesCounter;
  class ChunkedTimeSeriesCounter;

  typedef boost::function<int64_t ()> SampleFunction;

  /// Create a runtime profile object with 'name'. The profile, counters and any other
  /// structures owned by the profile are allocated from 'pool'.
  /// If 'is_averaged_profile' is true, the counters in this profile will be derived
  /// averages (of unit AveragedCounter) from other profiles, so the counter map will
  /// be left empty. Otherwise, the counter map is initialized with a single entry for
  /// TotalTime.
  static RuntimeProfile* Create(ObjectPool* pool, const std::string& name,
      bool is_averaged_profile = false);

  ~RuntimeProfile();

  /// Deserialize from thrift.  Runtime profiles are allocated from the pool.
  static RuntimeProfile* CreateFromThrift(ObjectPool* pool,
      const TRuntimeProfileTree& profiles);

  /// Adds a child profile.
  /// Checks if 'child' is already added by searching for its name in the
  /// child map, and only adds it if the name doesn't exist.
  /// 'indent' indicates whether the child will be printed w/ extra indentation
  /// relative to the parent.
  /// If location is non-null, child will be inserted after location.  Location must
  /// already be added to the profile.
  void AddChild(RuntimeProfile* child,
      bool indent = true, RuntimeProfile* location = NULL);

  /// Adds a child profile, similarly to AddChild(). The child profile is put before any
  /// existing profiles.
  void PrependChild(RuntimeProfile* child, bool indent = true);

  /// Creates a new child profile with the given 'name'. A child profile with that name
  /// must not already exist. If 'prepend' is true, prepended before other child profiles,
  /// otherwise appended after other child profiles.
  RuntimeProfile* CreateChild(
      const std::string& name, bool indent = true, bool prepend = false);

  /// Sorts all children according to descending total time. Does not
  /// invalidate pointers to profiles.
  void SortChildrenByTotalTime();

  /// Updates the AveragedCounter counters in this profile with the counters from the
  /// 'src' profile. If a counter is present in 'src' but missing in this profile, a new
  /// AveragedCounter is created with the same name. This method should not be invoked
  /// if is_average_profile_ is false. Obtains locks on the counter maps and child counter
  /// maps in both this and 'src' profiles.
  void UpdateAverage(RuntimeProfile* src);

  /// Updates this profile w/ the thrift profile.
  /// Counters and child profiles in thrift_profile that already exist in this profile
  /// are updated. Counters that do not already exist are created.
  /// Info strings matched up by key and are updated or added, depending on whether
  /// the key has already been registered.
  /// TODO: Event sequences are ignored
  void Update(const TRuntimeProfileTree& thrift_profile);

  /// Add a counter with 'name'/'unit'.  Returns a counter object that the caller can
  /// update.  The counter is owned by the RuntimeProfile object.
  /// If parent_counter_name is a non-empty string, the counter is added as a child of
  /// parent_counter_name.
  /// If the counter already exists, the existing counter object is returned.
  Counter* AddCounter(const std::string& name, TUnit::type unit,
      const std::string& parent_counter_name = "");

  /// Adds a counter that tracks the min, max and average values to the runtime profile.
  /// Otherwise, same behavior as AddCounter().
  SummaryStatsCounter* AddSummaryStatsCounter(const std::string& name, TUnit::type unit,
      const std::string& parent_counter_name = "");

  /// Adds a high water mark counter to the runtime profile. Otherwise, same behavior
  /// as AddCounter().
  HighWaterMarkCounter* AddHighWaterMarkCounter(const std::string& name,
      TUnit::type unit, const std::string& parent_counter_name = "");

  ConcurrentTimerCounter* AddConcurrentTimerCounter(const std::string& name,
      TUnit::type unit, const std::string& parent_counter_name = "");

  /// Add a derived counter with 'name'/'unit'. The counter is owned by the
  /// RuntimeProfile object.
  /// If parent_counter_name is a non-empty string, the counter is added as a child of
  /// parent_counter_name.
  /// Returns NULL if the counter already exists.
  DerivedCounter* AddDerivedCounter(const std::string& name, TUnit::type unit,
      const SampleFunction& counter_fn,
      const std::string& parent_counter_name = "");

  /// Add a set of thread counters prefixed with 'prefix'. Returns a ThreadCounters object
  /// that the caller can update.  The counter is owned by the RuntimeProfile object.
  ThreadCounters* AddThreadCounters(const std::string& prefix);

  // Add a derived counter to capture the local time. This function can be called at most
  // once.
  void AddLocalTimeCounter(const SampleFunction& counter_fn);

  /// Gets the counter object with 'name'.  Returns NULL if there is no counter with
  /// that name.
  Counter* GetCounter(const std::string& name);

  /// Gets the summary stats counter with 'name'. Returns NULL if there is no summary
  /// stats counter with that name.
  SummaryStatsCounter* GetSummaryStatsCounter(const std::string& name);

  /// Adds all counters with 'name' that are registered either in this or
  /// in any of the child profiles to 'counters'.
  void GetCounters(const std::string& name, std::vector<Counter*>* counters);

  /// Adds a string to the runtime profile.  If a value already exists for 'key',
  /// the value will be updated.
  void AddInfoString(const std::string& key, const std::string& value);

  /// Same as AddInfoString(), except that this method applies the redaction
  /// rules on 'value' before adding it to the runtime profile.
  void AddInfoStringRedacted(const std::string& key, const std::string& value);

  /// Adds a string to the runtime profile.  If a value already exists for 'key',
  /// 'value' will be appended to the previous value, with ", " separating them.
  void AppendInfoString(const std::string& key, const std::string& value);

  /// Helper to append to the "ExecOption" info string.
  void AppendExecOption(const std::string& option) {
    AppendInfoString("ExecOption", option);
  }

  /// Helper to append "Codegen Enabled" or "Codegen Disabled" exec options. If
  /// specified, 'extra_info' is appended to the exec option, and 'extra_label'
  /// is prepended to the exec option.
  void AddCodegenMsg(bool codegen_enabled, const std::string& extra_info = "",
      const std::string& extra_label = "");

  /// Helper wrapper for AddCodegenMsg() that takes a status instead of a string
  /// describing why codegen was disabled. 'codegen_status' can be OK whether or
  /// not 'codegen_enabled' is true (e.g. if codegen is disabled by a query option,
  /// then no error occurred).
  void AddCodegenMsg(bool codegen_enabled, const Status& codegen_status,
      const std::string& extra_label = "") {
    const string& err_msg = codegen_status.ok() ? "" : codegen_status.msg().msg();
    AddCodegenMsg(codegen_enabled, err_msg, extra_label);
  }

  /// Creates and returns a new EventSequence (owned by the runtime
  /// profile) - unless a timer with the same 'key' already exists, in
  /// which case it is returned.
  /// TODO: EventSequences are not merged by Merge() or Update()
  EventSequence* AddEventSequence(const std::string& key);
  EventSequence* AddEventSequence(const std::string& key, const TEventSequence& from);

  /// Returns event sequence with the provided name if it exists, otherwise NULL.
  EventSequence* GetEventSequence(const std::string& name) const;

  /// Updates 'value' of info string with 'key'. No-op if the key doesn't exist.
  void UpdateInfoString(const std::string& key, std::string value);

  /// Returns a pointer to the info string value for 'key'.  Returns NULL if
  /// the key does not exist.
  const std::string* GetInfoString(const std::string& key) const;

  /// Stops updating all counters in this profile that are periodically updated by a
  /// background thread (i.e. sampling, rate, bucketing and time series counters).
  /// Must be called before the profile is destroyed if any such counters are active.
  /// Does not stop counters on descendant profiles.
  void StopPeriodicCounters();

  /// Returns the counter for the total elapsed time.
  Counter* total_time_counter() { return counter_map_[TOTAL_TIME_COUNTER_NAME]; }
  Counter* inactive_timer() { return counter_map_[INACTIVE_TIME_COUNTER_NAME]; }
  int64_t local_time() { return local_time_ns_; }
  int64_t total_time() { return total_time_ns_; }

  /// Prints the contents of the profile in a name: value format.
  /// Does not hold locks when it makes any function calls.
  void PrettyPrint(std::ostream* s, const std::string& prefix="") const;

  /// Serializes profile to thrift.
  /// Does not hold locks when it makes any function calls.
  void ToThrift(TRuntimeProfileTree* tree) const;
  void ToThrift(std::vector<TRuntimeProfileNode>* nodes) const;

  /// Store profile into JSON format into a document
  void ToJsonHelper(rapidjson::Value* parent, rapidjson::Document* d) const;
  void ToJson(rapidjson::Document* d) const;

  /// Serializes the runtime profile to a string.  This first serializes the
  /// object using thrift compact binary format, then gzip compresses it and
  /// finally encodes it as base64.  This is not a lightweight operation and
  /// should not be in the hot path.
  Status SerializeToArchiveString(std::string* out) const WARN_UNUSED_RESULT;
  Status SerializeToArchiveString(std::stringstream* out) const WARN_UNUSED_RESULT;

  /// Deserializes a string into a TRuntimeProfileTree. 'archive_str' is expected to have
  /// been serialized by SerializeToArchiveString().
  static Status DeserializeFromArchiveString(
      const std::string& archive_str, TRuntimeProfileTree* out);

  /// Divides all counters by n
  void Divide(int n);

  void GetChildren(std::vector<RuntimeProfile*>* children);

  /// Gets all profiles in tree, including this one.
  void GetAllChildren(std::vector<RuntimeProfile*>* children);

  /// Returns the number of counters in this profile
  int num_counters() const { return counter_map_.size(); }

  /// Returns name of this profile
  const std::string& name() const { return name_; }

  /// *only call this on top-level profiles*
  /// (because it doesn't re-file child profiles)
  void set_name(const std::string& name) { name_ = name; }

  const TRuntimeProfileNodeMetadata& metadata() const { return metadata_; }

  /// Called if this corresponds to a plan node. Sets metadata so that later code that
  /// analyzes the profile can identify this as the plan node's profile.
  void SetPlanNodeId(int node_id);

  /// Called if this corresponds to a data sink. Sets metadata so that later code that
  /// analyzes the profile can identify this as the data sink's profile.
  void SetDataSinkId(int sink_id);

  /// Derived counter function: return measured throughput as input_value/second.
  static int64_t UnitsPerSecond(const Counter* total_counter, const Counter* timer);

  /// Derived counter function: return aggregated value
  static int64_t CounterSum(const std::vector<Counter*>* counters);

  /// Add a rate counter to the current profile based on src_counter with name.
  /// The rate counter is updated periodically based on the src counter.
  /// The rate counter has units in src_counter unit per second.
  /// StopPeriodicCounters() must be called to stop the periodic updating before this
  /// profile is destroyed. The periodic updating can be stopped earlier by calling
  /// PeriodicCounterUpdater::StopRateCounter() if 'src_counter' stops changing.
  Counter* AddRateCounter(const std::string& name, Counter* src_counter);

  /// Same as 'AddRateCounter' above except values are taken by calling fn.
  /// The resulting counter will be of 'unit'.
  Counter* AddRateCounter(const std::string& name, SampleFunction fn,
      TUnit::type unit);

  /// Add a sampling counter to the current profile based on src_counter with name.
  /// The sampling counter is updated periodically based on the src counter by averaging
  /// the samples taken from the src counter.
  /// The sampling counter has the same unit as src_counter unit.
  /// StopPeriodicCounters() must be called to stop the periodic updating before this
  /// profile is destroyed. The periodic updating can be stopped earlier by calling
  /// PeriodicCounterUpdater::StopSamplingCounter() if 'src_counter' stops changing.
  Counter* AddSamplingCounter(const std::string& name, Counter* src_counter);

  /// Same as 'AddSamplingCounter' above except the samples are taken by calling fn.
  Counter* AddSamplingCounter(const std::string& name, SampleFunction fn);

  /// Create a set of counters, one per bucket, to store the sampled value of src_counter.
  /// The 'src_counter' is sampled periodically to obtain the index of the bucket to
  /// increment. E.g. if the value of 'src_counter' is 3, the bucket at index 3 is
  /// updated. If the index exceeds the index of the last bucket, the last bucket is
  /// updated.
  ///
  /// The created counters do not appear in the profile when serialized or
  /// pretty-printed. The caller must do its own processing of the counter value
  /// (e.g. converting it to an info string).
  /// TODO: make this interface more consistent and sane.
  ///
  /// StopPeriodicCounters() must be called to stop the periodic updating before this
  /// profile is destroyed. The periodic updating can be stopped earlier by calling
  /// PeriodicCounterUpdater::StopBucketingCounters() if 'buckets' stops changing.
  std::vector<Counter*>* AddBucketingCounters(Counter* src_counter, int num_buckets);

  /// Creates a sampling time series counter. This begins sampling immediately. This
  /// counter contains a number of samples that are collected periodically by calling
  /// sample_fn(). StopPeriodicCounters() must be called to stop the periodic updating
  /// before this profile is destroyed. The periodic updating can be stopped earlier by
  /// calling PeriodicCounterUpdater::StopTimeSeriesCounter() if the input stops changing.
  /// Note: these counters don't get merged (to make average profiles)
  TimeSeriesCounter* AddSamplingTimeSeriesCounter(const std::string& name,
      TUnit::type unit, SampleFunction sample_fn);

  /// Same as above except the samples are collected from 'src_counter'.
  TimeSeriesCounter* AddSamplingTimeSeriesCounter(const std::string& name, Counter*
      src_counter);

  /// Adds a chunked time series counter to the profile. This begins sampling immediately.
  /// This counter will collect new samples periodically by calling 'sample_fn()'. Samples
  /// are not re-sampled into larger intervals, instead owners of this profile can call
  /// ClearChunkedTimeSeriesCounters() to reset the sample buffers of all chunked time
  /// series counters, e.g. after their current values have been transmitted to a remote
  /// node for profile aggregation.
  TimeSeriesCounter* AddChunkedTimeSeriesCounter(
      const std::string& name, TUnit::type unit, SampleFunction sample_fn);

  /// Clear all chunked time series counters in this profile and all children.
  void ClearChunkedTimeSeriesCounters();

  /// Recursively compute the fraction of the 'total_time' spent in this profile and
  /// its children.
  /// This function updates local_time_percent_ for each profile.
  void ComputeTimeInProfile();

  /// Set ExecSummary
  void SetTExecSummary(const TExecSummary& summary);

  /// Get a copy of exec_summary tp t_exec_summary
  void GetExecSummary(TExecSummary* t_exec_summary) const;

 private:
  /// Pool for allocated counters. Usually owned by the creator of this
  /// object, but occasionally allocated in the constructor.
  ObjectPool* pool_;

  /// Name for this runtime profile.
  std::string name_;

  /// Detailed metadata that identifies the plan node, sink, etc.
  TRuntimeProfileNodeMetadata metadata_;

  /// True if this profile is an average derived from other profiles.
  /// All counters in this profile must be of unit AveragedCounter.
  bool is_averaged_profile_;

  /// Map from counter names to counters.  The profile owns the memory for the
  /// counters.
  typedef std::map<std::string, Counter*> CounterMap;
  CounterMap counter_map_;

  /// Map from parent counter name to a set of child counter name.
  /// All top level counters are the child of "" (root).
  typedef std::map<std::string, std::set<std::string>> ChildCounterMap;
  ChildCounterMap child_counter_map_;

  /// A set of bucket counters registered in this runtime profile.
  std::set<std::vector<Counter*>*> bucketing_counters_;

  /// Rate counters, which also appear in 'counter_map_'. Tracked separately to enable
  /// stopping the counters.
  std::vector<Counter*> rate_counters_;

  /// Sampling counters, which also appear in 'counter_map_'. Tracked separately to enable
  /// stopping the counters.
  std::vector<Counter*> sampling_counters_;

  /// Time series counters. These do not appear in 'counter_map_'. Tracked separately
  /// because they are displayed separately in the profile and need to be stopped.
  typedef std::map<std::string, TimeSeriesCounter*> TimeSeriesCounterMap;
  TimeSeriesCounterMap time_series_counter_map_;

  /// True if this profile has active periodic counters, including bucketing, rate,
  /// sampling and time series counters.
  bool has_active_periodic_counters_ = false;

  /// Protects counter_map_, child_counter_map_, bucketing_counters_, rate_counters_,
  /// sampling_counters_, time_series_counter_map_, and has_active_periodic_counters_.
  mutable SpinLock counter_map_lock_;

  /// Child profiles.  Does not own memory.
  /// We record children in both a map (to facilitate updates) and a vector
  /// (to print things in the order they were registered)
  typedef std::map<std::string, RuntimeProfile*> ChildMap;
  ChildMap child_map_;

  /// Vector of (profile, indentation flag).
  typedef std::vector<std::pair<RuntimeProfile*, bool>> ChildVector;
  ChildVector children_;

  /// Protects child_map_ and children_.
  mutable SpinLock children_lock_;

  typedef std::map<std::string, std::string> InfoStrings;
  InfoStrings info_strings_;

  /// Keeps track of the order in which InfoStrings are displayed when printed.
  typedef std::vector<std::string> InfoStringsDisplayOrder;
  InfoStringsDisplayOrder info_strings_display_order_;

  /// Protects info_strings_ and info_strings_display_order_.
  mutable SpinLock info_strings_lock_;

  typedef std::map<std::string, EventSequence*> EventSequenceMap;
  EventSequenceMap event_sequence_map_;

  /// Protects event_sequence_map_.
  mutable SpinLock event_sequence_lock_;

  typedef std::map<std::string, SummaryStatsCounter*> SummaryStatsCounterMap;
  SummaryStatsCounterMap summary_stats_map_;

  /// Protects summary_stats_map_.
  mutable SpinLock summary_stats_map_lock_;

  Counter counter_total_time_;

  /// Total time spent waiting (on non-children) that should not be counted when
  /// computing local_time_percent_. This is updated for example in the exchange
  /// node when waiting on the sender from another fragment.
  Counter inactive_timer_;

  /// Time spent in just in this profile (i.e. not the children) as a fraction
  /// of the total time in the entire profile tree.
  double local_time_percent_;

  /// Time spent in this node (not including the children). Computed in
  /// ComputeTimeInProfile()
  int64_t local_time_ns_;

  /// Total time spent in this node. Computed in ComputeTimeInProfile() and is
  /// the maximum of the total time spent in children and the value of
  /// counter_total_time_.
  int64_t total_time_ns_;

  /// The Exec Summary
  TExecSummary t_exec_summary_;

  /// Protects exec_summary.
  mutable SpinLock t_exec_summary_lock_;

  /// Constructor used by Create().
  RuntimeProfile(ObjectPool* pool, const std::string& name, bool is_averaged_profile);

  /// Update a subtree of profiles from nodes, rooted at *idx.
  /// On return, *idx points to the node immediately following this subtree.
  void Update(const std::vector<TRuntimeProfileNode>& nodes, int* idx);

  /// Helper function to compute compute the fraction of the total time spent in
  /// this profile and its children.
  /// Called recusively.
  void ComputeTimeInProfile(int64_t total_time);

  /// Implementation of AddInfoString() and AppendInfoString(). If 'append' is false,
  /// implements AddInfoString(), otherwise implements AppendInfoString().
  /// Redaction rules are applied on the info string if 'redact' is true.
  /// Trailing whitspace is removed.
  void AddInfoStringInternal(
      const std::string& key, std::string value, bool append, bool redact = false);

  /// Send exec_summary to thrift
  void ExecSummaryToThrift(TRuntimeProfileTree* tree) const;

  /// Name of the counter maintaining the total time.
  static const std::string TOTAL_TIME_COUNTER_NAME;
  static const std::string LOCAL_TIME_COUNTER_NAME;
  static const std::string INACTIVE_TIME_COUNTER_NAME;

  /// Create a subtree of runtime profiles from nodes, starting at *node_idx.
  /// On return, *node_idx is the index one past the end of this subtree
  static RuntimeProfile* CreateFromThrift(
      ObjectPool* pool, const std::vector<TRuntimeProfileNode>& nodes, int* node_idx);

  /// Internal implementations of the Add*Counter() functions for use when the caller
  /// holds counter_map_lock_. Also returns 'created', which is true if a new counter was
  /// created and false if a counter with the given name already existed.
  Counter* AddCounterLocked(const std::string& name, TUnit::type unit,
      const std::string& parent_counter_name, bool* created);
  HighWaterMarkCounter* AddHighWaterMarkCounterLocked(const std::string& name,
      TUnit::type unit, const std::string& parent_counter_name, bool* created);
  ConcurrentTimerCounter* AddConcurrentTimerCounterLocked(const std::string& name,
      TUnit::type unit, const std::string& parent_counter_name, bool* created);

  ///  Inserts 'child' before the iterator 'insert_pos' in 'children_'.
  /// 'children_lock_' must be held by the caller.
  void AddChildLocked(
      RuntimeProfile* child, bool indent, ChildVector::iterator insert_pos);

  /// Print the child counters of the given counter name
  static void PrintChildCounters(const std::string& prefix,
      const std::string& counter_name, const CounterMap& counter_map,
      const ChildCounterMap& child_counter_map, std::ostream* s);

  /// Add all the counters of this instance into the given parent node in JSON format
  /// Args:
  ///   parent: the root node to add all the counters
  ///   d: document of this json, could be used to get Allocator
  ///   counter_name: this will be used to find its child counters in child_counter_map
  ///   counter_map: A map of counters name to counter
  ///   child_counter_map: A map of counter to its child counters
  void ToJsonCounters(rapidjson::Value* parent, rapidjson::Document* d,
      const string& counter_name, const CounterMap& counter_map,
      const ChildCounterMap& child_counter_map) const;
};

}

#endif
