Cache.hh

00001 //********************************************************************
00002 //*** cache/Cache.hh
00003 //*** Copyright (c) 2002 by Markus Winand <mws@fatalmind.com>
00004 //*** $Id: Cache.hh,v 1.16 2008-01-20 13:33:13 mws Exp $
00005 //********************************************************************
00006 
00007 #ifndef CACHE_CACHE_HH
00008 #define CACHE_CACHE_HH
00009 
00010 #ifndef INCLUDED_GC_PTR_HH
00011 #include "mm/gc_ptr.hh"
00012 #endif
00013 
00014 #ifndef TYPES_ARG_TRAITS_HH
00015 #include "Types/arg_traits.hh"
00016 #endif
00017 
00018 #ifndef INCLUDED_THREAD_LOCK_HH
00019 #include "Thread/Lock.hh"
00020 #endif
00021 
00022 #include <map>
00023 #include <limits>
00024 #include <time.h>
00025 
00026 namespace fatalmind {
00027 
00028 class LeastRecentlyUsedExpirationPolicy {
00029     public:
00030         LeastRecentlyUsedExpirationPolicy()
00031         : _lasthit(time(NULL))
00032         {
00033         };
00034 
00035         bool isValid() const throw() {
00036             return true;
00037         }
00038         int efficiency() const throw() {
00039             return _lasthit;
00040         }
00041 
00042         void hit() throw() {
00043             _lasthit = time(NULL);
00044         }
00045     private:
00046         time_t _lasthit;
00047 };
00048 
00049 template<typename K // key
00050     , typename V    // value
00051     , typename Ctor // ctor for value
00052     , typename E = LeastRecentlyUsedExpirationPolicy
00053     , class TM = DefaultThreadedModel
00054     , template <typename> class Allocator = std::allocator >
00055 class CacheInterface {
00056     public:
00057         typedef gc_ptr<V, TM> value_t;
00058         virtual value_t get(typename arg_traits<K>::const_param key) = 0;
00059         virtual value_t get(
00060               typename arg_traits<K>::const_param key
00061             , typename arg_traits<Ctor>::const_param arg
00062         ) = 0;
00063         virtual value_t put(typename arg_traits<K>::const_param key, value_t val) = 0;
00064     
00065         virtual void invalidate(typename arg_traits<K>::const_param key) = 0;
00066 
00067         virtual ~CacheInterface() {
00068         }
00069 };
00070 
00071 template<typename K // key
00072     , typename V    // value
00073     , typename Ctor // ctor for value
00074     , typename E = LeastRecentlyUsedExpirationPolicy
00075     , class TM = DefaultThreadedModel
00076     , template <typename> class Allocator = std::allocator >
00077 class Cache;
00078 
00079 template<typename K, typename V, typename Ctor, typename E, class TM, template<typename> class Allocator>
00080 std::ostream& operator<<(std::ostream&, const Cache<K, V, Ctor, E, TM, Allocator>& rho);
00081 
00082 template<typename K // key
00083     , typename V    // value
00084     , typename Ctor // ctor for value
00085     , typename E
00086     , class TM
00087     , template <typename> class Allocator>
00088 class Cache: public CacheInterface<K, V, Ctor, E, TM, Allocator> {
00089         typedef CacheInterface<K, V, Ctor, E, TM, Allocator> super;
00090     public:
00091         using super::value_t;
00092         explicit Cache(
00093               const unsigned int maxsize = std::numeric_limits<unsigned int>::max()
00094             , const unsigned int expirecnt = 0
00095         );
00096         virtual ~Cache() {};
00097 
00098         // miss if return.isNull() is true;
00099         virtual typename super::value_t get(typename arg_traits<K>::const_param key);
00100         virtual typename super::value_t get(
00101               typename arg_traits<K>::const_param key
00102             , typename arg_traits<Ctor>::const_param arg
00103         );
00104         virtual typename super::value_t put(
00105               typename arg_traits<K>::const_param key
00106             , typename super::value_t val
00107         );
00108         virtual void invalidate(
00109               typename arg_traits<K>::const_param key
00110         ); 
00111     protected:
00112         typedef typename TM::FastLock _lock_t;
00113         typedef std::pair<E, typename super::value_t> _entry_t;
00114         typedef std::pair<const K, _entry_t> _map_entry_t;
00115         typedef std::map<K, _entry_t, std::greater<K>, Allocator<_map_entry_t> > _map_t;
00116 
00117         inline void expire(typename _map_t::iterator hit);
00118         inline void _make_space_for_one();
00119         bool expire_invalid(typename _map_t::iterator hit);
00120         bool expire_invalid();
00121         inline bool full() const;
00122 
00123         _map_t _map;    
00124         mutable _lock_t _lk;
00125     
00126     private:
00127         const unsigned int _maxsize;
00128         const unsigned int _expirecnt;
00129 
00130     friend
00131         std::ostream& operator<< <>(std::ostream&, const Cache<K, V, Ctor, E, TM, Allocator>& rho);
00132 
00133     // hidden stuff
00134         Cache(const Cache&); // c-ctor
00135         Cache& operator=(const Cache&); // assignment
00136 };
00137 
00138 
00139 template<typename K // key
00140     , typename V    // value
00141     , typename Ctor // ctor for value
00142     , typename E = LeastRecentlyUsedExpirationPolicy
00143     , class TM = DefaultThreadedModel
00144     , template <typename> class Allocator = std::allocator >
00145 class NopCache: public CacheInterface<K, V, Ctor, E, TM, Allocator> {
00146         typedef CacheInterface<K, V, Ctor, E, TM, Allocator> super;
00147     public:
00148         explicit NopCache(
00149               const unsigned int maxsize = 0
00150             , const unsigned int expirecnt = 0
00151         ) {
00152         }
00153         virtual ~NopCache() {};
00154 
00155         typedef typename super::value_t value_t;
00156 
00157         // miss if return.isNull() is true;
00158         virtual typename super::value_t get(typename arg_traits<K>::const_param key) {
00159             // always misses
00160             return value_t();
00161         }
00162         virtual typename super::value_t get(
00163               typename arg_traits<K>::const_param key
00164             , typename arg_traits<Ctor>::const_param arg
00165         ) {
00166             return value_t(arg());
00167         }
00168 
00169         virtual typename super::value_t put(
00170               typename arg_traits<K>::const_param key
00171             , typename super::value_t val
00172         ) {
00173             return val;
00174         }
00175 
00176         virtual void invalidate(
00177               typename arg_traits<K>::const_param key
00178         ) {
00179         }
00180     private:
00181     // hidden stuff
00182         NopCache(const NopCache&); // c-ctor
00183         NopCache& operator=(const NopCache&); // assignment
00184 };
00185 
00186 }// namespace fatalmind
00187 
00188 #endif

Generated on Mon Nov 9 16:21:24 2009 for ResourcePool by  doxygen 1.5.3