// 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 KUDU_UTIL_MEM_TRACKER_H
#define KUDU_UTIL_MEM_TRACKER_H

#include <cstdint>
#include <list>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <glog/logging.h>

#include "kudu/util/high_water_mark.h"
#include "kudu/util/mutex.h"

namespace kudu {

class MemTrackerPB;

// A MemTracker tracks memory consumption; it contains an optional limit and is
// arranged into a tree structure such that the consumption tracked by a
// MemTracker is also tracked by its ancestors.
//
// The MemTracker hierarchy is rooted in a single static MemTracker.
// The root MemTracker always exists, and it is the common
// ancestor to all MemTrackers. All operations that discover MemTrackers begin
// at the root and work their way down the tree, while operations that deal
// with adjusting memory consumption begin at a particular MemTracker and work
// their way up the tree to the root. All MemTrackers (except the root) must
// have a parent. As a rule, all children belonging to a parent should have
// unique ids, but this is only enforced during a Find() operation to allow for
// transient duplicates (e.g. the web UI grabbing very short-lived references
// to all MemTrackers while rendering a web page). This also means id
// uniqueness only exists where it's actually needed.
//
// When a MemTracker begins its life, it has a strong reference to its parent
// and the parent has a weak reference to it. Both remain for the lifetime of
// the MemTracker.
//
// Memory consumption is tracked via calls to Consume()/Release(), either to
// the tracker itself or to one of its descendants.
//
// This class is thread-safe.
class MemTracker : public std::enable_shared_from_this<MemTracker> {
 public:
  ~MemTracker();

  // Creates and adds the tracker to the tree so that it can be retrieved with
  // FindTracker/FindOrCreateTracker.
  //
  // byte_limit < 0 means no limit; 'id' is a used as a label to uniquely identify
  // the MemTracker for the below Find...() calls as well as the web UI.
  //
  // Use the two-argument form if there is no parent.
  static std::shared_ptr<MemTracker> CreateTracker(
      int64_t byte_limit,
      const std::string& id,
      std::shared_ptr<MemTracker> parent = std::shared_ptr<MemTracker>());

  // If a tracker with the specified 'id' and 'parent' exists in the tree, sets
  // 'tracker' to reference that instance. Returns false if no such tracker
  // exists.
  //
  // Use the two-argument form if there is no parent.
  //
  // Note: this function will enforce that 'id' is unique amongst the children
  // of 'parent'.
  static bool FindTracker(
      const std::string& id,
      std::shared_ptr<MemTracker>* tracker,
      const std::shared_ptr<MemTracker>& parent = std::shared_ptr<MemTracker>());

  // If a global tracker with the specified 'id' exists in the tree, returns a
  // shared_ptr to that instance. Otherwise, creates a new MemTracker with the
  // specified byte_limit and id, parented to the root MemTracker.
  //
  // Note: this function will enforce that 'id' is unique amongst the children
  // of the root MemTracker.
  static std::shared_ptr<MemTracker> FindOrCreateGlobalTracker(
      int64_t byte_limit, const std::string& id);

  // Returns a list of all the valid trackers.
  static void ListTrackers(std::vector<std::shared_ptr<MemTracker>>* trackers);

  // Marshals the tracker tree into 'pb'.
  static void TrackersToPb(MemTrackerPB* pb);

  // Gets a shared_ptr to the "root" tracker, creating it if necessary.
  static std::shared_ptr<MemTracker> GetRootTracker();

  // Increases consumption of this tracker and its ancestors by 'bytes'.
  void Consume(int64_t bytes);

  // Increases consumption of this tracker and its ancestors by 'bytes' only if
  // they can all consume 'bytes'. If this brings any of them over, none of them
  // are updated.
  // Returns true if the try succeeded.
  bool TryConsume(int64_t bytes);

  // Returns true if this tracker could consume 'bytes' without exceeding its
  // limit, false otherwise.
  bool CanConsumeNoAncestors(int64_t bytes);

  // Decreases consumption of this tracker and its ancestors by 'bytes'.
  //
  // This will also cause the process to periodically trigger tcmalloc "ReleaseMemory"
  // to ensure that memory is released to the OS.
  void Release(int64_t bytes);

  // Returns true if a valid limit of this tracker or one of its ancestors is
  // exceeded.
  bool AnyLimitExceeded();

  // If this tracker has a limit, checks the limit and attempts to free up some memory if
  // the limit is exceeded by calling any added GC functions. Returns true if the limit is
  // exceeded after calling the GC functions. Returns false if there is no limit.
  bool LimitExceeded() {
    return limit_ >= 0 && limit_ < consumption();
  }

  // Returns the maximum consumption that can be made without exceeding the limit on
  // this tracker or any of its parents. Returns int64_t::max() if there are no
  // limits and a negative value if any limit is already exceeded.
  int64_t SpareCapacity() const;


