Mercurial > hg > orthanc-stone
comparison UnitTestsSources/TestStrategy.cpp @ 697:14557e550920
BasicFetchingStrategy
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Sun, 19 May 2019 13:21:22 +0200 |
parents | 7bf91c4ebd65 |
children | 51976977d2d3 |
comparison
equal
deleted
inserted
replaced
696:75deb0acd632 | 697:14557e550920 |
---|---|
127 | 127 |
128 | 128 |
129 class BasicFetchingStrategy : public IFetchingStrategy | 129 class BasicFetchingStrategy : public IFetchingStrategy |
130 { | 130 { |
131 private: | 131 private: |
132 struct Item | 132 class ContentItem |
133 { | 133 { |
134 private: | |
134 unsigned int item_; | 135 unsigned int item_; |
135 unsigned int quality_; | 136 unsigned int quality_; |
137 | |
138 public: | |
139 ContentItem(unsigned int item, | |
140 unsigned int quality) : | |
141 item_(item), | |
142 quality_(quality) | |
143 { | |
144 } | |
145 | |
146 unsigned int GetItem() const | |
147 { | |
148 return item_; | |
149 } | |
150 | |
151 unsigned int GetQuality() const | |
152 { | |
153 return quality_; | |
154 } | |
136 }; | 155 }; |
137 | 156 |
138 std::auto_ptr<IFetchingItemsSorter> sorter_; | 157 std::auto_ptr<IFetchingItemsSorter> sorter_; |
139 std::vector<unsigned int> nextQuality_; | 158 std::vector<unsigned int> nextQuality_; |
140 unsigned int maxQuality_; | 159 unsigned int maxQuality_; |
141 std::vector<Item> content_; | 160 std::vector<ContentItem> content_; |
142 size_t currentItem_; | 161 size_t position_; |
162 unsigned int blockSize_; | |
163 | |
164 void Schedule(unsigned int item, | |
165 unsigned int quality) | |
166 { | |
167 assert(item < GetItemsCount() && | |
168 quality <= maxQuality_); | |
169 | |
170 if (nextQuality_[item] <= quality) | |
171 { | |
172 content_.push_back(ContentItem(item, quality)); | |
173 } | |
174 } | |
143 | 175 |
144 public: | 176 public: |
145 BasicFetchingStrategy(IFetchingItemsSorter* sorter, // Takes ownership | 177 BasicFetchingStrategy(IFetchingItemsSorter* sorter, // Takes ownership |
146 unsigned int maxQuality) : | 178 unsigned int maxQuality) : |
147 sorter_(sorter), | 179 sorter_(sorter), |
148 nextQuality_(sorter_->GetItemsCount(), 0), | |
149 maxQuality_(maxQuality), | 180 maxQuality_(maxQuality), |
150 currentItem_(0) | 181 position_(0), |
182 blockSize_(2) | |
151 { | 183 { |
152 if (sorter == NULL) | 184 if (sorter == NULL) |
153 { | 185 { |
154 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); | 186 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); |
155 } | 187 } |
188 | |
189 nextQuality_.resize(sorter_->GetItemsCount(), 0), // Does not change along calls to "SetCurrent()" | |
156 | 190 |
157 SetCurrent(0); | 191 SetCurrent(0); |
158 } | 192 } |
159 | 193 |
160 virtual unsigned int GetItemsCount() const | 194 virtual unsigned int GetItemsCount() const |
165 virtual unsigned int GetMaxQuality() const | 199 virtual unsigned int GetMaxQuality() const |
166 { | 200 { |
167 return maxQuality_; | 201 return maxQuality_; |
168 } | 202 } |
169 | 203 |
204 void SetBlockSize(unsigned int size) | |
205 { | |
206 if (size <= 0) | |
207 { | |
208 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
209 } | |
210 | |
211 blockSize_ = size; | |
212 } | |
213 | |
170 virtual bool GetNext(unsigned int& item, | 214 virtual bool GetNext(unsigned int& item, |
171 unsigned int& quality) | 215 unsigned int& quality) |
172 { | 216 { |
173 if (currentItem_ >= content_.size()) | 217 if (position_ >= content_.size()) |
174 { | 218 { |
175 return false; | 219 return false; |
176 } | 220 } |
177 else | 221 else |
178 { | 222 { |
179 item = content_[currentItem_].item_; | 223 item = content_[position_].GetItem(); |
180 quality = content_[currentItem_].quality_; | 224 quality = content_[position_].GetQuality(); |
181 | 225 |
182 assert(nextQuality_[item] <= quality); | 226 assert(nextQuality_[item] <= quality); |
183 nextQuality_[item] = quality + 1; | 227 nextQuality_[item] = quality + 1; |
184 | 228 |
229 position_ ++; | |
185 return true; | 230 return true; |
186 } | 231 } |
187 } | 232 } |
188 | 233 |
189 virtual void SetCurrent(unsigned int item) | 234 virtual void SetCurrent(unsigned int item) |
190 { | 235 { |
236 // TODO - This function is O(N) complexity where "N" is the | |
237 // number of items times the max quality. Could use a LRU index. | |
238 | |
239 position_ = 0; | |
240 | |
191 std::vector<unsigned int> v; | 241 std::vector<unsigned int> v; |
192 sorter_->Sort(v, item); | 242 sorter_->Sort(v, item); |
193 | 243 |
194 assert(v.size() == GetItemsCount()); | 244 assert(v.size() == GetItemsCount()); |
245 | |
246 if (v.size() == 0) | |
247 { | |
248 return; | |
249 } | |
195 | 250 |
196 content_.clear(); | 251 content_.clear(); |
197 content_.reserve(v.size() * maxQuality_); | 252 content_.reserve(v.size() * maxQuality_); |
198 | 253 |
199 for (unsigned int q = 0; q < maxQuality_; q++) | 254 Schedule(v.front(), maxQuality_); |
200 { | 255 |
201 for (size_t i = 0; i < v.size(); i++) | 256 for (unsigned int q = 0; q <= maxQuality_; q++) |
257 { | |
258 unsigned int start = 1 + q * blockSize_; | |
259 unsigned int end = start + blockSize_; | |
260 | |
261 if (q == maxQuality_ || | |
262 end > v.size()) | |
202 { | 263 { |
203 | 264 end = v.size(); |
265 } | |
266 | |
267 unsigned int a = 0; | |
268 if (maxQuality_ >= q + 1) | |
269 { | |
270 a = maxQuality_ - q - 1; | |
271 } | |
272 | |
273 for (unsigned int j = a; j <= maxQuality_; j++) | |
274 { | |
275 for (unsigned int i = start; i < end; i++) | |
276 { | |
277 Schedule(v[i], j); | |
278 } | |
204 } | 279 } |
205 } | 280 } |
206 } | 281 } |
207 | 282 |
208 // Ask the strategy to re-schedule the item with the lowest | 283 // Ask the strategy to re-schedule the item with the lowest |
215 }; | 290 }; |
216 } | 291 } |
217 | 292 |
218 | 293 |
219 | 294 |
220 TEST(BasicFetchingStrategy, Test) | 295 namespace |
221 { | 296 { |
222 OrthancStone::BasicFetchingStrategy s(new OrthancStone::BasicFetchingItemsSorter(10), 3); | 297 class StrategyTester : public boost::noncopyable |
298 { | |
299 private: | |
300 std::map<unsigned int, unsigned int> qualities_; | |
301 | |
302 public: | |
303 bool IsValidCommand(unsigned int item, | |
304 unsigned int quality) | |
305 { | |
306 if (qualities_.find(item) != qualities_.end() && | |
307 qualities_[item] >= quality) | |
308 { | |
309 return false; | |
310 } | |
311 else | |
312 { | |
313 qualities_[item] = quality; | |
314 return true; | |
315 } | |
316 } | |
317 | |
318 bool HasFinished(OrthancStone::BasicFetchingStrategy& strategy) | |
319 { | |
320 for (unsigned int i = 0; i < strategy.GetItemsCount(); i++) | |
321 { | |
322 if (qualities_.find(i) == qualities_.end() || | |
323 qualities_[i] != strategy.GetMaxQuality()) | |
324 { | |
325 return false; | |
326 } | |
327 } | |
328 | |
329 return true; | |
330 } | |
331 }; | |
332 } | |
333 | |
334 | |
335 TEST(BasicFetchingStrategy, Test1) | |
336 { | |
337 ASSERT_THROW(OrthancStone::BasicFetchingStrategy(NULL, 0), Orthanc::OrthancException); | |
338 ASSERT_THROW(OrthancStone::BasicFetchingStrategy(new OrthancStone::BasicFetchingItemsSorter(0), 0), Orthanc::OrthancException); | |
339 | |
340 { | |
341 OrthancStone::BasicFetchingStrategy s(new OrthancStone::BasicFetchingItemsSorter(1), 0); | |
342 unsigned int i, q; | |
343 ASSERT_TRUE(s.GetNext(i, q)); ASSERT_EQ(0u, i); ASSERT_EQ(0u, q); | |
344 ASSERT_FALSE(s.GetNext(i, q)); | |
345 } | |
346 | |
347 { | |
348 OrthancStone::BasicFetchingStrategy s(new OrthancStone::BasicFetchingItemsSorter(1), 5); | |
349 unsigned int i, q; | |
350 ASSERT_TRUE(s.GetNext(i, q)); ASSERT_EQ(0u, i); ASSERT_EQ(5u, q); | |
351 ASSERT_FALSE(s.GetNext(i, q)); | |
352 } | |
353 | |
354 { | |
355 OrthancStone::BasicFetchingStrategy s(new OrthancStone::BasicFetchingItemsSorter(2), 2); | |
356 unsigned int i, q; | |
357 ASSERT_TRUE(s.GetNext(i, q)); ASSERT_EQ(0u, i); ASSERT_EQ(2u, q); | |
358 ASSERT_TRUE(s.GetNext(i, q)); ASSERT_EQ(1u, i); ASSERT_EQ(1u, q); | |
359 ASSERT_TRUE(s.GetNext(i, q)); ASSERT_EQ(1u, i); ASSERT_EQ(2u, q); | |
360 ASSERT_FALSE(s.GetNext(i, q)); | |
361 } | |
362 | |
363 { | |
364 OrthancStone::BasicFetchingStrategy s(new OrthancStone::BasicFetchingItemsSorter(3), 2); | |
365 unsigned int i, q; | |
366 ASSERT_TRUE(s.GetNext(i, q)); ASSERT_EQ(0u, i); ASSERT_EQ(2u, q); | |
367 ASSERT_TRUE(s.GetNext(i, q)); ASSERT_EQ(1u, i); ASSERT_EQ(1u, q); | |
368 ASSERT_TRUE(s.GetNext(i, q)); ASSERT_EQ(2u, i); ASSERT_EQ(1u, q); | |
369 ASSERT_TRUE(s.GetNext(i, q)); ASSERT_EQ(1u, i); ASSERT_EQ(2u, q); | |
370 ASSERT_TRUE(s.GetNext(i, q)); ASSERT_EQ(2u, i); ASSERT_EQ(2u, q); | |
371 ASSERT_FALSE(s.GetNext(i, q)); | |
372 } | |
373 | |
374 { | |
375 OrthancStone::BasicFetchingStrategy s(new OrthancStone::BasicFetchingItemsSorter(3), 2); | |
376 s.SetBlockSize(1); | |
377 s.SetCurrent(0); | |
378 unsigned int i, q; | |
379 ASSERT_TRUE(s.GetNext(i, q)); ASSERT_EQ(0u, i); ASSERT_EQ(2u, q); | |
380 ASSERT_TRUE(s.GetNext(i, q)); ASSERT_EQ(1u, i); ASSERT_EQ(1u, q); | |
381 ASSERT_TRUE(s.GetNext(i, q)); ASSERT_EQ(1u, i); ASSERT_EQ(2u, q); | |
382 ASSERT_TRUE(s.GetNext(i, q)); ASSERT_EQ(2u, i); ASSERT_EQ(0u, q); | |
383 ASSERT_TRUE(s.GetNext(i, q)); ASSERT_EQ(2u, i); ASSERT_EQ(1u, q); | |
384 ASSERT_TRUE(s.GetNext(i, q)); ASSERT_EQ(2u, i); ASSERT_EQ(2u, q); | |
385 ASSERT_FALSE(s.GetNext(i, q)); | |
386 } | |
387 | |
388 { | |
389 OrthancStone::BasicFetchingStrategy s(new OrthancStone::BasicFetchingItemsSorter(5), 0); | |
390 ASSERT_THROW(s.SetCurrent(5), Orthanc::OrthancException); | |
391 s.SetCurrent(2); | |
392 | |
393 unsigned int i, q; | |
394 ASSERT_TRUE(s.GetNext(i, q)); ASSERT_EQ(2u, i); ASSERT_EQ(0u, q); | |
395 ASSERT_TRUE(s.GetNext(i, q)); ASSERT_EQ(3u, i); ASSERT_EQ(0u, q); | |
396 ASSERT_TRUE(s.GetNext(i, q)); ASSERT_EQ(1u, i); ASSERT_EQ(0u, q); | |
397 ASSERT_TRUE(s.GetNext(i, q)); ASSERT_EQ(4u, i); ASSERT_EQ(0u, q); | |
398 ASSERT_TRUE(s.GetNext(i, q)); ASSERT_EQ(0u, i); ASSERT_EQ(0u, q); | |
399 ASSERT_FALSE(s.GetNext(i, q)); | |
400 } | |
401 | |
402 { | |
403 OrthancStone::BasicFetchingStrategy s(new OrthancStone::BasicFetchingItemsSorter(5), 0); | |
404 s.SetCurrent(4); | |
405 | |
406 unsigned int i, q; | |
407 ASSERT_TRUE(s.GetNext(i, q)); ASSERT_EQ(4u, i); ASSERT_EQ(0u, q); | |
408 ASSERT_TRUE(s.GetNext(i, q)); ASSERT_EQ(3u, i); ASSERT_EQ(0u, q); | |
409 ASSERT_TRUE(s.GetNext(i, q)); ASSERT_EQ(2u, i); ASSERT_EQ(0u, q); | |
410 ASSERT_TRUE(s.GetNext(i, q)); ASSERT_EQ(1u, i); ASSERT_EQ(0u, q); | |
411 ASSERT_TRUE(s.GetNext(i, q)); ASSERT_EQ(0u, i); ASSERT_EQ(0u, q); | |
412 ASSERT_FALSE(s.GetNext(i, q)); | |
413 } | |
414 } | |
415 | |
416 | |
417 TEST(BasicFetchingStrategy, Test2) | |
418 { | |
419 OrthancStone::BasicFetchingStrategy s(new OrthancStone::BasicFetchingItemsSorter(20), 2); | |
420 ASSERT_EQ(20u, s.GetItemsCount()); | |
421 ASSERT_EQ(2u, s.GetMaxQuality()); | |
422 | |
423 StrategyTester t; | |
424 | |
425 s.SetCurrent(10); | |
426 | |
427 unsigned int i, q; | |
428 while (s.GetNext(i, q)) | |
429 { | |
430 ASSERT_TRUE(t.IsValidCommand(i, q)); | |
431 } | |
432 | |
433 ASSERT_TRUE(t.HasFinished(s)); | |
223 } | 434 } |
224 | 435 |
225 | 436 |
226 | 437 |
227 | 438 |