OW_Cache.hpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2003-2004 Vintela, Inc. All rights reserved.
00003 *
00004 * Redistribution and use in source and binary forms, with or without
00005 * modification, are permitted provided that the following conditions are met:
00006 *
00007 *  - Redistributions of source code must retain the above copyright notice,
00008 *    this list of conditions and the following disclaimer.
00009 *
00010 *  - Redistributions in binary form must reproduce the above copyright notice,
00011 *    this list of conditions and the following disclaimer in the documentation
00012 *    and/or other materials provided with the distribution.
00013 *
00014 *  - Neither the name of Vintela, Inc. nor the names of its
00015 *    contributors may be used to endorse or promote products derived from this
00016 *    software without specific prior written permission.
00017 *
00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
00019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021 * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc. OR THE CONTRIBUTORS
00022 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00028 * POSSIBILITY OF SUCH DAMAGE.
00029 *******************************************************************************/
00030 
00035 #ifndef OW_CACHE_INCLUDE_GUARD_HPP_
00036 #define OW_CACHE_INCLUDE_GUARD_HPP_
00037 #include "OW_config.h"
00038 #include "OW_HashMap.hpp"
00039 #include "OW_String.hpp"
00040 #include "OW_Mutex.hpp"
00041 #include "OW_MutexLock.hpp"
00042 #include "OW_CIMNULL.hpp"
00043 #include <list>
00044 
00045 // The classes and functions defined in this file are not meant for general
00046 // use, they are internal implementation details.  They may change at any time.
00047 
00048 namespace OW_NAMESPACE
00049 {
00050 
00052 template <typename T>
00053 class Cache
00054 {
00055 public:
00056    Cache();
00057 
00064    void addToCache(const T& cc, const String& key);
00065    
00070    T getFromCache(const String& key);
00071    
00077    void removeFromCache(const String& key);
00078    
00081    void clearCache();
00082    
00086    void setMaxCacheSize(UInt32);
00087 
00088 private:
00089    // a list of items that are cached.  The list is sorted by lru.  The least
00090    // recently acessed item will be at begin(), and the most recenly acessed
00091    // class will be at end()--;  The second part of the pair is the key that
00092    // will be used in the index.
00093    // This is a list because we can quickly O(1) move items from the middle
00094    // to the end of the list when they're accessed. Also we need iterators
00095    // into the list to be stable.  We can re-arrange items in the list
00096    // without having to update the HashMap index.
00097    typedef std::list<std::pair<T, String> > class_cache_t;
00098    
00099    // the index into the cache.  Speeds up finding an item when we need to.
00100    typedef HashMap<String, typename class_cache_t::iterator> cache_index_t;
00101    class_cache_t theCache;
00102    cache_index_t theCacheIndex;
00103    Mutex cacheGuard;
00104    UInt32 maxCacheSize;
00105 };
00107 template <typename T>
00108 Cache<T>::Cache()
00109    : maxCacheSize(100)
00110 {
00111 }
00113 template <typename T>
00114 void
00115 Cache<T>::addToCache(const T& cc, const String& key)
00116 {
00117    MutexLock l(cacheGuard);
00118    if (theCacheIndex.size() >= maxCacheSize)
00119    {
00120       if (!theCache.empty())
00121       {
00122          String key = theCache.begin()->second;
00123          theCache.pop_front();
00124          theCacheIndex.erase(key);
00125       }
00126    }
00127    typename class_cache_t::iterator i = theCache.insert(theCache.end(),
00128       typename class_cache_t::value_type(cc, key));
00129    theCacheIndex.insert(typename cache_index_t::value_type(key, i));
00130 }
00132 template <typename T>
00133 T
00134 Cache<T>::getFromCache(const String& key)
00135 {
00136    MutexLock l(cacheGuard);
00137    T cc(CIMNULL);
00138    // look up key in the index
00139    typename cache_index_t::iterator ii = theCacheIndex.find(key);
00140    if (ii != theCacheIndex.end())
00141    {
00142       // we've got it, now get the iterator
00143       typename class_cache_t::iterator i = ii->second;
00144       // get the class
00145       cc = i->first;
00146       // now move the class to the end of the list
00147       theCache.splice(theCache.end(),theCache,i);
00148       // because splice doesn't actually move the elements, we don't have to
00149       // update the iterator in theCacheIndex
00150    }
00151    return cc;
00152 }
00154 template <typename T>
00155 void
00156 Cache<T>::removeFromCache(const String& key)
00157 {
00158    MutexLock l(cacheGuard);
00159    typename cache_index_t::iterator i = theCacheIndex.find(key);
00160    if (i != theCacheIndex.end())
00161    {
00162       typename class_cache_t::iterator ci = i->second;
00163       theCacheIndex.erase(i);
00164       theCache.erase(ci);
00165    }
00166 }
00168 template <typename T>
00169 void
00170 Cache<T>::clearCache()
00171 {
00172    MutexLock l(cacheGuard);
00173    theCache.clear();
00174    theCacheIndex.clear();
00175 }
00177 template <typename T>
00178 void
00179 Cache<T>::setMaxCacheSize(UInt32 max)
00180 {
00181    MutexLock l(cacheGuard);
00182    maxCacheSize = max;
00183    if (max != 0)
00184    {
00185       while (theCacheIndex.size() >= maxCacheSize)
00186       {
00187          if (!theCache.empty())
00188          {
00189             String key = theCache.begin()->second;
00190             theCache.pop_front();
00191             theCacheIndex.erase(key);
00192          }
00193       }
00194    }
00195 }
00196 
00197 } // end namespace OW_NAMESPACE
00198 
00199 #endif

Generated on Thu Feb 9 08:47:52 2006 for openwbem by  doxygen 1.4.6