00001
00002
00003
00004
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
00050 , typename V
00051 , typename Ctor
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
00072 , typename V
00073 , typename Ctor
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
00083 , typename V
00084 , typename Ctor
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
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
00134 Cache(const Cache&);
00135 Cache& operator=(const Cache&);
00136 };
00137
00138
00139 template<typename K
00140 , typename V
00141 , typename Ctor
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
00158 virtual typename super::value_t get(typename arg_traits<K>::const_param key) {
00159
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
00182 NopCache(const NopCache&);
00183 NopCache& operator=(const NopCache&);
00184 };
00185
00186 }
00187
00188 #endif