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
Doxygen and GraphViz are used to generate this API documentation from the Xalan-C header files.
Xalan-C++ XSLT Processor Version 1.9 |
|