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