/*
 * 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.
 */
#if !defined(XALAN_OBJECTCACHE_HEADER_GUARD)
#define XALAN_OBJECTCACHE_HEADER_GUARD



#include <algorithm>



#include <xalanc/Include/XalanVector.hpp>
#include <xalanc/Include/STLHelper.hpp>




namespace XALAN_CPP_NAMESPACE {



template<class ObjectType>
class DefaultCacheCreateFunctor
{
public:

    ObjectType*
    operator()(MemoryManager&   theManager) const
    {
        typedef ObjectType ThisType;

        XalanAllocationGuard    theGuard(theManager, theManager.allocate(sizeof(ThisType)));

        ThisType* const     theResult =
            new (theGuard.get()) ThisType();

        theGuard.release();

        return theResult;
    }
};



template<class ObjectType>
class DefaultCacheCreateFunctorMemMgr
{
public:

    ObjectType*
    operator()(MemoryManager&   theManager) const
    {
        typedef ObjectType ThisType;

        XalanAllocationGuard    theGuard(theManager, theManager.allocate(sizeof(ThisType)));

        ThisType* const     theResult =
            new (theGuard.get()) ThisType(theManager);

        theGuard.release();

        return theResult;
    }
};



template<class ObjectType>
class DefaultCacheResetFunctor
{
public:

    void
    operator()(ObjectType*) const
    {
    }
};



template<class ObjectType>
class ClearCacheResetFunctor
{
public:

    void
    operator()(ObjectType*  theInstance) const
    {
        theInstance->clear();
    }
};



#if defined(XALAN_OBJECT_CACHE_KEEP_BUSY_LIST)

template<
class ObjectType,
#if defined(XALAN_NO_DEFAULT_TEMPLATE_ARGUMENTS)
class CreateFunctorType,
class DeleteFunctorType,
class ResetFunctorType>
#else
class CreateFunctorType = DefaultCacheCreateFunctor<ObjectType>,
class DeleteFunctorType = DeleteFunctor<ObjectType>,
class ResetFunctorType = DefaultCacheResetFunctor<ObjectType> >
#endif
class XalanObjectCache
{
public:

    typedef XalanVector<ObjectType*>            VectorType;

    typedef ObjectType  CacheObjectType;

    explicit
    XalanObjectCache(
                MemoryManager&  theManager,
                XalanSize_t         initialListSize = 0) :
        m_availableList(theManager),
        m_busyList(theManager)
    {
        m_availableList.reserve(initialListSize);

        m_busyList.reserve(initialListSize);
    }

    ~XalanObjectCache()
    {
        reset();

        using std::for_each;

        for_each(
                m_availableList.begin(),
                m_availableList.end(),
                m_deleteFunctor(theManager));
    }

    ObjectType*
    get()
    {
        // We'll always return the back of the free list, since
        // that's the cheapest thing.
        if (m_availableList.empty() == true)
        {
            ObjectType* const   theNewObject = m_createFunctor(m_availableList.getMemoryManager());

            m_busyList.push_back(theNewObject);

            return theNewObject;
        }
        else
        {
            ObjectType* const   theObject = m_availableList.back();

            m_busyList.push_back(theObject);

            m_availableList.pop_back();

            return theObject;
        }
    }

    bool
    release(ObjectType*     theInstance)
    {
        using std::find;

        typedef typename VectorType::iterator   IteratorType;

        const IteratorType  i =
            find(
                m_busyList.begin(),
                m_busyList.end(),
                theInstance);

        if (i == m_busyList.end())
        {
            return false;
        }
        else
        {
            m_resetFunctor(theInstance);

            m_availableList.push_back(theInstance);

            m_busyList.erase(i);

            return true;
        }
    }

    void
    reset()
    {
        while (m_busyList.empty() == false)
        {
            ObjectType* const   theInstance = m_busyList.back();

            m_resetFunctor(theInstance);

            m_availableList.push_back(theInstance);

            m_busyList.pop_back();
        }
    }

    // Functors for various operations...
    CreateFunctorType   m_createFunctor;

    DeleteFunctorType   m_deleteFunctor;

    ResetFunctorType    m_resetFunctor;

private:

    // There are not defined...
    XalanObjectCache(const XalanObjectCache<ObjectType, CreateFunctorType, DeleteFunctorType, ResetFunctorType>&    theRHS);

    XalanObjectCache<ObjectType, CreateFunctorType, DeleteFunctorType, ResetFunctorType>&
    operator=(const XalanObjectCache<ObjectType, CreateFunctorType, DeleteFunctorType, ResetFunctorType>&   theRHS);


    // Data members...
    VectorType          m_availableList;

