Mercurial > hg > orthanc
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 } |