// Copyright 2011 Google Inc.
//
// Licensed 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.
//
// Author: jmaessen@google.com (Jan Maessen)

#ifndef PAGESPEED_KERNEL_BASE_POOL_H_
#define PAGESPEED_KERNEL_BASE_POOL_H_
#include <cstddef>
#include <list>
#include "base/logging.h"  // for DCHECK
#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/pool_element.h"
#include "pagespeed/kernel/base/stl_util.h"

namespace net_instaweb {

// A pool holds references to objects of type T that provide a pool_position
// method (which they can do by extending PoolElement in pool_element.h, or by
// providing a getter method of type PoolElement::Position* pool_position() (an
// abstract settable pointer for a PoolElement::Position).  Pool objects are
// maintained in insertion order.
//
// We can insert and remove references from a pool, ask for an arbitrary
// reference contained in a pool, and clear or delete all pool elements.  By
// default on destruction we delete pool elements using DeleteAll(); if a pool
// does not acquire object ownership, we should instead .Clear() it before
// destruction.
template<class T>
class Pool {
 public:
  // We can iterate over a pool using this iterator type.
  typedef typename PoolElement<T>::Position iterator;
  typedef typename std::list<T*>::const_iterator const_iterator;

  Pool() { }

  ~Pool() {
    DeleteAll();
  }

  // Is pool empty?
  bool empty() const {
    return contents_.empty();
  }

  // Size of pool
  size_t size() const {
    return contents_.size();
  }

  // Iterator pointing to beginning of pool
  iterator begin() {
    return contents_.begin();
  }

  // const Iterator pointing to beginning of pool
  const_iterator begin() const {
    return contents_.begin();
  }

  // Iterator pointing just past end of pool
  iterator end() {
    return contents_.end();
  }

  // Iterator pointing just past end of pool
  const_iterator end() const {
    return contents_.end();
  }

  // Add object to pool.  The object must not currently reside in a pool.
  void Add(T* object) {
    iterator* position = object->pool_position();
    contents_.push_back(object);
    // We need to get an iterator to the last element.  We locally bind to avoid
    // potential compiler trouble.
    iterator back_iter = contents_.end();
    --back_iter;
    *position = back_iter;
  }

  // Remove specified object from pool.  The object must have previously been
  // inserted into this pool.  Returns object.
  T* Remove(T* object) {
    iterator* position = object->pool_position();
    DCHECK(**position == object);
    contents_.erase(*position);
    *position = contents_.end();
    return object;
  }

  // Return oldest object in pool, or NULL.
  T* oldest() const {
    T* result = NULL;
    if (!contents_.empty()) {
      result = contents_.front();
    }
    return result;
  }

  // Remove the least-recently-inserted object from the pool.  Potentially
  // cheaper than Remove(Oldest()).
  T* RemoveOldest() {
    T* result = NULL;
    if (!contents_.empty()) {
      result = contents_.front();
      iterator* position = result->pool_position();
      DCHECK(*position == contents_.begin());
      contents_.pop_front();
      *position = contents_.end();
    }
    return result;
  }

  // DeleteAll: delete all elements of pool
  void DeleteAll() {
    STLDeleteElements(&contents_);
  }

  // Clear: clear pool without deleting elements
  void Clear() {
    contents_.clear();
  }

 private:
  std::list<T*> contents_;

  DISALLOW_COPY_AND_ASSIGN(Pool);
};

}  // namespace net_instaweb

#endif  // PAGESPEED_KERNEL_BASE_POOL_H_
