blob: 4dc3067ba3148dea0b8cf83f9de43d3a4a6ac2c4 [file] [log] [blame]
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999-2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
#if !defined(XALAN_OBJECTCACHE_HEADER_GUARD)
#define XALAN_OBJECTCACHE_HEADER_GUARD
#include <algorithm>
#include <vector>
#include <Include/STLHelper.hpp>
#include <Include/XalanAutoPtr.hpp>
template<class ObjectType>
class DefaultCacheCreateFunctor
{
public:
ObjectType*
operator()() const
{
return new ObjectType;
}
};
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:
#if defined(XALAN_NO_NAMESPACES)
typedef vector<ObjectType*> VectorType;
#else
typedef std::vector<ObjectType*> VectorType;
#endif
typedef ObjectType CacheObjectType;
explicit
XalanObjectCache(unsigned int initialListSize = 0) :
m_availableList(),
m_busyList()
{
m_availableList.reserve(initialListSize);
m_busyList.reserve(initialListSize);
}
~XalanObjectCache()
{
reset();
#if !defined(XALAN_NO_NAMESPACES)
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.size() == 0)
{
ObjectType* const theNewObject = m_createFunctor();
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_NAMESPACES)
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.size() != 0)
{
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:
#if defined(XALAN_NO_NAMESPACES)
typedef vector<ObjectType*> VectorType;
#else
typedef std::vector<ObjectType*> VectorType;
#endif
typedef ObjectType CacheObjectType;
explicit
XalanObjectCache(unsigned int initialListSize = 0) :
m_availableList()
{
m_availableList.reserve(initialListSize);
}
~XalanObjectCache()
{
reset();
#if !defined(XALAN_NO_NAMESPACES)
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.size() == 0)
{
return m_createFunctor();
}
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(unsigned int initialListSize = 0) :
BaseClassType(initialListSize)
{
}
};
#endif