// Copyright (c) 2012 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 NET_BASE_PRIORITY_QUEUE_H_
#define NET_BASE_PRIORITY_QUEUE_H_

#include <stddef.h>
#include <stdint.h>

#include <list>
#include <vector>

#include "base/logging.h"
#include "base/macros.h"
#include "base/threading/thread_checker.h"

#if !defined(NDEBUG)
#include <unordered_set>
#endif

namespace net {

// A simple priority queue. The order of values is by priority and then FIFO.
// Unlike the std::priority_queue, this implementation allows erasing elements
// from the queue, and all operations are O(p) time for p priority levels.
// The queue is agnostic to priority ordering (whether 0 precedes 1).
// If the highest priority is 0, FirstMin() returns the first in order.
//
// In debug-mode, the internal queues store (id, value) pairs where id is used
// to validate Pointers.
//
template <typename T>
class PriorityQueue {
 private:
  // This section is up-front for Pointer only.
#if !defined(NDEBUG)
  typedef std::list<std::pair<unsigned, T> > List;
#else
  typedef std::list<T> List;
#endif

 public:
  typedef uint32_t Priority;

  // A pointer to a value stored in the queue. The pointer becomes invalid
  // when the queue is destroyed or cleared, or the value is erased.
  class Pointer {
   public:
    // Constructs a null pointer.
    Pointer() : priority_(kNullPriority) {
#if !defined(NDEBUG)
      id_ = static_cast<unsigned>(-1);
#endif
      // TODO(syzm)
      // An uninitialized iterator behaves like an uninitialized pointer as per
      // the STL docs. The fix below is ugly and should possibly be replaced
      // with a better approach.
      iterator_ = dummy_empty_list_.end();
    }

    Pointer(const Pointer& p)
        : priority_(p.priority_),
          iterator_(p.iterator_) {
#if !defined(NDEBUG)
      id_ = p.id_;
#endif
    }

    Pointer& operator=(const Pointer& p) {
      // Self-assignment is benign.
      priority_ = p.priority_;
      iterator_ = p.iterator_;
#if !defined(NDEBUG)
      id_ = p.id_;
#endif
      return *this;
    }

    bool is_null() const { return priority_ == kNullPriority; }

    Priority priority() const { return priority_; }

#if !defined(NDEBUG)
    const T& value() const { return iterator_->second; }
#else
    const T& value() const { return *iterator_; }
#endif

    // Comparing to Pointer from a different PriorityQueue is undefined.
    bool Equals(const Pointer& other) const {
      return (priority_ == other.priority_) && (iterator_ == other.iterator_);
    }

    void Reset() {
      *this = Pointer();
    }

   private:
    friend class PriorityQueue;

    // Note that we need iterator and not const_iterator to pass to
    // List::erase.  When C++11 is turned on for Chromium, this could
    // be changed to const_iterator and the const_casts in the rest of
    // the file can be removed.
    typedef typename PriorityQueue::List::iterator ListIterator;

    static const Priority kNullPriority = static_cast<Priority>(-1);

    // It is guaranteed that Pointer will treat |iterator| as a
    // const_iterator.
    Pointer(Priority priority, const ListIterator& iterator)
        : priority_(priority), iterator_(iterator) {
#if !defined(NDEBUG)
      id_ = iterator_->first;
#endif
    }

    Priority priority_;
    ListIterator iterator_;
    // The STL iterators when uninitialized are like uninitialized pointers
    // which cause crashes when assigned to other iterators. We need to
    // initialize a NULL iterator to the end of a valid list.
    List dummy_empty_list_;

#if !defined(NDEBUG)
    // Used by the queue to check if a Pointer is valid.
    unsigned id_;
#endif
  };

  // Creates a new queue for |num_priorities|.
  explicit PriorityQueue(Priority num_priorities)
      : lists_(num_priorities), size_(0) {
#if !defined(NDEBUG)
    next_id_ = 0;
#endif
  }

