comparison Core/MultiThreading/CacheIndex.h @ 283:c9977db00e1d

caching
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 12 Dec 2012 15:32:15 +0100
parents 915ed24547ea
children
comparison
equal deleted inserted replaced
282:915ed24547ea 283:c9977db00e1d
33 #pragma once 33 #pragma once
34 34
35 #include <list> 35 #include <list>
36 #include <map> 36 #include <map>
37 #include <boost/noncopyable.hpp> 37 #include <boost/noncopyable.hpp>
38 #include <cassert>
39
40 #include "../OrthancException.h"
38 41
39 namespace Orthanc 42 namespace Orthanc
40 { 43 {
41 class NullType 44 class NullType
42 { 45 {
112 bool Contains(T id) const 115 bool Contains(T id) const
113 { 116 {
114 return index_.find(id) != index_.end(); 117 return index_.find(id) != index_.end();
115 } 118 }
116 119
120 bool Contains(T id, Payload& payload) const
121 {
122 typename Index::const_iterator it = index_.find(id);
123 if (it == index_.end())
124 {
125 return false;
126 }
127 else
128 {
129 payload = it->second->second;
130 return true;
131 }
132 }
133
134 /**
135 * Return the number of elements in the cache.
136 * \return The number of elements.
137 **/
138 size_t GetSize() const
139 {
140 assert(index_.size() == queue_.size());
141 return queue_.size();
142 }
143
117 /** 144 /**
118 * Check whether the cache index is empty. 145 * Check whether the cache index is empty.
119 * \return \c true iff the cache is empty. 146 * \return \c true iff the cache is empty.
120 **/ 147 **/
121 bool IsEmpty() const 148 bool IsEmpty() const
122 { 149 {
123 return index_.empty(); 150 return index_.empty();
124 } 151 }
125 }; 152 };
153
154
155
156
157 /******************************************************************
158 ** Implementation of the template
159 ******************************************************************/
160
161 template <typename T, typename Payload>
162 void CacheIndex<T, Payload>::CheckInvariants() const
163 {
164 #ifndef NDEBUG
165 assert(index_.size() == queue_.size());
166
167 for (typename Index::const_iterator
168 it = index_.begin(); it != index_.end(); it++)
169 {
170 assert(it->second != queue_.end());
171 assert(it->second->first == it->first);
172 }
173 #endif
174 }
175
176
177 template <typename T, typename Payload>
178 void CacheIndex<T, Payload>::Add(T id, Payload payload)
179 {
180 if (Contains(id))
181 {
182 throw OrthancException(ErrorCode_BadSequenceOfCalls);
183 }
184
185 queue_.push_front(std::make_pair(id, payload));
186 index_[id] = queue_.begin();
187
188 CheckInvariants();
189 }
190
191
192 template <typename T, typename Payload>
193 void CacheIndex<T, Payload>::TagAsMostRecent(T id)
194 {
195 if (!Contains(id))
196 {
197 throw OrthancException(ErrorCode_InexistentItem);
198 }
199
200 typename Index::iterator it = index_.find(id);
201 assert(it != index_.end());
202
203 std::pair<T, Payload> item = *(it->second);
204
205 queue_.erase(it->second);
206 queue_.push_front(item);
207 index_[id] = queue_.begin();
208
209 CheckInvariants();
210 }
211
212
213 template <typename T, typename Payload>
214 Payload CacheIndex<T, Payload>::Invalidate(T id)
215 {
216 if (!Contains(id))
217 {
218 throw OrthancException(ErrorCode_InexistentItem);
219 }
220
221 typename Index::iterator it = index_.find(id);
222 assert(it != index_.end());
223
224 Payload payload = it->second->second;
225 queue_.erase(it->second);
226 index_.erase(it);
227
228 CheckInvariants();
229 return payload;
230 }
231
232
233 template <typename T, typename Payload>
234 T CacheIndex<T, Payload>::RemoveOldest(Payload& payload)
235 {
236 if (IsEmpty())
237 {
238 throw OrthancException(ErrorCode_BadSequenceOfCalls);
239 }
240
241 std::pair<T, Payload> item = queue_.back();
242 T oldest = item.first;
243 payload = item.second;
244
245 queue_.pop_back();
246 assert(index_.find(oldest) != index_.end());
247 index_.erase(oldest);
248
249 CheckInvariants();
250
251 return oldest;
252 }
126 } 253 }