00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef __OASYS_DURABLE_STORE_INTERNAL_HEADER__
00020 #error DurableObjectCache.h must only be included from within DurableStore.h
00021 #endif
00022
00023 #include "../util/StringBuffer.h"
00024
00025 template <typename _DataType>
00026 class DurableObjectCache : public Logger {
00027 public:
00028 enum CachePolicy_t {
00029 CAP_BY_SIZE,
00030 CAP_BY_COUNT
00031 };
00032
00036 DurableObjectCache(const char* logpath,
00037 size_t capacity,
00038 CachePolicy_t policy = CAP_BY_SIZE);
00039
00043 ~DurableObjectCache();
00044
00050 int put(const SerializableObject& key, const _DataType* data, int flags);
00051
00055 int get(const SerializableObject& key, _DataType** data);
00056
00060 bool is_live(const SerializableObject& key);
00061
00065 int release(const SerializableObject& key, const _DataType* data);
00066
00070 int del(const SerializableObject& key);
00071
00075 int remove(const SerializableObject& key, const _DataType* data);
00076
00082 size_t flush();
00083
00086 size_t size() const { return size_; }
00087 size_t count() const { return cache_.size(); }
00088 size_t live() const { return cache_.size() - lru_.size(); }
00089 int hits() const { return hits_; }
00090 int misses() const { return misses_; }
00091 int evictions() const { return evictions_; }
00093
00097 void get_stats(StringBuffer* buf);
00098
00102 void reset_stats()
00103 {
00104 hits_ = 0;
00105 misses_ = 0;
00106 evictions_ = 0;
00107 }
00108
00109 protected:
00113 void get_cache_key(std::string* cache_key, const SerializableObject& key);
00114
00119 bool is_over_capacity(size_t size);
00120
00124 void evict_last();
00125
00130 typedef LRUList<std::string> CacheLRUList;
00131
00135 struct CacheElement {
00136 CacheElement(const _DataType* object, size_t object_size,
00137 bool live, CacheLRUList::iterator lru_iter)
00138
00139 : object_(object),
00140 object_size_(object_size),
00141 live_(live),
00142 lru_iter_(lru_iter) {}
00143
00144 const _DataType* object_;
00145 size_t object_size_;
00146 bool live_;
00147 CacheLRUList::iterator lru_iter_;
00148 };
00149
00153 class CacheTable : public StringHashMap<CacheElement*> {};
00154 typedef std::pair<typename CacheTable::iterator, bool> CacheInsertRet;
00155
00156 size_t size_;
00157 size_t capacity_;
00158 int hits_;
00159 int misses_;
00160 int evictions_;
00161 CacheLRUList lru_;
00162 CacheTable cache_;
00163 SpinLock* lock_;
00164 CachePolicy_t policy_;
00165
00166 public:
00171 class iterator {
00172 public:
00173 iterator() {}
00174 iterator(const typename CacheTable::iterator& i) : iter_(i) {}
00175
00176 const std::string& key() { return iter_->first; }
00177 bool live() { return iter_->second->live_; }
00178 const _DataType* object() { return iter_->second->object_; }
00179 size_t object_size() { return iter_->second->object_size_; }
00180
00181 const iterator& operator++()
00182 {
00183 iter_++;
00184 return *this;
00185 }
00186
00187 bool operator==(const iterator& other)
00188 {
00189 return iter_ == other.iter_;
00190 }
00191
00192 bool operator!=(const iterator& other)
00193 {
00194 return iter_ != other.iter_;
00195 }
00196
00197 protected:
00198 friend class DurableObjectCache;
00199 typename CacheTable::iterator iter_;
00200 };
00201
00203 iterator begin()
00204 {
00205 return iterator(cache_.begin());
00206 }
00207
00209 iterator end()
00210 {
00211 return iterator(cache_.end());
00212 }
00213
00214 };