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 00058 template<class ObjectType> 00059 class DefaultCacheCreateFunctorMemMgr 00060 { 00061 public: 00062 00063 ObjectType* 00064 operator()(MemoryManagerType& theManager) const 00065 { 00066 typedef ObjectType ThisType; 00067 00068 XalanMemMgrAutoPtr<ThisType, false> theGuard( theManager , (ThisType*)theManager.allocate(sizeof(ThisType))); 00069 00070 ThisType* theResult = theGuard.get(); 00071 00072 new (theResult) ThisType(theManager); 00073 00074 theGuard.release(); 00075 00076 return theResult; 00077 } 00078 }; 00079 00080 00081 template<class ObjectType> 00082 class DefaultCacheResetFunctor 00083 { 00084 public: 00085 00086 void 00087 operator()(ObjectType*) const 00088 { 00089 } 00090 }; 00091 00092 00093 00094 template<class ObjectType> 00095 class ClearCacheResetFunctor 00096 { 00097 public: 00098 00099 void 00100 operator()(ObjectType* theInstance) const 00101 { 00102 theInstance->clear(); 00103 } 00104 }; 00105 00106 00107 00108 #if defined(XALAN_OBJECT_CACHE_KEEP_BUSY_LIST) 00109 00110 template< 00111 class ObjectType, 00112 #if defined(XALAN_NO_DEFAULT_TEMPLATE_ARGUMENTS) 00113 class CreateFunctorType, 00114 class DeleteFunctorType, 00115 class ResetFunctorType> 00116 #else 00117 class CreateFunctorType = DefaultCacheCreateFunctor<ObjectType>, 00118 class DeleteFunctorType = DeleteFunctor<ObjectType>, 00119 class ResetFunctorType = DefaultCacheResetFunctor<ObjectType> > 00120 #endif 00121 class XalanObjectCache 00122 { 00123 public: 00124 00125 typedef XalanVector<ObjectType*> VectorType; 00126 00127 typedef ObjectType CacheObjectType; 00128 00129 explicit 00130 XalanObjectCache( 00131 MemoryManagerType& theManager, 00132 unsigned int initialListSize = 0) : 00133 m_availableList(theManager), 00134 m_busyList(theManager) 00135 { 00136 m_availableList.reserve(initialListSize); 00137 00138 m_busyList.reserve(initialListSize); 00139 } 00140 00141 ~XalanObjectCache() 00142 { 00143 reset(); 00144 00145 #if !defined(XALAN_NO_STD_NAMESPACE) 00146 using std::for_each; 00147 #endif 00148 00149 for_each( 00150 m_availableList.begin(), 00151 m_availableList.end(), 00152 m_deleteFunctor(theManager)); 00153 } 00154 00155 ObjectType* 00156 get() 00157 { 00158 // We'll always return the back of the free list, since 00159 // that's the cheapest thing. 00160 if (m_availableList.empty() == true) 00161 { 00162 ObjectType* const theNewObject = m_createFunctor(m_availableList.getMemoryManager()); 00163 00164 m_busyList.push_back(theNewObject); 00165 00166 return theNewObject; 00167 } 00168 else 00169 { 00170 ObjectType* const theObject = m_availableList.back(); 00171 00172 m_busyList.push_back(theObject); 00173 00174 m_availableList.pop_back(); 00175 00176 return theObject; 00177 } 00178 } 00179 00180 bool 00181 release(ObjectType* theInstance) 00182 { 00183 #if !defined(XALAN_NO_STD_NAMESPACE) 00184 using std::find; 00185 #endif 00186 00187 typedef typename VectorType::iterator IteratorType; 00188 00189 const IteratorType i = 00190 find( 00191 m_busyList.begin(), 00192 m_busyList.end(), 00193 theInstance); 00194 00195 if (i == m_busyList.end()) 00196 { 00197 return false; 00198 } 00199 else 00200 { 00201 m_resetFunctor(theInstance); 00202 00203 m_availableList.push_back(theInstance); 00204 00205 m_busyList.erase(i); 00206 00207 return true; 00208 } 00209 } 00210 00211 void 00212 reset() 00213 { 00214 while (m_busyList.empty() == false) 00215 { 00216 ObjectType* const theInstance = m_busyList.back(); 00217 00218 m_resetFunctor(theInstance); 00219 00220 m_availableList.push_back(theInstance); 00221 00222 m_busyList.pop_back(); 00223 } 00224 } 00225 00226 // Functors for various operations... 00227 CreateFunctorType m_createFunctor; 00228 00229 DeleteFunctorType m_deleteFunctor; 00230 00231 ResetFunctorType m_resetFunctor; 00232 00233 private: 00234 00235 // There are not defined... 00236 XalanObjectCache(const XalanObjectCache<ObjectType, CreateFunctorType, DeleteFunctorType, ResetFunctorType>& theRHS); 00237 00238 XalanObjectCache<ObjectType, CreateFunctorType, DeleteFunctorType, ResetFunctorType>& 00239 operator=(const XalanObjectCache<ObjectType, CreateFunctorType, DeleteFunctorType, ResetFunctorType>& theRHS); 00240 00241 00242 // Data members... 00243 VectorType m_availableList; 00244 00245 VectorType m_busyList; 00246 }; 00247 00248 00249 00250 #else 00251 00252 00253 00254 template< 00255 class ObjectType, 00256 #if defined(XALAN_NO_DEFAULT_TEMPLATE_ARGUMENTS) 00257 class CreateFunctorType, 00258 class DeleteFunctorType, 00259 class ResetFunctorType> 00260 #else 00261 class CreateFunctorType = DefaultCacheCreateFunctor<ObjectType>, 00262 class DeleteFunctorType = DeleteFunctor<ObjectType>, 00263 class ResetFunctorType = DefaultCacheResetFunctor<ObjectType> > 00264 #endif 00265 class XalanObjectCache 00266 { 00267 public: 00268 00269 typedef XalanVector<ObjectType*> VectorType; 00270 00271 typedef ObjectType CacheObjectType; 00272 00273 explicit 00274 XalanObjectCache(MemoryManagerType& theManager, 00275 unsigned int initialListSize = 0) : 00276 m_deleteFunctor(theManager), 00277 m_availableList(theManager) 00278 { 00279 m_availableList.reserve(initialListSize); 00280 } 00281 00282 ~XalanObjectCache() 00283 { 00284 reset(); 00285 00286 #if !defined(XALAN_NO_STD_NAMESPACE) 00287 using std::for_each; 00288 #endif 00289 00290 for_each( 00291 m_availableList.begin(), 00292 m_availableList.end(), 00293 m_deleteFunctor); 00294 } 00295 00296 ObjectType* 00297 get() 00298 { 00299 // We'll always return the back of the free list, since 00300 // that's the cheapest thing. 00301 if (m_availableList.empty() == true) 00302 { 00303 return m_createFunctor(m_availableList.getMemoryManager()); 00304 } 00305 else 00306 { 00307 ObjectType* const theObject = m_availableList.back(); 00308 00309 m_availableList.pop_back(); 00310 00311 return theObject; 00312 } 00313 } 00314 00315 bool 00316 release(ObjectType* theInstance) 00317 { 00318 m_resetFunctor(theInstance); 00319 00320 m_availableList.push_back(theInstance); 00321 00322 return true; 00323 } 00324 00325 void 00326 reset() 00327 { 00328 } 00329 00330 // Functors for various operations... 00331 CreateFunctorType m_createFunctor; 00332 00333 DeleteFunctorType m_deleteFunctor; 00334 00335 ResetFunctorType m_resetFunctor; 00336 00337 private: 00338 00339 // These are not defined... 00340 XalanObjectCache(const XalanObjectCache<ObjectType, CreateFunctorType, DeleteFunctorType, ResetFunctorType>& theRHS); 00341 00342 XalanObjectCache<ObjectType, CreateFunctorType, DeleteFunctorType, ResetFunctorType>& 00343 operator=(const XalanObjectCache<ObjectType, CreateFunctorType, DeleteFunctorType, ResetFunctorType>& theRHS); 00344 00345 00346 // Data members... 00347 VectorType m_availableList; 00348 }; 00349 00350 00351 00352 #endif 00353 00354 00355 00356 template<class XalanObjectCacheType> 00357 class GuardCachedObject 00358 { 00359 public: 00360 00361 typedef typename XalanObjectCacheType::CacheObjectType CacheObjectType; 00362 00363 GuardCachedObject(XalanObjectCacheType& theCache) : 00364 m_cache(theCache), 00365 m_cachedObject(theCache.get()) 00366 { 00367 } 00368 00369 ~GuardCachedObject() 00370 { 00371 if (m_cachedObject != 0) 00372 { 00373 m_cache.release(m_cachedObject); 00374 } 00375 } 00376 00377 CacheObjectType* 00378 get() const 00379 { 00380 return m_cachedObject; 00381 } 00382 00383 CacheObjectType* 00384 release() 00385 { 00386 CacheObjectType* const temp = m_cachedObject; 00387 00388 m_cachedObject = 0; 00389 00390 return temp; 00391 } 00392 00393 private: 00394 00395 // Not implemented... 00396 GuardCachedObject(const GuardCachedObject<XalanObjectCacheType>&); 00397 00398 00399 // Data members... 00400 XalanObjectCacheType& m_cache; 00401 00402 CacheObjectType* m_cachedObject; 00403 }; 00404 00405 00406 00407 template<class ObjectType> 00408 class XalanObjectCacheDefault : 00409 public XalanObjectCache< 00410 ObjectType, 00411 DefaultCacheCreateFunctor<ObjectType>, 00412 DeleteFunctor<ObjectType>, 00413 DefaultCacheResetFunctor<ObjectType> > 00414 { 00415 public: 00416 00417 typedef XalanObjectCache< 00418 ObjectType, 00419 DefaultCacheCreateFunctor<ObjectType>, 00420 DeleteFunctor<ObjectType>, 00421 DefaultCacheResetFunctor<ObjectType> > BaseClassType; 00422 00423 explicit 00424 XalanObjectCacheDefault( 00425 MemoryManagerType& theManager, 00426 unsigned int initialListSize = 0) : 00427 BaseClassType(theManager, initialListSize) 00428 { 00429 } 00430 }; 00431 00432 00433 00434 template<class ObjectType> 00435 class XalanMemoryManagerObjectCacheDefault : 00436 public XalanObjectCache< 00437 ObjectType, 00438 DefaultCacheCreateFunctorMemMgr<ObjectType>, 00439 DeleteFunctor<ObjectType>, 00440 DefaultCacheResetFunctor<ObjectType> > 00441 { 00442 public: 00443 00444 typedef XalanObjectCache< 00445 ObjectType, 00446 DefaultCacheCreateFunctorMemMgr<ObjectType>, 00447 DeleteFunctor<ObjectType>, 00448 DefaultCacheResetFunctor<ObjectType> > BaseClassType; 00449 00450 explicit 00451 XalanMemoryManagerObjectCacheDefault( 00452 MemoryManagerType& theManager, 00453 unsigned int initialListSize = 0) : 00454 BaseClassType(theManager, initialListSize) 00455 { 00456 } 00457 }; 00458 00459 00460 00461 XALAN_CPP_NAMESPACE_END 00462 00463 00464 00465 #endif
Doxygen and GraphViz are used to generate this API documentation from the Xalan-C header files.
Xalan-C++ XSLT Processor Version 1.10 |
|