  ~PriorityQueue() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); }

  // Adds |value| with |priority| to the queue. Returns a pointer to the
  // created element.
  Pointer Insert(const T& value, Priority priority) {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    DCHECK_LT(priority, lists_.size());
    ++size_;
    List& list = lists_[priority];
#if !defined(NDEBUG)
    unsigned id = next_id_;
    valid_ids_.insert(id);
    ++next_id_;
    return Pointer(priority, list.insert(list.end(),
                                         std::make_pair(id, value)));
#else
    return Pointer(priority, list.insert(list.end(), value));
#endif
  }

  // Adds |value| with |priority| to the queue. Returns a pointer to the
  // created element.
  Pointer InsertAtFront(const T& value, Priority priority) {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    DCHECK_LT(priority, lists_.size());
    ++size_;
    List& list = lists_[priority];
#if !defined(NDEBUG)
    unsigned id = next_id_;
    valid_ids_.insert(id);
    ++next_id_;
    return Pointer(priority, list.insert(list.begin(),
                                         std::make_pair(id, value)));
#else
    return Pointer(priority, list.insert(list.begin(), value));
#endif
  }

  // Removes the value pointed by |pointer| from the queue. All pointers to this
  // value including |pointer| become invalid.
  void Erase(const Pointer& pointer) {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    DCHECK_LT(pointer.priority_, lists_.size());
    DCHECK_GT(size_, 0u);

#if !defined(NDEBUG)
    DCHECK_EQ(1u, valid_ids_.erase(pointer.id_));
    DCHECK_EQ(pointer.iterator_->first, pointer.id_);
#endif

    --size_;
    lists_[pointer.priority_].erase(pointer.iterator_);
  }

  // Returns a pointer to the first value of minimum priority or a null-pointer
  // if empty.
  Pointer FirstMin() const {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    for (size_t i = 0; i < lists_.size(); ++i) {
      List* list = const_cast<List*>(&lists_[i]);
      if (!list->empty())
        return Pointer(i, list->begin());
    }
    return Pointer();
  }

  // Returns a pointer to the last value of minimum priority or a null-pointer
  // if empty.
  Pointer LastMin() const {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    for (size_t i = 0; i < lists_.size(); ++i) {
      List* list = const_cast<List*>(&lists_[i]);
      if (!list->empty())
        return Pointer(i, --list->end());
    }
    return Pointer();
  }

  // Returns a pointer to the first value of maximum priority or a null-pointer
  // if empty.
  Pointer FirstMax() const {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    for (size_t i = lists_.size(); i > 0; --i) {
      size_t index = i - 1;
      List* list = const_cast<List*>(&lists_[index]);
      if (!list->empty())
        return Pointer(index, list->begin());
    }
    return Pointer();
  }

  // Returns a pointer to the last value of maximum priority or a null-pointer
  // if empty.
  Pointer LastMax() const {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    for (size_t i = lists_.size(); i > 0; --i) {
      size_t index = i - 1;
      List* list = const_cast<List*>(&lists_[index]);
      if (!list->empty())
        return Pointer(index, --list->end());
    }
    return Pointer();
  }

  // Given an ordering of the values in this queue by decreasing
  // priority and then FIFO, returns a pointer to the value following
  // the value of the given pointer (which must be non-NULL).
  //
  // (One could also implement GetNextTowardsFirstMin() [decreasing
  // priority, then reverse FIFO] as well as
  // GetNextTowards{First,Last}Max() [increasing priority, then
  // {,reverse} FIFO].)
  Pointer GetNextTowardsLastMin(const Pointer& pointer) const {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    DCHECK(!pointer.is_null());
    DCHECK_LT(pointer.priority_, lists_.size());

    typename Pointer::ListIterator it = pointer.iterator_;
    Priority priority = pointer.priority_;
    DCHECK(it != lists_[priority].end());
    ++it;
    while (it == lists_[priority].end()) {
      if (priority == 0u)
        return Pointer();
      --priority;
      it = const_cast<List*>(&lists_[priority])->begin();
    }
    return Pointer(priority, it);
  }

  // Empties the queue. All pointers become invalid.
  void Clear() {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    for (size_t i = 0; i < lists_.size(); ++i) {
      lists_[i].clear();
    }
#if !defined(NDEBUG)
    valid_ids_.clear();
#endif
    size_ = 0u;
  }

  // Returns the number of priorities the queue supports.
  size_t num_priorities() const {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    return lists_.size();
  }

  bool empty() const {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    return size_ == 0;
  }

  // Returns number of queued values.
  size_t size() const {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    return size_;
  }

 private:
  typedef std::vector<List> ListVector;

#if !defined(NDEBUG)
  unsigned next_id_;
  std::unordered_set<unsigned> valid_ids_;
#endif

  ListVector lists_;
  size_t size_;

  THREAD_CHECKER(thread_checker_);

  DISALLOW_COPY_AND_ASSIGN(PriorityQueue);
};

}  // namespace net

#endif  // NET_BASE_PRIORITY_QUEUE_H_
