00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef SUPPORT_GENERIC_CACHE_H
00014 #define SUPPORT_GENERIC_CACHE_H
00015
00021 #include <PalmTypes.h>
00022 #include <support/Atom.h>
00023 #include <support/Locker.h>
00024 #include <support/KeyedVector.h>
00025 #include <support/StdIO.h>
00026 #if _SUPPORTS_RTTI
00027 #include <typeinfo>
00028 #endif
00029
00030 #if _SUPPORTS_NAMESPACE
00031 namespace palmos {
00032 namespace support {
00033 #endif
00034
00039 class ITextOutput;
00040
00041
00042
00043 enum {
00044 B_GENERIC_CACHE_SIZE_UNLIMITED = 0
00045 };
00046
00047 enum {
00048 B_GENERIC_CACHE_NEVER_PURGE = 0x00000001,
00049 B_GENERIC_CACHE_DONT_ADD = 0x00000002,
00050 B_GENERIC_CACHE_DONT_PURGE = 0x00000004
00051 };
00052
00053 class SAbstractCache
00054 {
00055 public:
00056 const void* AbstractLookup(const void *key, int32_t flags) const;
00057 status_t AbstractAdd(const void *key, const void *data, int32_t flags);
00058 status_t AbstractRemove(const void *key);
00059 void Dump(const sptr<ITextOutput>& io) const;
00060 protected:
00061 SAbstractCache(ssize_t cacheSize);
00062 virtual ~SAbstractCache();
00063 private:
00064 virtual void PerformPrintItem(const void* data, const sptr<ITextOutput>& io) const = 0;
00065 virtual ssize_t PerformSize(const void* data) const = 0;
00066 virtual uint32_t& PerformEntryAge(const void* entry) const = 0;
00067 virtual const void* PerformEntryData(const void* entry) const = 0;
00068 virtual const SAbstractKeyedVector& Entries() const = 0;
00069 virtual SAbstractKeyedVector& Entries() = 0;
00070 virtual status_t CreateEntry(const void* key, const void* data, uint32_t age) = 0;
00071 inline uint32_t tick() const;
00072 inline ssize_t size_left() const { return m_cacheSize-m_sizeUsed; }
00073 mutable uint32_t m_age;
00074 ssize_t m_cacheSize;
00075 ssize_t m_sizeUsed;
00076 };
00077
00078
00079
00080 template<class KEY, class TYPE>
00081 class SGenericCache : private SAbstractCache
00082 {
00083 public:
00084 inline SGenericCache(ssize_t cacheSize);
00085 virtual inline ~SGenericCache();
00086
00087 inline TYPE Lookup(const KEY& key, int32_t flags = 0) const;
00088 inline status_t Add(const KEY& key, const TYPE& data, int32_t flags = 0);
00089 inline status_t Remove(const KEY& key);
00090 inline void Dump(const sptr<ITextOutput>& io) const;
00091
00092 private:
00093 virtual void PerformPrintItem(const void* data, const sptr<ITextOutput>& io) const;
00094 virtual ssize_t PerformSize(const void* data) const;
00095 virtual uint32_t& PerformEntryAge(const void* entry) const;
00096 virtual const void* PerformEntryData(const void* entry) const;
00097 virtual const SAbstractKeyedVector& Entries() const;
00098 virtual SAbstractKeyedVector& Entries();
00099 virtual status_t CreateEntry(const void* key, const void* data, uint32_t age);
00100 template<class ENTTYPE> struct entry_t {
00101 mutable uint32_t age;
00102 ENTTYPE data;
00103 entry_t() {}
00104 entry_t(const entry_t& from)
00105 : age(from.age),
00106 data(from.data)
00107 {}
00108 };
00109 SKeyedVector<KEY, entry_t<TYPE> > m_entries;
00110 mutable SLocker m_lock;
00111 };
00112
00115
00116
00117
00118 template<class TYPE> inline
00119 ssize_t PGenericCacheSize(const TYPE& data)
00120 {
00121 return data->Size();
00122 }
00123
00124
00125 template<class TYPE> inline
00126 const sptr<ITextOutput>& PGenericCachePrintItem(const sptr<ITextOutput>& io, const TYPE& data)
00127 {
00128 #if _SUPPORTS_RTTI
00129 io << &data << " (" << typeid(data).name() << ") size=" << PGenericCacheSize(data);
00130 #else
00131 io << &data << " size=" << PGenericCacheSize(data);
00132 #endif
00133 return io;
00134 }
00135
00136
00137
00138 template<class KEY, class TYPE> inline
00139 SGenericCache<KEY, TYPE>::SGenericCache(ssize_t cacheSize)
00140 : SAbstractCache(cacheSize), m_lock("SGenericCache::m_lock")
00141 {
00142 }
00143
00144 template<class KEY, class TYPE> inline
00145 SGenericCache<KEY, TYPE>::~SGenericCache()
00146 {
00147 }
00148
00149
00150
00151 template<class KEY, class TYPE> inline
00152 void SGenericCache<KEY, TYPE>::Dump(const sptr<ITextOutput>& io) const
00153 {
00154 SLocker::Autolock _l(m_lock);
00155 SAbstractCache::Dump(io);
00156 }
00157
00158 template<class KEY, class TYPE> inline
00159 TYPE SGenericCache<KEY, TYPE>::Lookup(const KEY& key, int32_t flags) const
00160 {
00161 SLocker::Autolock _l(m_lock);
00162 return *(static_cast< const TYPE* >( AbstractLookup(&key, flags) ));
00163 }
00164
00165 template<class KEY, class TYPE> inline
00166 status_t SGenericCache<KEY, TYPE>::Add(const KEY& key, const TYPE& data, int32_t flags)
00167 {
00168 SLocker::Autolock _l(m_lock);
00169 return AbstractAdd(&key, &data, flags);
00170 }
00171
00172 template<class KEY, class TYPE> inline
00173 status_t SGenericCache<KEY, TYPE>::Remove(const KEY& key)
00174 {
00175 SLocker::Autolock _l(m_lock);
00176 return AbstractRemove(&key);
00177 }
00178
00179
00180
00181 template<class KEY, class TYPE> inline
00182 void SGenericCache<KEY, TYPE>::PerformPrintItem(const void* data, const sptr<ITextOutput>& io) const
00183 {
00184 PGenericCachePrintItem(io, *static_cast< const TYPE* >(data));
00185 }
00186
00187 template<class KEY, class TYPE> inline
00188 ssize_t SGenericCache<KEY, TYPE>::PerformSize(const void *data) const
00189 {
00190 return PGenericCacheSize(*static_cast< const TYPE* >(data));
00191 }
00192
00193 template<class KEY, class TYPE> inline
00194 uint32_t& SGenericCache<KEY, TYPE>::PerformEntryAge(const void* entry) const
00195 {
00196 return static_cast<const entry_t<TYPE>*>(entry)->age;
00197 }
00198
00199 template<class KEY, class TYPE> inline
00200 const void* SGenericCache<KEY, TYPE>::PerformEntryData(const void* entry) const
00201 {
00202 return &(static_cast<const entry_t<TYPE>*>(entry)->data);
00203 }
00204
00205
00206
00207 template<class KEY, class TYPE> inline
00208 const SAbstractKeyedVector& SGenericCache<KEY, TYPE>::Entries() const
00209 {
00210 return *(static_cast<const SAbstractKeyedVector*>((const void*)&m_entries));
00211 }
00212
00213 template<class KEY, class TYPE> inline
00214 SAbstractKeyedVector& SGenericCache<KEY, TYPE>::Entries()
00215 {
00216 return *(static_cast<SAbstractKeyedVector*>((void*)&m_entries));
00217 }
00218
00219 template<class KEY, class TYPE> inline
00220 status_t SGenericCache<KEY, TYPE>::CreateEntry(const void* key, const void* data, uint32_t age)
00221 {
00222 entry_t<TYPE> entry;
00223 entry.age = age;
00224 entry.data = *(static_cast< const TYPE* >(data));
00225 return m_entries.AddItem(*(static_cast<const KEY*>(key)), entry);
00226 }
00227
00228
00229
00230 #if _SUPPORTS_NAMESPACE
00231 } }
00232 #endif
00233
00234 #endif