Xalan-C++ API Documentation

The Xalan C++ XSLT Processor Version 1.9

Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages

XalanObjectCache.hpp

Go to the documentation of this file.
00001 /*
00002  * Copyright 1999-2004 The Apache Software Foundation.
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 #if !defined(XALAN_OBJECTCACHE_HEADER_GUARD)
00017 #define XALAN_OBJECTCACHE_HEADER_GUARD
00018 
00019 
00020 
00021 #include <algorithm>
00022 
00023 
00024 
00025 #include <xalanc/Include/XalanVector.hpp>
00026 #include <xalanc/Include/STLHelper.hpp>
00027 
00028 
00029 
00030 
00031 XALAN_CPP_NAMESPACE_BEGIN
00032 
00033 
00034 
00035 template<class ObjectType>
00036 class DefaultCacheCreateFunctor
00037 {
00038 public:
00039 
00040     ObjectType*
00041     operator()(MemoryManagerType& theManager) const
00042     {
00043         typedef ObjectType ThisType;
00044         
00045         XalanMemMgrAutoPtr<ThisType, false> theGuard( theManager , (ThisType*)theManager.allocate(sizeof(ThisType)));
00046 
00047         ThisType* theResult = theGuard.get();
00048 
00049         new (theResult) ThisType();
00050 
00051         theGuard.release();
00052 
00053         return theResult;
00054     }
00055 };
00056 
00057 template<class ObjectType>
00058 class DefaultCacheCreateFunctorMemMgr
00059 {
00060 public:
00061 
00062     ObjectType*
00063     operator()(MemoryManagerType& theManager) const
00064     {
00065         typedef ObjectType ThisType;
00066         
00067         XalanMemMgrAutoPtr<ThisType, false> theGuard( theManager , (ThisType*)theManager.allocate(sizeof(ThisType)));
00068 
00069         ThisType* theResult = theGuard.get();
00070 
00071         new (theResult) ThisType(theManager);
00072 
00073         theGuard.release();
00074 
00075         return theResult;
00076     }
00077 };
00078 
00079 
00080 template<class ObjectType>
00081 class DefaultCacheResetFunctor
00082 {
00083 public:
00084 
00085     void
00086     operator()(ObjectType*) const
00087     {
00088     }
00089 };
00090 
00091 
00092 
00093 template<class ObjectType>
00094 class ClearCacheResetFunctor
00095 {
00096 public:
00097 
00098     void
00099     operator()(ObjectType*  theInstance) const
00100     {
00101         theInstance->clear();
00102     }
00103 };
00104 
00105 
00106 
00107 #if defined(XALAN_OBJECT_CACHE_KEEP_BUSY_LIST)
00108 
00109 template<
00110 class ObjectType,
00111 #if defined(XALAN_NO_DEFAULT_TEMPLATE_ARGUMENTS)
00112 class CreateFunctorType,
00113 class DeleteFunctorType,
00114 class ResetFunctorType>
00115 #else
00116 class CreateFunctorType = DefaultCacheCreateFunctor<ObjectType>,
00117 class DeleteFunctorType = DeleteFunctor<ObjectType>,
00118 class ResetFunctorType = DefaultCacheResetFunctor<ObjectType> >
00119 #endif
00120 class XalanObjectCache
00121 {
00122 public:
00123 
00124     typedef XalanVector<ObjectType*>            VectorType;
00125 
00126     typedef ObjectType  CacheObjectType;
00127 
00128     explicit
00129     XalanObjectCache(MemoryManagerType& theManager,
00130                     unsigned int    initialListSize = 0) :
00131         m_availableList(theManager),
00132         m_busyList(theManager)
00133     {
00134         m_availableList.reserve(initialListSize);
00135 
00136         m_busyList.reserve(initialListSize);
00137     }
00138 
00139     ~XalanObjectCache()
00140     {
00141         reset();
00142 
00143 #if !defined(XALAN_NO_STD_NAMESPACE)
00144         using std::for_each;
00145 #endif
00146 
00147         for_each(
00148                 m_availableList.begin(),
00149                 m_availableList.end(),
00150                 m_deleteFunctor(theManager));
00151     }
00152 
00153     ObjectType*
00154     get()
00155     {
00156         // We'll always return the back of the free list, since
00157         // that's the cheapest thing.
00158         if (m_availableList.empty() == true)
00159         {
00160             ObjectType* const   theNewObject = m_createFunctor(theManager);
00161 
00162             m_busyList.push_back(theNewObject);
00163 
00164             return theNewObject;
00165         }
00166         else
00167         {
00168             ObjectType* const   theObject = m_availableList.back();
00169 
00170             m_busyList.push_back(theObject);
00171 
00172             m_availableList.pop_back();
00173 
00174             return theObject;
00175         }
00176     }
00177 
00178     bool
00179     release(ObjectType*     theInstance)
00180     {
00181 #if !defined(XALAN_NO_STD_NAMESPACE)
00182         using std::find;
00183 #endif
00184 
00185         typedef typename VectorType::iterator   IteratorType;
00186 
00187         const IteratorType  i =
00188             find(
00189                 m_busyList.begin(),
00190                 m_busyList.end(),
00191                 theInstance);
00192 
00193         if (i == m_busyList.end())
00194         {
00195             return false;
00196         }
00197         else
00198         {
00199             m_resetFunctor(theInstance);
00200 
00201             m_availableList.push_back(theInstance);
00202 
00203             m_busyList.erase(i);
00204 
00205             return true;
00206         }
00207     }
00208 
00209     void
00210     reset()
00211     {
00212         while (m_busyList.empty() == false)
00213         {
00214             ObjectType* const   theInstance = m_busyList.back();
00215 
00216             m_resetFunctor(theInstance);
00217 
00218             m_availableList.push_back(theInstance);
00219 
00220             m_busyList.pop_back();
00221         }
00222     }
00223 
00224     // Functors for various operations...
00225     CreateFunctorType   m_createFunctor;
00226 
00227     DeleteFunctorType   m_deleteFunctor;
00228 
00229     ResetFunctorType    m_resetFunctor;
00230 
00231 private:
00232 
00233     // There are not defined...
00234     XalanObjectCache(const XalanObjectCache<ObjectType, CreateFunctorType, DeleteFunctorType, ResetFunctorType>&    theRHS);
00235 
00236     XalanObjectCache<ObjectType, CreateFunctorType, DeleteFunctorType, ResetFunctorType>&
00237     operator=(const XalanObjectCache<ObjectType, CreateFunctorType, DeleteFunctorType, ResetFunctorType>&   theRHS);
00238 
00239 
00240     // Data members...
00241     VectorType          m_availableList;
00242 
00243     VectorType          m_busyList;
00244 };
00245 
00246 
00247 
00248 #else
00249 
00250 
00251 
00252 template<
00253 class ObjectType,
00254 #if defined(XALAN_NO_DEFAULT_TEMPLATE_ARGUMENTS)
00255 class CreateFunctorType,
00256 class DeleteFunctorType,
00257 class ResetFunctorType>
00258 #else
00259 class CreateFunctorType = DefaultCacheCreateFunctor<ObjectType>,
00260 class DeleteFunctorType = DeleteFunctor<ObjectType>,
00261 class ResetFunctorType = DefaultCacheResetFunctor<ObjectType> >
00262 #endif
00263 class XalanObjectCache
00264 {
00265 public:
00266 
00267     typedef XalanVector<ObjectType*>            VectorType;
00268 
00269     typedef ObjectType  CacheObjectType;
00270 
00271     explicit
00272     XalanObjectCache(MemoryManagerType& theManager,
00273                     unsigned int    initialListSize = 0) :
00274         m_deleteFunctor(theManager),
00275         m_availableList(theManager)
00276     {
00277         m_availableList.reserve(initialListSize);
00278     }
00279 
00280     ~XalanObjectCache()
00281     {
00282         reset();
00283 
00284 #if !defined(XALAN_NO_STD_NAMESPACE)
00285         using std::for_each;
00286 #endif
00287 
00288         for_each(
00289                 m_availableList.begin(),
00290                 m_availableList.end(),
00291                 m_deleteFunctor);
00292     }
00293 
00294     ObjectType*
00295     get()
00296     {
00297         // We'll always return the back of the free list, since
00298         // that's the cheapest thing.
00299         if (m_availableList.empty() == true)
00300         {
00301             return m_createFunctor(m_availableList.getMemoryManager());
00302         }
00303         else
00304         {
00305             ObjectType* const   theObject = m_availableList.back();
00306 
00307             m_availableList.pop_back();
00308 
00309             return theObject;
00310         }
00311     }
00312 
00313     bool
00314     release(ObjectType*     theInstance)
00315     {
00316         m_resetFunctor(theInstance);
00317 
00318         m_availableList.push_back(theInstance);
00319 
00320         return true;
00321     }
00322 
00323     void
00324     reset()
00325     {
00326     }
00327 
00328     // Functors for various operations...
00329     CreateFunctorType   m_createFunctor;
00330 
00331     DeleteFunctorType   m_deleteFunctor;
00332 
00333     ResetFunctorType    m_resetFunctor;
00334 
00335 private:
00336 
00337     // These are not defined...
00338     XalanObjectCache(const XalanObjectCache<ObjectType, CreateFunctorType, DeleteFunctorType, ResetFunctorType>&    theRHS);
00339 
00340     XalanObjectCache<ObjectType, CreateFunctorType, DeleteFunctorType, ResetFunctorType>&
00341     operator=(const XalanObjectCache<ObjectType, CreateFunctorType, DeleteFunctorType, ResetFunctorType>&   theRHS);
00342 
00343 
00344     // Data members...
00345     VectorType          m_availableList;
00346 };
00347 
00348 
00349 
00350 #endif
00351 
00352 
00353 
00354 template<class XalanObjectCacheType>
00355 class GuardCachedObject
00356 {
00357 public:
00358 
00359     typedef typename XalanObjectCacheType::CacheObjectType  CacheObjectType;
00360 
00361     GuardCachedObject(XalanObjectCacheType& theCache) :
00362         m_cache(theCache),
00363         m_cachedObject(theCache.get())
00364     {
00365     }
00366 
00367     ~GuardCachedObject()
00368     {
00369         if (m_cachedObject != 0)
00370         {
00371             m_cache.release(m_cachedObject);
00372         }
00373     }
00374 
00375     CacheObjectType*
00376     get() const
00377     {
00378         return m_cachedObject;
00379     }
00380 
00381     CacheObjectType*
00382     release()
00383     {
00384         CacheObjectType* const  temp = m_cachedObject;
00385 
00386         m_cachedObject = 0;
00387 
00388         return temp;
00389     }
00390 
00391 private:
00392 
00393     // Not implemented...
00394     GuardCachedObject(const GuardCachedObject<XalanObjectCacheType>&);
00395 
00396 
00397     // Data members...
00398     XalanObjectCacheType&   m_cache;
00399 
00400     CacheObjectType*        m_cachedObject;
00401 };
00402 
00403 
00404 
00405 template<class ObjectType>
00406 class XalanObjectCacheDefault : public XalanObjectCache<ObjectType, DefaultCacheCreateFunctor<ObjectType>, DeleteFunctor<ObjectType>, DefaultCacheResetFunctor<ObjectType> >
00407 {
00408 public:
00409 
00410     typedef XalanObjectCache<ObjectType, DefaultCacheCreateFunctor<ObjectType>, DeleteFunctor<ObjectType>, DefaultCacheResetFunctor<ObjectType> >       BaseClassType;
00411 
00412     explicit
00413     XalanObjectCacheDefault(unsigned int    initialListSize = 0) :
00414         BaseClassType(initialListSize)
00415     {
00416     }
00417 };
00418 
00419 
00420 
00421 XALAN_CPP_NAMESPACE_END
00422 
00423 
00424 
00425 #endif

Interpreting class diagrams

Doxygen and GraphViz are used to generate this API documentation from the Xalan-C header files.

Xalan-C++ XSLT Processor Version 1.9
Copyright © 1999-2004 The Apache Software Foundation. All Rights Reserved.