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 }