  int64_t limit() const { return limit_; }
  bool has_limit() const { return limit_ >= 0; }
  const std::string& id() const { return id_; }

  // Returns the memory consumed in bytes.
  int64_t consumption() const {
    return consumption_.current_value();
  }

  int64_t peak_consumption() const { return consumption_.max_value(); }

  // Retrieve the parent tracker, or NULL If one is not set.
  std::shared_ptr<MemTracker> parent() const { return parent_; }

  // Returns a textual representation of the tracker that is likely (but not
  // guaranteed) to be globally unique.
  std::string ToString() const;

 private:
  // byte_limit < 0 means no limit
  // 'id' is the label for LogUsage() and web UI.
  MemTracker(int64_t byte_limit, const std::string& id, std::shared_ptr<MemTracker> parent);

  // Further initializes the tracker.
  void Init();

  // Adds tracker to child_trackers_.
  void AddChildTracker(const std::shared_ptr<MemTracker>& tracker);

  // Variant of FindTracker() that must be called with a non-NULL parent.
  static bool FindTrackerInternal(
      const std::string& id,
      std::shared_ptr<MemTracker>* tracker,
      const std::shared_ptr<MemTracker>& parent);

  // Creates the root tracker.
  static void CreateRootTracker();

  int64_t limit_;
  const std::string id_;
  const std::string descr_;
  std::shared_ptr<MemTracker> parent_;

  HighWaterMark consumption_;

  // this tracker plus all of its ancestors
  std::vector<MemTracker*> all_trackers_;
  // all_trackers_ with valid limits
  std::vector<MemTracker*> limit_trackers_;

  // All the child trackers of this tracker. Used for error reporting and
  // listing only (i.e. updating the consumption of a parent tracker does not
  // update that of its children).
  mutable Mutex child_trackers_lock_;
  std::list<std::weak_ptr<MemTracker>> child_trackers_;

  // Iterator into parent_->child_trackers_ for this object. Stored to have O(1)
  // remove.
  std::list<std::weak_ptr<MemTracker>>::iterator child_tracker_it_;
};

// An std::allocator that manipulates a MemTracker during allocation
// and deallocation.
template<typename T, typename Alloc = std::allocator<T> >
class MemTrackerAllocator : public Alloc {
 public:
  typedef typename Alloc::pointer pointer;
  typedef typename Alloc::const_pointer const_pointer;
  typedef typename Alloc::size_type size_type;

  explicit MemTrackerAllocator(std::shared_ptr<MemTracker> mem_tracker)
      : mem_tracker_(std::move(mem_tracker)) {}

  // This constructor is used for rebinding.
  template <typename U>
  MemTrackerAllocator(const MemTrackerAllocator<U>& allocator)
      : Alloc(allocator),
        mem_tracker_(allocator.mem_tracker()) {
  }

  ~MemTrackerAllocator() {
  }

  pointer allocate(size_type n, const_pointer hint = 0) {
    // Ideally we'd use TryConsume() here to enforce the tracker's limit.
    // However, that means throwing bad_alloc if the limit is exceeded, and
    // it's not clear that the rest of Kudu can handle that.
    mem_tracker_->Consume(n * sizeof(T));
    return Alloc::allocate(n, hint);
  }

  void deallocate(pointer p, size_type n) {
    Alloc::deallocate(p, n);
    mem_tracker_->Release(n * sizeof(T));
  }

  // This allows an allocator<T> to be used for a different type.
  template <class U>
  struct rebind {
    typedef MemTrackerAllocator<U, typename Alloc::template rebind<U>::other> other;
  };

  const std::shared_ptr<MemTracker>& mem_tracker() const { return mem_tracker_; }

 private:
  std::shared_ptr<MemTracker> mem_tracker_;
};

// Convenience class that adds memory consumption to a tracker when declared,
// releasing it when the end of scope is reached.
class ScopedTrackedConsumption {
 public:
  ScopedTrackedConsumption(std::shared_ptr<MemTracker> tracker,
                           int64_t to_consume)
      : tracker_(std::move(tracker)), consumption_(to_consume) {
    DCHECK(tracker_);
    tracker_->Consume(consumption_);
  }

  void Reset(int64_t new_consumption) {
    // Consume(-x) is the same as Release(x).
    tracker_->Consume(new_consumption - consumption_);
    consumption_ = new_consumption;
  }

  ~ScopedTrackedConsumption() {
    tracker_->Release(consumption_);
  }

  int64_t consumption() const { return consumption_; }

 private:
  std::shared_ptr<MemTracker> tracker_;
  int64_t consumption_;
};

} // namespace kudu

#endif // KUDU_UTIL_MEM_TRACKER_H
