00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #ifndef __OASYS_DURABLE_STORE_INTERNAL_HEADER__
00041 #error DurableObjectCache.h must only be included from within DurableStore.h
00042 #endif
00043
00044 template <typename _DataType>
00045 class DurableObjectCache : public Logger {
00046 public:
00047 enum CachePolicy_t {
00048 CAP_BY_SIZE,
00049 CAP_BY_COUNT
00050 };
00051
00055 DurableObjectCache(const char* logpath,
00056 size_t capacity,
00057 CachePolicy_t policy = CAP_BY_SIZE);
00058
00062 ~DurableObjectCache();
00063
00069 int put(const SerializableObject& key, const _DataType* data, int flags);
00070
00074 int get(const SerializableObject& key, _DataType** data);
00075
00079 bool is_live(const SerializableObject& key);
00080
00084 int release(const SerializableObject& key, const _DataType* data);
00085
00089 int del(const SerializableObject& key);
00090
00094 int remove(const SerializableObject& key, const _DataType* data);
00095
00101 size_t flush();
00102
00105 size_t size() { return size_; }
00106 size_t count() { return cache_.size(); }
00107 size_t live() { return cache_.size() - lru_.size(); }
00108 int hits() { return hits_; }
00109 int misses() { return misses_; }
00110 int evictions() { return evictions_; }
00112
00116 void reset_stats()
00117 {
00118 hits_ = 0;
00119 misses_ = 0;
00120 evictions_ = 0;
00121 }
00122
00123 protected:
00127 void get_cache_key(std::string* cache_key, const SerializableObject& key);
00128
00133 bool is_over_capacity(size_t size);
00134
00138 void evict_last();
00139
00144 typedef LRUList<std::string> CacheLRUList;
00145
00149 struct CacheElement {
00150 CacheElement(const _DataType* object, size_t object_size,
00151 bool live, CacheLRUList::iterator lru_iter)
00152
00153 : object_(object),
00154 object_size_(object_size),
00155 live_(live),
00156 lru_iter_(lru_iter) {}
00157
00158 const _DataType* object_;
00159 size_t object_size_;
00160 bool live_;
00161 CacheLRUList::iterator lru_iter_;
00162 };
00163
00167 class CacheTable : public StringHashMap<CacheElement*> {};
00168 typedef std::pair<typename CacheTable::iterator, bool> CacheInsertRet;
00169
00170 size_t size_;
00171 size_t capacity_;
00172 int hits_;
00173 int misses_;
00174 int evictions_;
00175 CacheLRUList lru_;
00176 CacheTable cache_;
00177 SpinLock* lock_;
00178 CachePolicy_t policy_;
00179
00180 public:
00185 class iterator {
00186 public:
00187 iterator() {}
00188 iterator(const typename CacheTable::iterator& i) : iter_(i) {}
00189
00190 const std::string& key() { return iter_->first; }
00191 bool live() { return iter_->second->live_; }
00192 const _DataType* object() { return iter_->second->object_; }
00193 size_t object_size() { return iter_->second->object_size_; }
00194
00195 const iterator& operator++()
00196 {
00197 iter_++;
00198 return *this;
00199 }
00200
00201 bool operator==(const iterator& other)
00202 {
00203 return iter_ == other.iter_;
00204 }
00205
00206 bool operator!=(const iterator& other)
00207 {
00208 return iter_ != other.iter_;
00209 }
00210
00211 protected:
00212 friend class DurableObjectCache;
00213 typename CacheTable::iterator iter_;
00214 };
00215
00217 iterator begin()
00218 {
00219 return iterator(cache_.begin());
00220 }
00221
00223 iterator end()
00224 {
00225 return iterator(cache_.end());
00226 }
00227
00228 };