00001 /* 00002 * The Apache Software License, Version 1.1 00003 * 00004 * 00005 * Copyright (c) 1999-2004 The Apache Software Foundation. All rights 00006 * reserved. 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions 00010 * are met: 00011 * 00012 * 1. Redistributions of source code must retain the above copyright 00013 * notice, this list of conditions and the following disclaimer. 00014 * 00015 * 2. Redistributions in binary form must reproduce the above copyright 00016 * notice, this list of conditions and the following disclaimer in 00017 * the documentation and/or other materials provided with the 00018 * distribution. 00019 * 00020 * 3. The end-user documentation included with the redistribution, 00021 * if any, must include the following acknowledgment: 00022 * "This product includes software developed by the 00023 * Apache Software Foundation (http://www.apache.org/)." 00024 * Alternately, this acknowledgment may appear in the software itself, 00025 * if and wherever such third-party acknowledgments normally appear. 00026 * 00027 * 4. The names "Xalan" and "Apache Software Foundation" must 00028 * not be used to endorse or promote products derived from this 00029 * software without prior written permission. For written 00030 * permission, please contact apache@apache.org. 00031 * 00032 * 5. Products derived from this software may not be called "Apache", 00033 * nor may "Apache" appear in their name, without prior written 00034 * permission of the Apache Software Foundation. 00035 * 00036 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 00037 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00038 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00039 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 00040 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00041 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00042 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 00043 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00044 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00045 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 00046 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00047 * SUCH DAMAGE. 00048 * ==================================================================== 00049 * 00050 * This software consists of voluntary contributions made by many 00051 * individuals on behalf of the Apache Software Foundation and was 00052 * originally based on software copyright (c) 1999, International 00053 * Business Machines, Inc., http://www.ibm.com. For more 00054 * information on the Apache Software Foundation, please see 00055 * <http://www.apache.org/>. 00056 */ 00057 #if !defined(XALAN_OBJECTCACHE_HEADER_GUARD) 00058 #define XALAN_OBJECTCACHE_HEADER_GUARD 00059 00060 00061 00062 #include <algorithm> 00063 #include <vector> 00064 00065 00066 00067 #include <xalanc/Include/STLHelper.hpp> 00068 #include <xalanc/Include/XalanAutoPtr.hpp> 00069 00070 00071 00072 XALAN_CPP_NAMESPACE_BEGIN 00073 00074 00075 00076 template<class ObjectType> 00077 class DefaultCacheCreateFunctor 00078 { 00079 public: 00080 00081 ObjectType* 00082 operator()() const 00083 { 00084 return new ObjectType; 00085 } 00086 }; 00087 00088 00089 00090 template<class ObjectType> 00091 class DefaultCacheResetFunctor 00092 { 00093 public: 00094 00095 void 00096 operator()(ObjectType*) const 00097 { 00098 } 00099 }; 00100 00101 00102 00103 template<class ObjectType> 00104 class ClearCacheResetFunctor 00105 { 00106 public: 00107 00108 void 00109 operator()(ObjectType* theInstance) const 00110 { 00111 theInstance->clear(); 00112 } 00113 }; 00114 00115 00116 00117 #if defined(XALAN_OBJECT_CACHE_KEEP_BUSY_LIST) 00118 00119 template< 00120 class ObjectType, 00121 #if defined(XALAN_NO_DEFAULT_TEMPLATE_ARGUMENTS) 00122 class CreateFunctorType, 00123 class DeleteFunctorType, 00124 class ResetFunctorType> 00125 #else 00126 class CreateFunctorType = DefaultCacheCreateFunctor<ObjectType>, 00127 class DeleteFunctorType = DeleteFunctor<ObjectType>, 00128 class ResetFunctorType = DefaultCacheResetFunctor<ObjectType> > 00129 #endif 00130 class XalanObjectCache 00131 { 00132 public: 00133 00134 #if defined(XALAN_NO_STD_NAMESPACE) 00135 typedef vector<ObjectType*> VectorType; 00136 #else 00137 typedef std::vector<ObjectType*> VectorType; 00138 #endif 00139 00140 typedef ObjectType CacheObjectType; 00141 00142 explicit 00143 XalanObjectCache(unsigned int initialListSize = 0) : 00144 m_availableList(), 00145 m_busyList() 00146 { 00147 m_availableList.reserve(initialListSize); 00148 00149 m_busyList.reserve(initialListSize); 00150 } 00151 00152 ~XalanObjectCache() 00153 { 00154 reset(); 00155 00156 #if !defined(XALAN_NO_STD_NAMESPACE) 00157 using std::for_each; 00158 #endif 00159 00160 for_each( 00161 m_availableList.begin(), 00162 m_availableList.end(), 00163 m_deleteFunctor); 00164 } 00165 00166 ObjectType* 00167 get() 00168 { 00169 // We'll always return the back of the free list, since 00170 // that's the cheapest thing. 00171 if (m_availableList.empty() == true) 00172 { 00173 ObjectType* const theNewObject = m_createFunctor(); 00174 00175 m_busyList.push_back(theNewObject); 00176 00177 return theNewObject; 00178 } 00179 else 00180 { 00181 ObjectType* const theObject = m_availableList.back(); 00182 00183 m_busyList.push_back(theObject); 00184 00185 m_availableList.pop_back(); 00186 00187 return theObject; 00188 } 00189 } 00190 00191 bool 00192 release(ObjectType* theInstance) 00193 { 00194 #if !defined(XALAN_NO_STD_NAMESPACE) 00195 using std::find; 00196 #endif 00197 00198 typedef typename VectorType::iterator IteratorType; 00199 00200 const IteratorType i = 00201 find( 00202 m_busyList.begin(), 00203 m_busyList.end(), 00204 theInstance); 00205 00206 if (i == m_busyList.end()) 00207 { 00208 return false; 00209 } 00210 else 00211 { 00212 m_resetFunctor(theInstance); 00213 00214 m_availableList.push_back(theInstance); 00215 00216 m_busyList.erase(i); 00217 00218 return true; 00219 } 00220 } 00221 00222 void 00223 reset() 00224 { 00225 while (m_busyList.empty() == false) 00226 { 00227 ObjectType* const theInstance = m_busyList.back(); 00228 00229 m_resetFunctor(theInstance); 00230 00231 m_availableList.push_back(theInstance); 00232 00233 m_busyList.pop_back(); 00234 } 00235 } 00236 00237 // Functors for various operations... 00238 CreateFunctorType m_createFunctor; 00239 00240 DeleteFunctorType m_deleteFunctor; 00241 00242 ResetFunctorType m_resetFunctor; 00243 00244 private: 00245 00246 // There are not defined... 00247 XalanObjectCache(const XalanObjectCache<ObjectType, CreateFunctorType, DeleteFunctorType, ResetFunctorType>& theRHS); 00248 00249 XalanObjectCache<ObjectType, CreateFunctorType, DeleteFunctorType, ResetFunctorType>& 00250 operator=(const XalanObjectCache<ObjectType, CreateFunctorType, DeleteFunctorType, ResetFunctorType>& theRHS); 00251 00252 00253 // Data members... 00254 VectorType m_availableList; 00255 00256 VectorType m_busyList; 00257 }; 00258 00259 00260 00261 #else 00262 00263 00264 00265 template< 00266 class ObjectType, 00267 #if defined(XALAN_NO_DEFAULT_TEMPLATE_ARGUMENTS) 00268 class CreateFunctorType, 00269 class DeleteFunctorType, 00270 class ResetFunctorType> 00271 #else 00272 class CreateFunctorType = DefaultCacheCreateFunctor<ObjectType>, 00273 class DeleteFunctorType = DeleteFunctor<ObjectType>, 00274 class ResetFunctorType = DefaultCacheResetFunctor<ObjectType> > 00275 #endif 00276 class XalanObjectCache 00277 { 00278 public: 00279 00280 #if defined(XALAN_NO_STD_NAMESPACE) 00281 typedef vector<ObjectType*> VectorType; 00282 #else 00283 typedef std::vector<ObjectType*> VectorType; 00284 #endif 00285 00286 typedef ObjectType CacheObjectType; 00287 00288 explicit 00289 XalanObjectCache(unsigned int initialListSize = 0) : 00290 m_availableList() 00291 { 00292 m_availableList.reserve(initialListSize); 00293 } 00294 00295 ~XalanObjectCache() 00296 { 00297 reset(); 00298 00299 #if !defined(XALAN_NO_STD_NAMESPACE) 00300 using std::for_each; 00301 #endif 00302 00303 for_each( 00304 m_availableList.begin(), 00305 m_availableList.end(), 00306 m_deleteFunctor); 00307 } 00308 00309 ObjectType* 00310 get() 00311 { 00312 // We'll always return the back of the free list, since 00313 // that's the cheapest thing. 00314 if (m_availableList.empty() == true) 00315 { 00316 return m_createFunctor(); 00317 } 00318 else 00319 { 00320 ObjectType* const theObject = m_availableList.back(); 00321 00322 m_availableList.pop_back(); 00323 00324 return theObject; 00325 } 00326 } 00327 00328 bool 00329 release(ObjectType* theInstance) 00330 { 00331 m_resetFunctor(theInstance); 00332 00333 m_availableList.push_back(theInstance); 00334 00335 return true; 00336 } 00337 00338 void 00339 reset() 00340 { 00341 } 00342 00343 // Functors for various operations... 00344 CreateFunctorType m_createFunctor; 00345 00346 DeleteFunctorType m_deleteFunctor; 00347 00348 ResetFunctorType m_resetFunctor; 00349 00350 private: 00351 00352 // These are not defined... 00353 XalanObjectCache(const XalanObjectCache<ObjectType, CreateFunctorType, DeleteFunctorType, ResetFunctorType>& theRHS); 00354 00355 XalanObjectCache<ObjectType, CreateFunctorType, DeleteFunctorType, ResetFunctorType>& 00356 operator=(const XalanObjectCache<ObjectType, CreateFunctorType, DeleteFunctorType, ResetFunctorType>& theRHS); 00357 00358 00359 // Data members... 00360 VectorType m_availableList; 00361 }; 00362 00363 00364 00365 #endif 00366 00367 00368 00369 template<class XalanObjectCacheType> 00370 class GuardCachedObject 00371 { 00372 public: 00373 00374 typedef typename XalanObjectCacheType::CacheObjectType CacheObjectType; 00375 00376 GuardCachedObject(XalanObjectCacheType& theCache) : 00377 m_cache(theCache), 00378 m_cachedObject(theCache.get()) 00379 { 00380 } 00381 00382 ~GuardCachedObject() 00383 { 00384 if (m_cachedObject != 0) 00385 { 00386 m_cache.release(m_cachedObject); 00387 } 00388 } 00389 00390 CacheObjectType* 00391 get() const 00392 { 00393 return m_cachedObject; 00394 } 00395 00396 CacheObjectType* 00397 release() 00398 { 00399 CacheObjectType* const temp = m_cachedObject; 00400 00401 m_cachedObject = 0; 00402 00403 return temp; 00404 } 00405 00406 private: 00407 00408 // Not implemented... 00409 GuardCachedObject(const GuardCachedObject<XalanObjectCacheType>&); 00410 00411 00412 // Data members... 00413 XalanObjectCacheType& m_cache; 00414 00415 CacheObjectType* m_cachedObject; 00416 }; 00417 00418 00419 00420 template<class ObjectType> 00421 class XalanObjectCacheDefault : public XalanObjectCache<ObjectType, DefaultCacheCreateFunctor<ObjectType>, DeleteFunctor<ObjectType>, DefaultCacheResetFunctor<ObjectType> > 00422 { 00423 public: 00424 00425 typedef XalanObjectCache<ObjectType, DefaultCacheCreateFunctor<ObjectType>, DeleteFunctor<ObjectType>, DefaultCacheResetFunctor<ObjectType> > BaseClassType; 00426 00427 explicit 00428 XalanObjectCacheDefault(unsigned int initialListSize = 0) : 00429 BaseClassType(initialListSize) 00430 { 00431 } 00432 }; 00433 00434 00435 00436 XALAN_CPP_NAMESPACE_END 00437 00438 00439 00440 #endif
Doxygen and GraphViz are used to generate this API documentation from the Xalan-C header files.
![]() |
Xalan-C++ XSLT Processor Version 1.7 |
|