1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/types.h>
21 #include <cppunit/TestAssert.h>
22 #include <cppunit/TestFixture.h>
23 #include <cppunit/extensions/HelperMacros.h>
24 #include <cppunit/plugin/TestPlugIn.h>
26 //#define TIMELOG for measuring performance
31 #include <rtl/logfile.hxx>
38 namespace /* private */
40 const sal_uLong NUM_ENTRIES
= 10;
42 class BigPtrEntryMock
: public BigPtrEntry
45 BigPtrEntryMock(sal_uLong count
) : count_(count
)
53 sal_uLong
getCount() const
58 void setCount(sal_uLong newCount
)
63 sal_uLong
Position() const
72 bool AddToCount(const ElementPtr
& rElem
, void* pArgs
)
74 BigPtrEntryMock
* const pbem
= static_cast<BigPtrEntryMock
* const>(rElem
);
75 pbem
->setCount(pbem
->getCount() + *((sal_uLong
*)pArgs
));
79 void dumpBigPtrArray(const BigPtrArray
& bparr
)
84 void fillBigPtrArray(BigPtrArray
& bparr
, sal_uLong numEntries
)
86 for (sal_uLong i
= 0; i
< numEntries
; i
++)
87 bparr
.Insert(new BigPtrEntryMock(i
), bparr
.Count());
90 void printMethodName(const char* name
)
95 bool checkElementPositions(const BigPtrArray
& bparr
)
97 for (sal_uLong i
= 0; i
< bparr
.Count(); i
++)
99 if (static_cast<BigPtrEntryMock
*>(bparr
[i
])->Position() != i
)
105 void releaseBigPtrArrayContent(BigPtrArray
& bparr
)
107 for (sal_uLong i
= 0; i
< bparr
.Count(); i
++)
112 RTL_LOGFILE_CONTEXT(logFile
, "BigPtrArray performance measures" );
116 class BigPtrArrayUnittest
: public CppUnit::TestFixture
120 BigPtrArrayUnittest()
124 /** Test constructor/destructor
125 The size of the BigPtrArray
126 aka the 'Count' should be 0
131 printMethodName("test_ctor\n");
135 CPPUNIT_ASSERT_MESSAGE
137 "BigPtrArray ctor failed",
142 void test_insert_entries_at_front()
144 printMethodName("test_insert_entries_at_front\n");
147 RTL_LOGFILE_CONTEXT_TRACE(logFile
, "START: test_insert_entries_at_front");
152 for (sal_uLong i
= 0; i
< NUM_ENTRIES
; i
++)
154 sal_uLong oldCount
= bparr
.Count();
155 bparr
.Insert(new BigPtrEntryMock(i
), 0);
156 CPPUNIT_ASSERT_MESSAGE
158 "test_insert_entries_at_front failed",
159 (bparr
.Count() == oldCount
+ 1)
164 RTL_LOGFILE_CONTEXT_TRACE(logFile
, "END: test_insert_entries_at_front");
167 for (sal_uLong i
= 0, j
= NUM_ENTRIES
- 1; i
< NUM_ENTRIES
; i
++, j
--)
169 CPPUNIT_ASSERT_MESSAGE
171 "test_insert_entries_at_front failed",
172 static_cast<BigPtrEntryMock
*>(bparr
[i
])->getCount() == j
176 CPPUNIT_ASSERT_MESSAGE
178 "test_insert_entries_at_front failed",
179 checkElementPositions(bparr
)
182 releaseBigPtrArrayContent(bparr
);
183 dumpBigPtrArray(bparr
);
186 void test_insert_entries_in_the_middle()
188 printMethodName("test_insert_entries_in_the_middle\n");
191 RTL_LOGFILE_CONTEXT_TRACE(logFile
, "START: test_insert_entries_in_the_middle");
196 fillBigPtrArray(bparr
, NUM_ENTRIES
);
197 dumpBigPtrArray(bparr
);
199 sal_uLong oldCount
= bparr
.Count();
201 bparr
.Insert(new BigPtrEntryMock(NUM_ENTRIES
), bparr
.Count() / 2);
204 RTL_LOGFILE_CONTEXT_TRACE(logFile
, "END: test_insert_entries_in_the_middle");
207 CPPUNIT_ASSERT_MESSAGE
209 "test_insert_entries_in_the_middle failed",
210 (oldCount
+ 1 == bparr
.Count() && static_cast<BigPtrEntryMock
*>(bparr
[bparr
.Count() / 2])->getCount() == NUM_ENTRIES
)
213 CPPUNIT_ASSERT_MESSAGE
215 "test_insert_entries_in_the_middle failed",
216 checkElementPositions(bparr
)
219 releaseBigPtrArrayContent(bparr
);
220 dumpBigPtrArray(bparr
);
223 void test_insert_at_already_used_index()
225 printMethodName("test_insert_at_already_used_index\n");
228 RTL_LOGFILE_CONTEXT_TRACE(logFile
, "START: test_insert_at_already_used_index");
233 fillBigPtrArray(bparr
, NUM_ENTRIES
);
234 dumpBigPtrArray(bparr
);
236 sal_uLong oldCount
= bparr
.Count();
238 for (sal_uLong i
= 0, j
= -5; i
< 5; i
++, j
++)
239 bparr
.Insert(new BigPtrEntryMock(j
), i
);
242 RTL_LOGFILE_CONTEXT_TRACE(logFile
, "END: test_insert_at_already_used_index");
245 CPPUNIT_ASSERT_MESSAGE
247 "test_insert_at_already_used_index failed",
248 (oldCount
+ 5 == bparr
.Count())
251 for (sal_uLong i
= 0, j
= -5; i
< bparr
.Count(); i
++, j
++)
253 CPPUNIT_ASSERT_MESSAGE
255 "test_insert_at_already_used_index failed",
256 static_cast<BigPtrEntryMock
*>(bparr
[i
])->getCount() == j
260 CPPUNIT_ASSERT_MESSAGE
262 "test_insert_at_already_used_index failed",
263 checkElementPositions(bparr
)
266 releaseBigPtrArrayContent(bparr
);
267 dumpBigPtrArray(bparr
);
270 void test_insert_at_end()
272 printMethodName("test_insert_at_end\n");
276 fillBigPtrArray(bparr
, NUM_ENTRIES
);
277 dumpBigPtrArray(bparr
);
279 sal_uLong oldCount
= bparr
.Count();
280 bparr
.Insert(new BigPtrEntryMock(NUM_ENTRIES
), bparr
.Count());
282 CPPUNIT_ASSERT_MESSAGE
284 "test_insert_at_end failed",
285 (oldCount
+ 1 == bparr
.Count() && static_cast<BigPtrEntryMock
*>(bparr
[bparr
.Count()-1])->getCount() == NUM_ENTRIES
)
288 CPPUNIT_ASSERT_MESSAGE
290 "test_insert_at_end failed",
291 checkElementPositions(bparr
)
294 releaseBigPtrArrayContent(bparr
);
295 dumpBigPtrArray(bparr
);
298 void test_remove_at_front()
300 printMethodName("test_remove_at_front\n");
303 RTL_LOGFILE_CONTEXT_TRACE(logFile
, "START: test_remove_at_front");
308 fillBigPtrArray(bparr
, NUM_ENTRIES
);
309 dumpBigPtrArray(bparr
);
311 for (sal_uLong i
= 0; i
< NUM_ENTRIES
; i
++)
313 sal_uLong oldCount
= bparr
.Count();
315 delete bparr
[0]; // release content
316 bparr
.Remove(0); // remove item from container
318 CPPUNIT_ASSERT_MESSAGE
320 "test_remove_at_front failed (wrong count)",
321 (oldCount
- 1 == bparr
.Count())
324 for (sal_uLong j
= 0, k
= i
+ 1; j
< bparr
.Count(); j
++, k
++)
326 CPPUNIT_ASSERT_MESSAGE
328 "test_remove_at_front failed",
329 static_cast<BigPtrEntryMock
*>(bparr
[j
])->getCount() == k
333 CPPUNIT_ASSERT_MESSAGE
335 "test_remove_at_front failed",
336 checkElementPositions(bparr
)
339 dumpBigPtrArray(bparr
);
343 RTL_LOGFILE_CONTEXT_TRACE(logFile
, "END: test_remove_at_front");
347 void test_remove_at_back()
349 printMethodName("test_remove_at_back\n");
353 fillBigPtrArray(bparr
, NUM_ENTRIES
);
354 dumpBigPtrArray(bparr
);
356 for (int i
= NUM_ENTRIES
- 1; i
>= 0; i
--)
358 sal_uLong oldCount
= bparr
.Count();
362 CPPUNIT_ASSERT_MESSAGE
364 "test_remove_at_back failed (wrong count)",
365 (oldCount
- 1 == bparr
.Count())
368 for (sal_uLong j
= 0; j
< bparr
.Count(); j
++)
370 CPPUNIT_ASSERT_MESSAGE
372 "test_remove_at_back failed",
373 static_cast<BigPtrEntryMock
*>(bparr
[j
])->getCount() == j
377 CPPUNIT_ASSERT_MESSAGE
379 "test_remove_at_back failed",
380 checkElementPositions(bparr
)
383 dumpBigPtrArray(bparr
);
387 void test_remove_in_the_middle()
389 printMethodName("test_remove_in_the_middle\n");
392 RTL_LOGFILE_CONTEXT_TRACE(logFile
, "START: test_remove_in_the_middle");
397 fillBigPtrArray(bparr
, NUM_ENTRIES
);
398 dumpBigPtrArray(bparr
);
400 while (bparr
.Count())
402 sal_uLong oldCount
= bparr
.Count();
403 sal_uLong oldElement
= static_cast<BigPtrEntryMock
*>(bparr
[bparr
.Count() / 2])->getCount();
405 delete bparr
[bparr
.Count() / 2];
406 bparr
.Remove(bparr
.Count() / 2);
408 CPPUNIT_ASSERT_MESSAGE
410 "test_remove_in_the_middle failed (wrong count)",
411 (oldCount
- 1 == bparr
.Count())
414 for (sal_uLong i
= 0; i
< bparr
.Count(); i
++)
416 CPPUNIT_ASSERT_MESSAGE
418 "test_remove_in_the_middle failed",
419 static_cast<BigPtrEntryMock
*>(bparr
[i
])->getCount() != oldElement
423 CPPUNIT_ASSERT_MESSAGE
425 "test_remove_in_the_middle failed",
426 checkElementPositions(bparr
)
429 dumpBigPtrArray(bparr
);
432 RTL_LOGFILE_CONTEXT_TRACE(logFile
, "END: test_remove_in_the_middle");
436 void test_remove_multiple_elements_at_once()
438 printMethodName("test_remove_multiple_elements_at_once\n");
442 fillBigPtrArray(bparr
, NUM_ENTRIES
);
443 dumpBigPtrArray(bparr
);
447 sal_uLong nRemove
= (bparr
.Count() > 3) ? 3 : bparr
.Count();
448 sal_uLong oldCount
= bparr
.Count();
450 for (sal_uLong i
= 0; i
< nRemove
; i
++)
453 bparr
.Remove(0, nRemove
);
455 CPPUNIT_ASSERT_MESSAGE
457 "test_remove_multiple_elements_at_once failed",
458 (oldCount
- nRemove
== bparr
.Count())
461 CPPUNIT_ASSERT_MESSAGE
463 "test_remove_multiple_elements_at_once failed",
464 checkElementPositions(bparr
)
467 dumpBigPtrArray(bparr
);
471 void test_remove_all_elements_at_once()
473 printMethodName("test_remove_all_elements_at_once\n");
477 fillBigPtrArray(bparr
, NUM_ENTRIES
);
478 dumpBigPtrArray(bparr
);
480 releaseBigPtrArrayContent(bparr
);
481 bparr
.Remove(0, bparr
.Count());
483 CPPUNIT_ASSERT_MESSAGE
485 "test_remove_all_elements_at_once failed",
489 dumpBigPtrArray(bparr
);
492 void test_move_elements_from_lower_to_higher_pos()
494 printMethodName("test_move_elements_from_lower_to_higher_pos\n");
498 fillBigPtrArray(bparr
, NUM_ENTRIES
);
499 dumpBigPtrArray(bparr
);
501 for (sal_uLong i
= 0; i
< NUM_ENTRIES
- 1; i
++)
503 bparr
.Move(i
, i
+ 2);
504 dumpBigPtrArray(bparr
);
507 for (sal_uLong i
= 0; i
< (NUM_ENTRIES
- 1); i
++)
509 CPPUNIT_ASSERT_MESSAGE
511 "test_move_elements_from_lower_to_higher_pos failed",
512 static_cast<BigPtrEntryMock
*>(bparr
[i
])->getCount() == (i
+ 1)
516 CPPUNIT_ASSERT_MESSAGE
518 "test_move_elements_from_lower_to_higher_pos failed",
519 static_cast<BigPtrEntryMock
*>(bparr
[NUM_ENTRIES
-1])->getCount() == 0
522 CPPUNIT_ASSERT_MESSAGE
524 "test_move_elements_from_lower_to_higher_pos failed",
525 checkElementPositions(bparr
)
528 releaseBigPtrArrayContent(bparr
);
531 void test_move_elements_from_higher_to_lower_pos()
533 printMethodName("test_move_elements_from_higher_to_lower_pos\n");
537 fillBigPtrArray(bparr
, NUM_ENTRIES
);
538 dumpBigPtrArray(bparr
);
540 for (int i
= NUM_ENTRIES
- 1; i
>= 1; i
--)
542 bparr
.Move(i
, i
- 1);
543 dumpBigPtrArray(bparr
);
546 CPPUNIT_ASSERT_MESSAGE
548 "test_move_elements_from_higher_to_lower_pos failed",
549 static_cast<BigPtrEntryMock
*>(bparr
[0])->getCount() == (NUM_ENTRIES
- 1)
552 for (sal_uLong i
= 1; i
< NUM_ENTRIES
; i
++)
554 CPPUNIT_ASSERT_MESSAGE
556 "test_move_elements_from_higher_to_lower_pos failed",
557 static_cast<BigPtrEntryMock
*>(bparr
[i
])->getCount() == (i
- 1)
561 CPPUNIT_ASSERT_MESSAGE
563 "test_move_elements_from_higher_to_lower_pos failed",
564 checkElementPositions(bparr
)
567 releaseBigPtrArrayContent(bparr
);
570 void test_move_to_same_position()
572 printMethodName("test_move_to_same_position\n");
576 fillBigPtrArray(bparr
, NUM_ENTRIES
);
577 dumpBigPtrArray(bparr
);
579 for (sal_uLong i
= 0; i
< NUM_ENTRIES
; i
++)
584 dumpBigPtrArray(bparr
);
586 for (sal_uLong i
= 0; i
< NUM_ENTRIES
; i
++)
588 CPPUNIT_ASSERT_MESSAGE
590 "test_move_to_same_position failed",
591 static_cast<BigPtrEntryMock
*>(bparr
[i
])->getCount() == i
595 CPPUNIT_ASSERT_MESSAGE
597 "test_move_to_same_position failed",
598 checkElementPositions(bparr
)
601 releaseBigPtrArrayContent(bparr
);
602 dumpBigPtrArray(bparr
);
605 void test_replace_elements()
607 printMethodName("test_replace_elements\n");
611 fillBigPtrArray(bparr
, NUM_ENTRIES
);
612 dumpBigPtrArray(bparr
);
614 for (sal_uLong i
= 0, j
= NUM_ENTRIES
- 1; i
< NUM_ENTRIES
; i
++, j
--)
617 bparr
.Replace(i
, new BigPtrEntryMock(j
));
618 dumpBigPtrArray(bparr
);
621 for (sal_uLong i
= 0; i
< NUM_ENTRIES
; i
++)
623 CPPUNIT_ASSERT_MESSAGE
625 "test_replace_elements failed",
626 static_cast<BigPtrEntryMock
*>(bparr
[i
])->getCount() == (NUM_ENTRIES
- i
- 1)
630 CPPUNIT_ASSERT_MESSAGE
632 "test_replace_elements failed",
633 checkElementPositions(bparr
)
636 releaseBigPtrArrayContent(bparr
);
641 printMethodName("test_for_each\n");
645 fillBigPtrArray(bparr
, NUM_ENTRIES
);
646 dumpBigPtrArray(bparr
);
648 sal_uLong addCount
= 1;
649 bparr
.ForEach(AddToCount
, &addCount
);
651 for (sal_uLong i
= 0; i
< NUM_ENTRIES
; i
++)
653 CPPUNIT_ASSERT_MESSAGE
655 "test_for_each failed",
656 static_cast<BigPtrEntryMock
*>(bparr
[i
])->getCount() == (i
+1)
660 releaseBigPtrArrayContent(bparr
);
661 dumpBigPtrArray(bparr
);
664 void test_for_some1()
666 printMethodName("test_for_some1\n");
670 fillBigPtrArray(bparr
, NUM_ENTRIES
);
671 dumpBigPtrArray(bparr
);
673 sal_uLong addCount
= 1;
674 bparr
.ForEach(0, NUM_ENTRIES
/ 2, AddToCount
, &addCount
);
677 for (/* */; i
< NUM_ENTRIES
/ 2; i
++)
679 CPPUNIT_ASSERT_MESSAGE
681 "test_for_some1 failed",
682 static_cast<BigPtrEntryMock
*>(bparr
[i
])->getCount() == (i
+1)
686 for (/* */; i
< NUM_ENTRIES
; i
++)
688 CPPUNIT_ASSERT_MESSAGE
690 "test_for_some1 failed",
691 static_cast<BigPtrEntryMock
*>(bparr
[i
])->getCount() == (i
)
695 releaseBigPtrArrayContent(bparr
);
696 dumpBigPtrArray(bparr
);
699 void test_for_some2()
701 printMethodName("test_for_some2\n");
705 fillBigPtrArray(bparr
, NUM_ENTRIES
);
706 dumpBigPtrArray(bparr
);
708 sal_uLong addCount
= 1;
709 bparr
.ForEach(NUM_ENTRIES
/ 2, NUM_ENTRIES
, AddToCount
, &addCount
);
712 for (/* */; i
< NUM_ENTRIES
/ 2; i
++)
714 CPPUNIT_ASSERT_MESSAGE
716 "test_for_some2 failed",
717 static_cast<BigPtrEntryMock
*>(bparr
[i
])->getCount() == (i
)
721 for (/* */; i
< NUM_ENTRIES
; i
++)
723 CPPUNIT_ASSERT_MESSAGE
725 "test_for_some2 failed",
726 static_cast<BigPtrEntryMock
*>(bparr
[i
])->getCount() == (i
+1)
730 releaseBigPtrArrayContent(bparr
);
731 dumpBigPtrArray(bparr
);
734 void test_for_some3()
736 printMethodName("test_for_some3\n");
740 fillBigPtrArray(bparr
, NUM_ENTRIES
);
741 dumpBigPtrArray(bparr
);
743 sal_uLong addCount
= 1;
744 bparr
.ForEach(0, 0, AddToCount
, &addCount
);
746 for (sal_uLong i
= 0; i
< NUM_ENTRIES
; i
++)
748 CPPUNIT_ASSERT_MESSAGE
750 "test_for_some3 failed",
751 static_cast<BigPtrEntryMock
*>(bparr
[i
])->getCount() == i
754 releaseBigPtrArrayContent(bparr
);
757 CPPUNIT_TEST_SUITE(BigPtrArrayUnittest
);
758 CPPUNIT_TEST(test_ctor
);
759 CPPUNIT_TEST(test_insert_entries_at_front
);
760 CPPUNIT_TEST(test_insert_entries_in_the_middle
);
761 CPPUNIT_TEST(test_insert_at_already_used_index
);
762 CPPUNIT_TEST(test_insert_at_end
);
763 CPPUNIT_TEST(test_remove_at_front
);
764 CPPUNIT_TEST(test_remove_at_back
);
765 CPPUNIT_TEST(test_remove_in_the_middle
);
766 CPPUNIT_TEST(test_remove_multiple_elements_at_once
);
767 CPPUNIT_TEST(test_remove_all_elements_at_once
);
768 CPPUNIT_TEST(test_move_elements_from_lower_to_higher_pos
);
769 CPPUNIT_TEST(test_move_elements_from_higher_to_lower_pos
);
770 CPPUNIT_TEST(test_replace_elements
);
771 CPPUNIT_TEST(test_for_each
);
772 CPPUNIT_TEST(test_for_some1
);
773 CPPUNIT_TEST(test_for_some2
);
774 CPPUNIT_TEST(test_for_some3
);
775 CPPUNIT_TEST_SUITE_END();
778 const char* START
= "START: ";
779 const char* END
= "END: ";
781 class PerformanceTracer
786 PerformanceTracer(const string
& methodName
) :
790 startString_
+= methodName
;
791 endString_
+= methodName
;
793 RTL_LOGFILE_CONTEXT_TRACE(logFile
, startString_
.c_str());
800 RTL_LOGFILE_CONTEXT_TRACE(logFile
, endString_
.c_str());
809 class BigPtrArrayPerformanceTest
: public CppUnit::TestFixture
812 BigPtrArrayPerformanceTest()
816 void test_insert_at_end_1000()
817 { test_insert_at_end("1000"); }
819 void test_insert_at_end_10000()
820 { test_insert_at_end("10000"); }
822 void test_insert_at_end_100000()
823 { test_insert_at_end("100000"); }
825 void test_insert_at_end_1000000()
826 { test_insert_at_end("1000000"); }
828 void test_insert_at_front_1000()
829 { test_insert_at_front("1000"); }
831 void test_insert_at_front_10000()
832 { test_insert_at_front("10000"); }
834 void test_insert_at_front_100000()
835 { test_insert_at_front("100000"); }
837 void test_insert_at_front_1000000()
838 { test_insert_at_front("1000000"); }
840 CPPUNIT_TEST_SUITE(BigPtrArrayPerformanceTest
);
841 CPPUNIT_TEST(test_insert_at_end_1000
);
842 CPPUNIT_TEST(test_insert_at_end_10000
);
843 CPPUNIT_TEST(test_insert_at_end_100000
);
844 CPPUNIT_TEST(test_insert_at_end_1000000
);
845 CPPUNIT_TEST(test_insert_at_front_1000
);
846 CPPUNIT_TEST(test_insert_at_front_10000
);
847 CPPUNIT_TEST(test_insert_at_front_100000
);
848 CPPUNIT_TEST(test_insert_at_front_1000000
);
849 CPPUNIT_TEST_SUITE_END();
852 void test_insert_at_end(const char* numElements
)
854 char buff
[100] = { 0 };
855 strcat(buff
, "test_insert_at_end ");
856 strcat(buff
, numElements
);
857 int n
= atoi(numElements
);
858 PerformanceTracer
tracer(buff
);
860 for (int i
= 0; i
< n
; i
++)
861 bparr
.Insert(new BigPtrEntryMock(i
), bparr
.Count());
863 releaseBigPtrArrayContent(bparr
);
866 void test_insert_at_front(const char* numElements
)
868 char buff
[100] = { 0 };
869 strcat(buff
, "test_insert_at_front ");
870 strcat(buff
, numElements
);
871 int n
= atoi(numElements
);
872 PerformanceTracer
tracer(buff
);
874 for (int i
= 0; i
< n
; i
++)
875 bparr
.Insert(new BigPtrEntryMock(i
), 0);
877 releaseBigPtrArrayContent(bparr
);
881 // register test suites
882 CPPUNIT_TEST_SUITE_REGISTRATION(BigPtrArrayUnittest
);
884 CPPUNIT_TEST_SUITE_REGISTRATION(BigPtrArrayPerformanceTest
);
887 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */