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