comparison UnitTestsSources/ComputationalGeometryTests.cpp @ 1873:e0966648ebd0

unit tests of SegmentTree
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 11 Jan 2022 15:36:04 +0100
parents db8a8a19b543
children 08f2476e8f5e
comparison
equal deleted inserted replaced
1872:db8a8a19b543 1873:e0966648ebd0
28 #include <OrthancException.h> 28 #include <OrthancException.h>
29 29
30 30
31 namespace 31 namespace
32 { 32 {
33 typedef Orthanc::SingleValueObject<int> Counter;
34
33 class CounterFactory : public OrthancStone::SegmentTree::IPayloadFactory 35 class CounterFactory : public OrthancStone::SegmentTree::IPayloadFactory
34 { 36 {
37 private:
38 int value_;
39
35 public: 40 public:
36 virtual Orthanc::IDynamicObject* Create() 41 CounterFactory(int value) :
42 value_(value)
37 { 43 {
38 return new Orthanc::SingleValueObject<int>(42); 44 }
45
46 virtual Orthanc::IDynamicObject* Create() ORTHANC_OVERRIDE
47 {
48 return new Counter(value_);
39 } 49 }
40 }; 50 };
41 } 51
42 52 class IncrementVisitor : public OrthancStone::SegmentTree::IVisitor
43 53 {
44 TEST(SegmentTree, Basic) 54 private:
45 { 55 int increment_;
46 CounterFactory factory; 56
57 public:
58 IncrementVisitor(int increment) :
59 increment_(increment)
60 {
61 }
62
63 virtual void Visit(const OrthancStone::SegmentTree& node,
64 bool fullyInside) ORTHANC_OVERRIDE
65 {
66 if (fullyInside)
67 {
68 Counter& payload = node.GetTypedPayload<Counter>();
69
70 if (payload.GetValue() + increment_ < 0)
71 {
72 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
73 }
74 else
75 {
76 payload.SetValue(payload.GetValue() + increment_);
77 }
78 }
79 }
80 };
81 }
82
83
84 TEST(SegmentTree, Create)
85 {
86 CounterFactory factory(42);
47 OrthancStone::SegmentTree root(4u, 15u, factory); // Check out Figure 1.1 (page 14) from textbook 87 OrthancStone::SegmentTree root(4u, 15u, factory); // Check out Figure 1.1 (page 14) from textbook
48 88
49 ASSERT_EQ(4u, root.GetLowBound()); 89 ASSERT_EQ(4u, root.GetLowBound());
50 ASSERT_EQ(15u, root.GetHighBound()); 90 ASSERT_EQ(15u, root.GetHighBound());
51 ASSERT_FALSE(root.IsLeaf()); 91 ASSERT_FALSE(root.IsLeaf());
52 ASSERT_EQ(42, root.GetTypedPayload< Orthanc::SingleValueObject<int> >().GetValue()); 92 ASSERT_EQ(42, root.GetTypedPayload<Counter>().GetValue());
53 ASSERT_EQ(21u, root.CountNodes()); 93 ASSERT_EQ(21u, root.CountNodes());
54 94
55 OrthancStone::SegmentTree* n = &root.GetLeftChild(); 95 const OrthancStone::SegmentTree* n = &root.GetLeftChild();
56 ASSERT_EQ(4u, n->GetLowBound()); 96 ASSERT_EQ(4u, n->GetLowBound());
57 ASSERT_EQ(9u, n->GetHighBound()); 97 ASSERT_EQ(9u, n->GetHighBound());
58 ASSERT_FALSE(n->IsLeaf()); 98 ASSERT_FALSE(n->IsLeaf());
59 ASSERT_EQ(9u, n->CountNodes()); 99 ASSERT_EQ(9u, n->CountNodes());
60 100
171 n = &root.GetRightChild().GetRightChild().GetRightChild().GetRightChild(); 211 n = &root.GetRightChild().GetRightChild().GetRightChild().GetRightChild();
172 ASSERT_EQ(14u, n->GetLowBound()); 212 ASSERT_EQ(14u, n->GetLowBound());
173 ASSERT_EQ(15u, n->GetHighBound()); 213 ASSERT_EQ(15u, n->GetHighBound());
174 ASSERT_TRUE(n->IsLeaf()); 214 ASSERT_TRUE(n->IsLeaf());
175 ASSERT_EQ(1u, n->CountNodes()); 215 ASSERT_EQ(1u, n->CountNodes());
176 } 216
217 ASSERT_TRUE(root.FindLeaf(3) == NULL);
218 for (size_t i = 4; i < 15; i++)
219 {
220 n = root.FindLeaf(i);
221 ASSERT_TRUE(n != NULL);
222 ASSERT_TRUE(n->IsLeaf());
223 ASSERT_EQ(i, n->GetLowBound());
224 ASSERT_EQ(i + 1, n->GetHighBound());
225 ASSERT_EQ(42, n->GetTypedPayload<Counter>().GetValue());
226 }
227 ASSERT_TRUE(root.FindLeaf(15) == NULL);
228 }
229
230
231 static bool CheckCounter(const OrthancStone::SegmentTree& node,
232 int expectedValue)
233 {
234 if (node.GetTypedPayload<Counter>().GetValue() != expectedValue)
235 {
236 return false;
237 }
238 else if (node.IsLeaf())
239 {
240 return true;
241 }
242 else
243 {
244 return (CheckCounter(node.GetLeftChild(), expectedValue) &&
245 CheckCounter(node.GetRightChild(), expectedValue));
246 }
247 }
248
249
250 #if 0
251 static void Print(const OrthancStone::SegmentTree& node,
252 unsigned int indent)
253 {
254 for (size_t i = 0; i < indent; i++)
255 printf(" ");
256 printf("(%lu,%lu): %d\n", node.GetLowBound(), node.GetHighBound(), node.GetTypedPayload<Counter>().GetValue());
257 if (!node.IsLeaf())
258 {
259 Print(node.GetLeftChild(), indent + 1);
260 Print(node.GetRightChild(), indent + 1);
261 }
262 }
263 #endif
264
265
266 TEST(SegmentTree, Visit)
267 {
268 CounterFactory factory(0);
269 OrthancStone::SegmentTree root(4u, 15u, factory); // Check out Figure 1.1 (page 14) from textbook
270
271 ASSERT_TRUE(CheckCounter(root, 0));
272
273 IncrementVisitor plus(1);
274 IncrementVisitor minus(-1);
275
276 root.VisitSegment(0, 20, plus);
277 ASSERT_EQ(1, root.GetTypedPayload<Counter>().GetValue());
278 ASSERT_TRUE(CheckCounter(root.GetLeftChild(), 0));
279 ASSERT_TRUE(CheckCounter(root.GetRightChild(), 0));
280
281 root.VisitSegment(0, 20, plus);
282 ASSERT_EQ(2, root.GetTypedPayload<Counter>().GetValue());
283 ASSERT_TRUE(CheckCounter(root.GetLeftChild(), 0));
284 ASSERT_TRUE(CheckCounter(root.GetRightChild(), 0));
285
286 root.VisitSegment(0, 20, minus);
287 root.VisitSegment(0, 20, minus);
288 ASSERT_TRUE(CheckCounter(root, 0));
289
290 root.VisitSegment(8, 11, plus);
291 ASSERT_EQ(0, root.FindNode(4, 15)->GetTypedPayload<Counter>().GetValue());
292 ASSERT_EQ(0, root.FindNode(4, 9)->GetTypedPayload<Counter>().GetValue());
293 ASSERT_EQ(0, root.FindNode(4, 6)->GetTypedPayload<Counter>().GetValue());
294 ASSERT_EQ(0, root.FindNode(4, 5)->GetTypedPayload<Counter>().GetValue());
295 ASSERT_EQ(0, root.FindNode(5, 6)->GetTypedPayload<Counter>().GetValue());
296 ASSERT_EQ(0, root.FindNode(6, 9)->GetTypedPayload<Counter>().GetValue());
297 ASSERT_EQ(0, root.FindNode(6, 7)->GetTypedPayload<Counter>().GetValue());
298 ASSERT_EQ(0, root.FindNode(7, 9)->GetTypedPayload<Counter>().GetValue());
299 ASSERT_EQ(0, root.FindNode(7, 8)->GetTypedPayload<Counter>().GetValue());
300 ASSERT_EQ(1, root.FindNode(8, 9)->GetTypedPayload<Counter>().GetValue());
301 ASSERT_EQ(0, root.FindNode(9, 15)->GetTypedPayload<Counter>().GetValue());
302 ASSERT_EQ(0, root.FindNode(9, 12)->GetTypedPayload<Counter>().GetValue());
303 ASSERT_EQ(1, root.FindNode(9, 10)->GetTypedPayload<Counter>().GetValue());
304 ASSERT_EQ(0, root.FindNode(10, 12)->GetTypedPayload<Counter>().GetValue());
305 ASSERT_EQ(1, root.FindNode(10, 11)->GetTypedPayload<Counter>().GetValue());
306 ASSERT_EQ(0, root.FindNode(11, 12)->GetTypedPayload<Counter>().GetValue());
307 ASSERT_EQ(0, root.FindNode(12, 15)->GetTypedPayload<Counter>().GetValue());
308 ASSERT_EQ(0, root.FindNode(12, 13)->GetTypedPayload<Counter>().GetValue());
309 ASSERT_EQ(0, root.FindNode(13, 15)->GetTypedPayload<Counter>().GetValue());
310 ASSERT_EQ(0, root.FindNode(13, 14)->GetTypedPayload<Counter>().GetValue());
311 ASSERT_EQ(0, root.FindNode(14, 15)->GetTypedPayload<Counter>().GetValue());
312
313 root.VisitSegment(9, 11, minus);
314 ASSERT_EQ(0, root.FindNode(4, 15)->GetTypedPayload<Counter>().GetValue());
315 ASSERT_EQ(0, root.FindNode(4, 9)->GetTypedPayload<Counter>().GetValue());
316 ASSERT_EQ(0, root.FindNode(4, 6)->GetTypedPayload<Counter>().GetValue());
317 ASSERT_EQ(0, root.FindNode(4, 5)->GetTypedPayload<Counter>().GetValue());
318 ASSERT_EQ(0, root.FindNode(5, 6)->GetTypedPayload<Counter>().GetValue());
319 ASSERT_EQ(0, root.FindNode(6, 9)->GetTypedPayload<Counter>().GetValue());
320 ASSERT_EQ(0, root.FindNode(6, 7)->GetTypedPayload<Counter>().GetValue());
321 ASSERT_EQ(0, root.FindNode(7, 9)->GetTypedPayload<Counter>().GetValue());
322 ASSERT_EQ(0, root.FindNode(7, 8)->GetTypedPayload<Counter>().GetValue());
323 ASSERT_EQ(1, root.FindNode(8, 9)->GetTypedPayload<Counter>().GetValue());
324 ASSERT_TRUE(CheckCounter(root.GetRightChild(), 0));
325
326 root.VisitSegment(8, 9, minus);
327 ASSERT_TRUE(CheckCounter(root, 0));
328 }