Mercurial > hg > orthanc
comparison UnitTests/MemoryCache.cpp @ 509:e7841864c97c
StableResourcesMonitor
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 16 Aug 2013 14:23:54 +0200 |
parents | c4122c3a47c1 |
children | 3b735fdf320b |
comparison
equal
deleted
inserted
replaced
507:c4122c3a47c1 | 509:e7841864c97c |
---|---|
15 r.Add("d"); | 15 r.Add("d"); |
16 r.Add("a"); | 16 r.Add("a"); |
17 r.Add("c"); | 17 r.Add("c"); |
18 r.Add("b"); | 18 r.Add("b"); |
19 | 19 |
20 r.TagAsMostRecent("a"); | 20 r.MakeMostRecent("a"); |
21 r.TagAsMostRecent("d"); | 21 r.MakeMostRecent("d"); |
22 r.TagAsMostRecent("b"); | 22 r.MakeMostRecent("b"); |
23 r.TagAsMostRecent("c"); | 23 r.MakeMostRecent("c"); |
24 r.TagAsMostRecent("d"); | 24 r.MakeMostRecent("d"); |
25 r.TagAsMostRecent("c"); | 25 r.MakeMostRecent("c"); |
26 | 26 |
27 ASSERT_EQ("a", r.GetOldest()); | 27 ASSERT_EQ("a", r.GetOldest()); |
28 ASSERT_EQ("a", r.RemoveOldest()); | 28 ASSERT_EQ("a", r.RemoveOldest()); |
29 ASSERT_EQ("b", r.GetOldest()); | 29 ASSERT_EQ("b", r.GetOldest()); |
30 ASSERT_EQ("b", r.RemoveOldest()); | 30 ASSERT_EQ("b", r.RemoveOldest()); |
47 r.Add("a", 420); | 47 r.Add("a", 420); |
48 r.Add("b", 421); | 48 r.Add("b", 421); |
49 r.Add("c", 422); | 49 r.Add("c", 422); |
50 r.Add("d", 423); | 50 r.Add("d", 423); |
51 | 51 |
52 r.TagAsMostRecent("a"); | 52 r.MakeMostRecent("a"); |
53 r.TagAsMostRecent("d"); | 53 r.MakeMostRecent("d"); |
54 r.TagAsMostRecent("b"); | 54 r.MakeMostRecent("b"); |
55 r.TagAsMostRecent("c"); | 55 r.MakeMostRecent("c"); |
56 r.TagAsMostRecent("d"); | 56 r.MakeMostRecent("d"); |
57 r.TagAsMostRecent("c"); | 57 r.MakeMostRecent("c"); |
58 | 58 |
59 ASSERT_TRUE(r.Contains("b")); | 59 ASSERT_TRUE(r.Contains("b")); |
60 ASSERT_EQ(421, r.Invalidate("b")); | 60 ASSERT_EQ(421, r.Invalidate("b")); |
61 ASSERT_FALSE(r.Contains("b")); | 61 ASSERT_FALSE(r.Contains("b")); |
62 | 62 |
74 ASSERT_EQ("d", r.RemoveOldest(p)); ASSERT_EQ(423, p); | 74 ASSERT_EQ("d", r.RemoveOldest(p)); ASSERT_EQ(423, p); |
75 | 75 |
76 ASSERT_EQ("c", r.GetOldest()); | 76 ASSERT_EQ("c", r.GetOldest()); |
77 ASSERT_EQ(422, r.GetOldestPayload()); | 77 ASSERT_EQ(422, r.GetOldestPayload()); |
78 ASSERT_EQ("c", r.RemoveOldest(p)); ASSERT_EQ(422, p); | 78 ASSERT_EQ("c", r.RemoveOldest(p)); ASSERT_EQ(422, p); |
79 | |
80 ASSERT_TRUE(r.IsEmpty()); | |
81 } | |
82 | |
83 | |
84 TEST(LRU, PayloadUpdate) | |
85 { | |
86 Orthanc::LeastRecentlyUsedIndex<std::string, int> r; | |
87 | |
88 r.Add("a", 420); | |
89 r.Add("b", 421); | |
90 r.Add("d", 423); | |
91 | |
92 r.MakeMostRecent("a", 424); | |
93 r.MakeMostRecent("d", 421); | |
94 | |
95 ASSERT_EQ("b", r.GetOldest()); | |
96 ASSERT_EQ(421, r.GetOldestPayload()); | |
97 r.RemoveOldest(); | |
98 | |
99 ASSERT_EQ("a", r.GetOldest()); | |
100 ASSERT_EQ(424, r.GetOldestPayload()); | |
101 r.RemoveOldest(); | |
102 | |
103 ASSERT_EQ("d", r.GetOldest()); | |
104 ASSERT_EQ(421, r.GetOldestPayload()); | |
105 r.RemoveOldest(); | |
106 | |
107 ASSERT_TRUE(r.IsEmpty()); | |
108 } | |
109 | |
110 | |
111 | |
112 TEST(LRU, PayloadUpdateBis) | |
113 { | |
114 Orthanc::LeastRecentlyUsedIndex<std::string, int> r; | |
115 | |
116 r.AddOrMakeMostRecent("a", 420); | |
117 r.AddOrMakeMostRecent("b", 421); | |
118 r.AddOrMakeMostRecent("d", 423); | |
119 r.AddOrMakeMostRecent("a", 424); | |
120 r.AddOrMakeMostRecent("d", 421); | |
121 | |
122 ASSERT_EQ("b", r.GetOldest()); | |
123 ASSERT_EQ(421, r.GetOldestPayload()); | |
124 r.RemoveOldest(); | |
125 | |
126 ASSERT_EQ("a", r.GetOldest()); | |
127 ASSERT_EQ(424, r.GetOldestPayload()); | |
128 r.RemoveOldest(); | |
129 | |
130 ASSERT_EQ("d", r.GetOldest()); | |
131 ASSERT_EQ(421, r.GetOldestPayload()); | |
132 r.RemoveOldest(); | |
79 | 133 |
80 ASSERT_TRUE(r.IsEmpty()); | 134 ASSERT_TRUE(r.IsEmpty()); |
81 } | 135 } |
82 | 136 |
83 | 137 |
139 // Closing the cache: 47, 44, 42 are successively removed | 193 // Closing the cache: 47, 44, 42 are successively removed |
140 } | 194 } |
141 | 195 |
142 ASSERT_EQ("45 42 43 47 44 42 ", provider.log_); | 196 ASSERT_EQ("45 42 43 47 44 42 ", provider.log_); |
143 } | 197 } |
198 | |
199 | |
200 #include "../OrthancServer/ServerEnumerations.h" | |
201 | |
202 namespace | |
203 { | |
204 struct Payload | |
205 { | |
206 Orthanc::ResourceType type_; | |
207 boost::posix_time::ptime time_; | |
208 | |
209 Payload() : type_(Orthanc::ResourceType_Instance) | |
210 { | |
211 } | |
212 | |
213 Payload(Orthanc::ResourceType type) : type_(type) | |
214 { | |
215 time_ = boost::posix_time::second_clock::local_time(); | |
216 } | |
217 | |
218 unsigned int GetAge() const | |
219 { | |
220 return (boost::posix_time::second_clock::local_time() - time_).total_seconds(); | |
221 } | |
222 }; | |
223 | |
224 | |
225 class StableResourcesMonitor | |
226 { | |
227 private: | |
228 bool done_; | |
229 boost::mutex mutex_; | |
230 unsigned int stableTimeout_; | |
231 Orthanc::LeastRecentlyUsedIndex<std::string, Payload> unstableResources_; | |
232 boost::thread thread_; | |
233 | |
234 static void Thread(StableResourcesMonitor* that) | |
235 { | |
236 static const unsigned int SLEEP = 1; // Check for stable resources each second | |
237 | |
238 while (!that->done_) | |
239 { | |
240 boost::this_thread::sleep(boost::posix_time::seconds(SLEEP)); | |
241 | |
242 boost::mutex::scoped_lock lock(that->mutex_); | |
243 while (!that->unstableResources_.IsEmpty() && | |
244 that->unstableResources_.GetOldestPayload().GetAge() > that->stableTimeout_) | |
245 { | |
246 // This DICOM resource has not received any new instance for | |
247 // some time. It can be considered as stable. | |
248 | |
249 Payload payload; | |
250 std::string id = that->unstableResources_.RemoveOldest(payload); | |
251 | |
252 LOG(INFO) << "Stable resource: " << id << " (type " << payload.type_ << ")"; | |
253 } | |
254 } | |
255 | |
256 LOG(INFO) << "Closing the monitor for stable resources"; | |
257 } | |
258 | |
259 public: | |
260 StableResourcesMonitor(unsigned int stableTimeout) | |
261 { | |
262 done_ = false; | |
263 stableTimeout_ = stableTimeout; | |
264 thread_ = boost::thread(Thread, this); | |
265 } | |
266 | |
267 ~StableResourcesMonitor() | |
268 { | |
269 done_ = true; | |
270 | |
271 if (thread_.joinable()) | |
272 { | |
273 thread_.join(); | |
274 } | |
275 } | |
276 | |
277 void ResourceUpdated(const std::string& id, | |
278 Orthanc::ResourceType type) | |
279 { | |
280 assert(type == Orthanc::ResourceType_Patient || | |
281 type == Orthanc::ResourceType_Study || | |
282 type == Orthanc::ResourceType_Series); | |
283 | |
284 boost::mutex::scoped_lock lock(mutex_); | |
285 unstableResources_.AddOrMakeMostRecent(id, type); | |
286 } | |
287 }; | |
288 } | |
289 | |
290 TEST(LRU, Hello) | |
291 { | |
292 StableResourcesMonitor m(5); | |
293 boost::this_thread::sleep(boost::posix_time::seconds(1)); | |
294 m.ResourceUpdated("Hello", Orthanc::ResourceType_Study); | |
295 m.ResourceUpdated("World", Orthanc::ResourceType_Series); | |
296 boost::this_thread::sleep(boost::posix_time::seconds(2)); | |
297 m.ResourceUpdated("Hello", Orthanc::ResourceType_Study); | |
298 boost::this_thread::sleep(boost::posix_time::seconds(10)); | |
299 } |