blob: a57a9a73f6fd4af7a26f64ad6797d4e443510acd [file] [log] [blame]
/*
* 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>
XALAN_CPP_NAMESPACE_BEGIN
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();
#if !defined(XALAN_NO_STD_NAMESPACE)
using std::for_each;
#endif
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)
{
#if !defined(XALAN_NO_STD_NAMESPACE)
using std::find;
#endif
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();
#if !defined(XALAN_NO_STD_NAMESPACE)
using std::for_each;
#endif
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)
{
}
};
XALAN_CPP_NAMESPACE_END
#endif