00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef CACHE_H
00023 #define CACHE_H
00024
00025 #include <list>
00026 #include <time.h>
00027
00028 namespace ICQ2000 {
00029
00030
00031
00032
00033
00034
00035
00036 template <typename Key, typename Value> class CacheItem {
00037 protected:
00038 unsigned int m_timeout;
00039 time_t m_timestamp;
00040 Key m_key;
00041 Value m_value;
00042
00043 public:
00044 CacheItem(const Key &k, const Value &v, unsigned int timeout);
00045
00046 const Key& getKey() const;
00047 Value& getValue();
00048 time_t getTimestamp() const;
00049 time_t getExpiryTime() const;
00050 void setTimestamp(time_t t);
00051 void setTimeout(time_t t);
00052 void refresh();
00053 };
00054
00055 template < typename Key, typename Value >
00056 class Cache {
00057 protected:
00058 typedef typename std::list< CacheItem<Key,Value> >::iterator literator;
00059 typedef typename std::list< CacheItem<Key,Value> >::const_iterator citerator;
00060
00061 unsigned int m_timeout;
00062
00063
00064
00065
00066
00067
00068 std::list< CacheItem<Key,Value> > m_list;
00069
00070 citerator lookup(const Key& k) const {
00071 citerator curr = m_list.begin();
00072 while (curr != m_list.end()) {
00073 if ((*curr).getKey() == k) return curr;
00074 ++curr;
00075 }
00076 return m_list.end();
00077 }
00078
00079 literator lookup(const Key& k) {
00080 literator curr = m_list.begin();
00081 while (curr != m_list.end()) {
00082 if ((*curr).getKey() == k) return curr;
00083 ++curr;
00084 }
00085 return m_list.end();
00086 }
00087
00088 public:
00089 Cache();
00090 virtual ~Cache();
00091
00092 bool exists(const Key &k) const {
00093 citerator i = lookup(k);
00094 return (i != m_list.end());
00095 }
00096
00097 Value& operator[](const Key &k) {
00098 literator i = lookup(k);
00099 if (i == m_list.end()) {
00100 return insert(k, Value());
00101 } else {
00102 return (*i).getValue();
00103 }
00104 }
00105
00106 void remove(const Key &k) {
00107 literator i = lookup(k);
00108 if (i != m_list.end()) removeItem(i);
00109 }
00110
00111 virtual void removeItem(const literator& l) {
00112 m_list.erase(l);
00113 }
00114
00115 virtual void expireItem(const literator& l) {
00116
00117 removeItem(l);
00118 }
00119
00120 void expireAll() {
00121 while (!m_list.empty()) {
00122 expireItem(m_list.begin());
00123 }
00124 }
00125
00126 void removeAll() {
00127 while (!m_list.empty()) {
00128 removeItem(m_list.begin());
00129 }
00130 }
00131
00132 Value& insert(const Key &k, const Value &v) {
00133 CacheItem<Key,Value> t(k,v,m_timeout);
00134 return (*insert(t)).getValue();
00135 }
00136
00137 literator insert(const CacheItem<Key,Value>& t) {
00138 time_t exp_time = t.getExpiryTime();
00139
00140 literator l = m_list.end();
00141 while (l != m_list.begin()) {
00142 --l;
00143 if ( (*l).getExpiryTime() < exp_time ) {
00144 ++l;
00145 break;
00146 }
00147 }
00148 return m_list.insert(l, t);
00149 }
00150
00151 bool empty() const {
00152 return m_list.empty();
00153 }
00154
00155 const Key& front() const {
00156 return m_list.front().getKey();
00157 }
00158
00159 void refresh(const Key &k) {
00160 literator i = lookup(k);
00161 if (i != m_list.end()) {
00162 CacheItem<Key,Value> t(*i);
00163 m_list.erase(i);
00164 insert(t);
00165 }
00166 }
00167
00168 unsigned int getDefaultTimeout() { return m_timeout; }
00169 void setDefaultTimeout(unsigned int s) { m_timeout = s; }
00170
00171 void setTimeout(const Key &k, unsigned int s) {
00172 literator i = lookup(k);
00173 if (i != m_list.end()) {
00174 CacheItem<Key,Value> t(*i);
00175 t.setTimeout(s);
00176 m_list.erase(i);
00177 insert(t);
00178 }
00179 }
00180
00181 void clearoutPoll() {
00182 time_t n = time(NULL);
00183 while (!m_list.empty() && m_list.front().getExpiryTime() < n)
00184 expireItem( m_list.begin() );
00185 }
00186
00187 };
00188
00189 template <typename Key, typename Value>
00190 CacheItem<Key,Value>::CacheItem(const Key &k, const Value &v, unsigned int timeout)
00191 : m_timeout(timeout), m_timestamp(time(NULL)),
00192 m_key(k), m_value(v) { }
00193
00194 template <typename Key, typename Value>
00195 void CacheItem<Key,Value>::setTimestamp(time_t t) { m_timestamp = t; }
00196
00197 template <typename Key, typename Value>
00198 void CacheItem<Key,Value>::setTimeout(time_t t) { m_timeout = t; }
00199
00200 template <typename Key, typename Value>
00201 time_t CacheItem<Key,Value>::getTimestamp() const { return m_timestamp; }
00202
00203 template <typename Key, typename Value>
00204 time_t CacheItem<Key,Value>::getExpiryTime() const { return m_timestamp + m_timeout; }
00205
00206 template <typename Key, typename Value>
00207 void CacheItem<Key,Value>::refresh() { m_timestamp = time(NULL); }
00208
00209 template <typename Key, typename Value>
00210 const Key& CacheItem<Key,Value>::getKey() const {
00211 return m_key;
00212 }
00213
00214 template <typename Key, typename Value>
00215 Value& CacheItem<Key,Value>::getValue() {
00216 return m_value;
00217 }
00218
00219 template <typename Key, typename Value>
00220 Cache<Key,Value>::Cache() {
00221 setDefaultTimeout(60);
00222 }
00223
00224 template <typename Key, typename Value>
00225 Cache<Key,Value>::~Cache() {
00226 removeAll();
00227 }
00228
00229 }
00230
00231 #endif