| /* |
| * 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(); |
| |
| #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) |
| { |
| } |
| }; |
| |
| |
| |
| } |
| |
| |
| |
| #endif |