## 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.