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