    VectorType          m_busyList;
};



#else



template<
class ObjectType,
#if defined(XALAN_NO_DEFAULT_TEMPLATE_ARGUMENTS)
class CreateFunctorType,
class DeleteFunctorType,
class ResetFunctorType>
#else
class CreateFunctorType = DefaultCacheCreateFunctor<ObjectType>,
class DeleteFunctorType = DeleteFunctor<ObjectType>,
class ResetFunctorType = DefaultCacheResetFunctor<ObjectType> >
#endif
class XalanObjectCache
{
public:

    typedef XalanVector<ObjectType*>            VectorType;

    typedef ObjectType  CacheObjectType;

    explicit
    XalanObjectCache(MemoryManager&     theManager,
                    XalanSize_t             initialListSize = 0) :
        m_deleteFunctor(theManager),
        m_availableList(theManager)
    {
        m_availableList.reserve(initialListSize);
    }

    ~XalanObjectCache()
    {
        reset();

        using std::for_each;

        for_each(
                m_availableList.begin(),
                m_availableList.end(),
                m_deleteFunctor);
    }

    ObjectType*
    get()
    {
        // We'll always return the back of the free list, since
        // that's the cheapest thing.
        if (m_availableList.empty() == true)
        {
            return m_createFunctor(m_availableList.getMemoryManager());
        }
        else
        {
            ObjectType* const   theObject = m_availableList.back();

            m_availableList.pop_back();

            return theObject;
        }
    }

    bool
    release(ObjectType*     theInstance)
    {
        m_resetFunctor(theInstance);

        m_availableList.push_back(theInstance);

        return true;
    }

    void
    reset()
    {
    }

    // Functors for various operations...
    CreateFunctorType   m_createFunctor;

    DeleteFunctorType   m_deleteFunctor;

    ResetFunctorType    m_resetFunctor;

private:

    // These are not defined...
    XalanObjectCache(const XalanObjectCache<ObjectType, CreateFunctorType, DeleteFunctorType, ResetFunctorType>&    theRHS);

    XalanObjectCache<ObjectType, CreateFunctorType, DeleteFunctorType, ResetFunctorType>&
    operator=(const XalanObjectCache<ObjectType, CreateFunctorType, DeleteFunctorType, ResetFunctorType>&   theRHS);


    // Data members...
    VectorType          m_availableList;
};



#endif



template<class XalanObjectCacheType>
class GuardCachedObject
{
public:

    typedef typename XalanObjectCacheType::CacheObjectType  CacheObjectType;

    GuardCachedObject(XalanObjectCacheType& theCache) :
        m_cache(theCache),
        m_cachedObject(theCache.get())
    {
    }

    ~GuardCachedObject()
    {
        if (m_cachedObject != 0)
        {
            m_cache.release(m_cachedObject);
        }
    }

    CacheObjectType*
    get() const
    {
        return m_cachedObject;
    }

    CacheObjectType*
    release()
    {
        CacheObjectType* const  temp = m_cachedObject;

        m_cachedObject = 0;

        return temp;
    }

private:

    // Not implemented...
    GuardCachedObject(const GuardCachedObject<XalanObjectCacheType>&);


    // Data members...
    XalanObjectCacheType&   m_cache;

    CacheObjectType*        m_cachedObject;
};



template<class ObjectType>
class XalanObjectCacheDefault :
            public XalanObjectCache<
                        ObjectType,
                        DefaultCacheCreateFunctor<ObjectType>,
                        DeleteFunctor<ObjectType>,
                        DefaultCacheResetFunctor<ObjectType> >
{
public:

    typedef XalanObjectCache<
                ObjectType,
                DefaultCacheCreateFunctor<ObjectType>,
                DeleteFunctor<ObjectType>,
                DefaultCacheResetFunctor<ObjectType> >  BaseClassType;

    explicit
    XalanObjectCacheDefault(
                MemoryManager&  theManager,
                XalanSize_t         initialListSize = 0) :
        BaseClassType(theManager, initialListSize)
    {
    }
};



template<class ObjectType>
class XalanMemoryManagerObjectCacheDefault :
            public XalanObjectCache<
                        ObjectType,
                        DefaultCacheCreateFunctorMemMgr<ObjectType>,
                        DeleteFunctor<ObjectType>,
                        DefaultCacheResetFunctor<ObjectType> >
{
public:

    typedef XalanObjectCache<
                ObjectType,
                DefaultCacheCreateFunctorMemMgr<ObjectType>,
                DeleteFunctor<ObjectType>,
                DefaultCacheResetFunctor<ObjectType> >  BaseClassType;

    explicit
    XalanMemoryManagerObjectCacheDefault(
                MemoryManager&  theManager,
                XalanSize_t         initialListSize = 0) :
        BaseClassType(theManager, initialListSize)
    {
    }
};



}



#endif
