Main Page   Class Hierarchy   Compound List   File List   Compound Members   Related Pages  

Cache.h

00001 /*
00002  * Cache
00003  *
00004  * Copyright (C) 2001 Barnaby Gray <barnaby@beedesign.co.uk>
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
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    * This class will cache an id to an object, it's templated
00034    * since it'll be useful in several places with different sorts of
00035    * ids and objects.
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      * list for storing them in order to timeout
00067      * a hash could be used as well, but efficiency isn't really an
00068      * issue - there shouldn't be more than 10 items in here at any one point
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       // might want to override to add signalling on expiring of items
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); // default timeout
00224   }
00225 
00226   template <typename Key, typename Value>
00227   Cache<Key,Value>::~Cache() {
00228     removeAll();
00229   }
00230  
00231 }
00232 
00233 #endif

Generated on Tue Jan 15 12:24:34 2002 for libicq2000 by doxygen1.2.12 written by Dimitri van Heesch, © 1997-2001