/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sw.hxx" #define TIMELOG #include "gtest/gtest.h" #include #include #include #include #undef ENABLE_DEBUG_OUTPUT // FIXME: #define RUN_OLD_FAILING_TESTS 0 using namespace std; namespace /* private */ { const int NUM_ENTRIES = 1000; class BigPtrEntryMock : public BigPtrEntry { public: BigPtrEntryMock(int count) : count_(count) { } ~BigPtrEntryMock() { #ifdef ENABLE_DEBUG_OUTPUT printf("Destructor called (%i)\n", count_); #endif } int getCount() const { return count_; } void setCount(int newCount) { count_ = newCount; } sal_uLong Position() const { return GetPos(); } private: int count_; }; sal_Bool AddToCount(const ElementPtr& rElem, void* pArgs) { BigPtrEntryMock* const pbem = static_cast(rElem); pbem->setCount(pbem->getCount() + *((int*)pArgs)); return true; } void dumpBigPtrArray(const BigPtrArray& bparr) { #ifdef ENABLE_DEBUG_OUTPUT for (int i = 0; i < bparr.Count(); i++) printf("bparr[%i,%i]: %i\n", i, static_cast(bparr[i])->Position(), static_cast(bparr[i])->getCount()); printf("\n"); #endif } void fillBigPtrArray(BigPtrArray& bparr, sal_uLong numEntries) { for (int i = 0; i < numEntries; i++) bparr.Insert(new BigPtrEntryMock(i), bparr.Count()); } void printMethodName(const char* name) { #ifdef ENABLE_DEBUG_OUTPUT printf(name); #endif } bool checkElementPositions(const BigPtrArray& bparr) { for (int i = 0; i < bparr.Count(); i++) { if (static_cast(bparr[i])->Position() != i) return false; } return true; } void releaseBigPtrArrayContent(BigPtrArray& bparr) { for (int i = 0; i < bparr.Count(); i++) delete bparr[i]; } RTL_LOGFILE_CONTEXT(logFile, "BigPtrArray performance measures" ); } class BigPtrArrayUnittest : public ::testing::Test { public: BigPtrArrayUnittest() { } }; /** Test constructor/destructor The size of the BigPtrArray aka the 'Count' should be 0 initially. */ TEST_F(BigPtrArrayUnittest, test_ctor) { printMethodName("test_ctor\n"); BigPtrArray bparr; ASSERT_TRUE(bparr.Count() == 0) << "BigPtrArray ctor failed";; } TEST_F(BigPtrArrayUnittest, test_insert_entries_at_front) { printMethodName("test_insert_entries_at_front\n"); RTL_LOGFILE_CONTEXT_TRACE(logFile, "START: test_insert_entries_at_front"); BigPtrArray bparr; for (int i = 0; i < NUM_ENTRIES; i++) { sal_uLong oldCount = bparr.Count(); bparr.Insert(new BigPtrEntryMock(i), 0); ASSERT_TRUE((bparr.Count() == oldCount + 1)) << "test_insert_entries_at_front failed"; } RTL_LOGFILE_CONTEXT_TRACE(logFile, "END: test_insert_entries_at_front"); for (int i = 0, j = NUM_ENTRIES - 1; i < NUM_ENTRIES; i++, j--) { ASSERT_TRUE(static_cast(bparr[i])->getCount() == j) << "test_insert_entries_at_front failed"; } ASSERT_TRUE(checkElementPositions(bparr)) << "test_insert_entries_at_front failed"; releaseBigPtrArrayContent(bparr); dumpBigPtrArray(bparr); } TEST_F(BigPtrArrayUnittest, test_insert_entries_in_the_middle) { printMethodName("test_insert_entries_in_the_middle\n"); RTL_LOGFILE_CONTEXT_TRACE(logFile, "START: test_insert_entries_in_the_middle"); BigPtrArray bparr; fillBigPtrArray(bparr, NUM_ENTRIES); dumpBigPtrArray(bparr); sal_uLong oldCount = bparr.Count(); bparr.Insert(new BigPtrEntryMock(NUM_ENTRIES), bparr.Count() / 2); RTL_LOGFILE_CONTEXT_TRACE(logFile, "END: test_insert_entries_in_the_middle"); ASSERT_TRUE((oldCount + 1 == bparr.Count() && static_cast(bparr[bparr.Count() / 2])->getCount() == NUM_ENTRIES)) << "test_insert_entries_in_the_middle failed"; ASSERT_TRUE(checkElementPositions(bparr)) << "test_insert_entries_in_the_middle failed"; releaseBigPtrArrayContent(bparr); dumpBigPtrArray(bparr); } TEST_F(BigPtrArrayUnittest, test_insert_at_already_used_index) { printMethodName("test_insert_at_already_used_index\n"); RTL_LOGFILE_CONTEXT_TRACE(logFile, "START: test_insert_at_already_used_index"); BigPtrArray bparr; fillBigPtrArray(bparr, NUM_ENTRIES); dumpBigPtrArray(bparr); int oldCount = bparr.Count(); for (int i = 0, j = -5; i < 5; i++, j++) bparr.Insert(new BigPtrEntryMock(j), i); RTL_LOGFILE_CONTEXT_TRACE(logFile, "END: test_insert_at_already_used_index"); ASSERT_TRUE((oldCount + 5 == bparr.Count())) << "test_insert_at_already_used_index failed"; for (int i = 0, j = -5; i < bparr.Count(); i++, j++) { ASSERT_TRUE(static_cast(bparr[i])->getCount() == j) << "test_insert_at_already_used_index failed"; } ASSERT_TRUE(checkElementPositions(bparr)) << "test_insert_at_already_used_index failed"; releaseBigPtrArrayContent(bparr); dumpBigPtrArray(bparr); } TEST_F(BigPtrArrayUnittest, test_insert_at_end) { printMethodName("test_insert_at_end\n"); BigPtrArray bparr; fillBigPtrArray(bparr, NUM_ENTRIES); dumpBigPtrArray(bparr); sal_uLong oldCount = bparr.Count(); bparr.Insert(new BigPtrEntryMock(NUM_ENTRIES), bparr.Count()); ASSERT_TRUE((oldCount + 1 == bparr.Count() && static_cast(bparr[bparr.Count()-1])->getCount() == NUM_ENTRIES)) << "test_insert_at_end failed"; ASSERT_TRUE(checkElementPositions(bparr)) << "test_insert_at_end failed"; releaseBigPtrArrayContent(bparr); dumpBigPtrArray(bparr); } TEST_F(BigPtrArrayUnittest, test_remove_at_front) { printMethodName("test_remove_at_front\n"); RTL_LOGFILE_CONTEXT_TRACE(logFile, "START: test_remove_at_front"); BigPtrArray bparr; fillBigPtrArray(bparr, NUM_ENTRIES); dumpBigPtrArray(bparr); for (int i = 0; i < NUM_ENTRIES; i++) { sal_uLong oldCount = bparr.Count(); delete bparr[0]; // release content bparr.Remove(0); // remove item from container ASSERT_TRUE((oldCount - 1 == bparr.Count())) << "test_remove_at_front failed (wrong count)"; for (int j = 0, k = i + 1; j < bparr.Count(); j++, k++) { ASSERT_TRUE(static_cast(bparr[j])->getCount() == k) << "test_remove_at_front failed"; } ASSERT_TRUE(checkElementPositions(bparr)) << "test_remove_at_front failed"; dumpBigPtrArray(bparr); } RTL_LOGFILE_CONTEXT_TRACE(logFile, "END: test_remove_at_front"); } TEST_F(BigPtrArrayUnittest, test_remove_at_back) { printMethodName("test_remove_at_back\n"); BigPtrArray bparr; fillBigPtrArray(bparr, NUM_ENTRIES); dumpBigPtrArray(bparr); for (int i = NUM_ENTRIES - 1; i >= 0; i--) { sal_uLong oldCount = bparr.Count(); delete bparr[i]; bparr.Remove(i); ASSERT_TRUE((oldCount - 1 == bparr.Count())) << "test_remove_at_back failed (wrong count)"; for (int j = 0; j < bparr.Count(); j++) { ASSERT_TRUE(static_cast(bparr[j])->getCount() == j) << "test_remove_at_back failed"; } ASSERT_TRUE(checkElementPositions(bparr)) << "test_remove_at_back failed"; dumpBigPtrArray(bparr); } } TEST_F(BigPtrArrayUnittest, test_remove_in_the_middle) { printMethodName("test_remove_in_the_middle\n"); RTL_LOGFILE_CONTEXT_TRACE(logFile, "START: test_remove_in_the_middle"); BigPtrArray bparr; fillBigPtrArray(bparr, NUM_ENTRIES); dumpBigPtrArray(bparr); while (bparr.Count()) { sal_uLong oldCount = bparr.Count(); int oldElement = static_cast(bparr[bparr.Count() / 2])->getCount(); delete bparr[bparr.Count() / 2]; bparr.Remove(bparr.Count() / 2); ASSERT_TRUE((oldCount - 1 == bparr.Count())) << "test_remove_in_the_middle failed (wrong count)"; for (int i = 0; i < bparr.Count(); i++) { ASSERT_TRUE(static_cast(bparr[i])->getCount() != oldElement) << "test_remove_in_the_middle failed"; } ASSERT_TRUE(checkElementPositions(bparr)) << "test_remove_in_the_middle failed"; dumpBigPtrArray(bparr); } RTL_LOGFILE_CONTEXT_TRACE(logFile, "END: test_remove_in_the_middle"); } TEST_F(BigPtrArrayUnittest, test_remove_multiple_elements_at_once) { printMethodName("test_remove_multiple_elements_at_once\n"); BigPtrArray bparr; fillBigPtrArray(bparr, NUM_ENTRIES); dumpBigPtrArray(bparr); while(bparr.Count()) { sal_uLong nRemove = (bparr.Count() > 3) ? 3 : bparr.Count(); sal_uLong oldCount = bparr.Count(); for (int i = 0; i < nRemove; i++) delete bparr[i]; bparr.Remove(0, nRemove); ASSERT_TRUE((oldCount - nRemove == bparr.Count())) << "test_remove_multiple_elements_at_once failed"; ASSERT_TRUE(checkElementPositions(bparr)) << "test_remove_multiple_elements_at_once failed"; dumpBigPtrArray(bparr); } } TEST_F(BigPtrArrayUnittest, test_remove_all_elements_at_once) { printMethodName("test_remove_all_elements_at_once\n"); BigPtrArray bparr; fillBigPtrArray(bparr, NUM_ENTRIES); dumpBigPtrArray(bparr); releaseBigPtrArrayContent(bparr); bparr.Remove(0, bparr.Count()); ASSERT_TRUE(bparr.Count() == 0) << "test_remove_all_elements_at_once failed"; dumpBigPtrArray(bparr); } TEST_F(BigPtrArrayUnittest, test_move_elements_from_lower_to_higher_pos) { printMethodName("test_move_elements_from_lower_to_higher_pos\n"); BigPtrArray bparr; fillBigPtrArray(bparr, NUM_ENTRIES); dumpBigPtrArray(bparr); for (int i = 0; i < NUM_ENTRIES - 1; i++) { bparr.Move(i, i + 2); dumpBigPtrArray(bparr); } for (int i = 0; i < (NUM_ENTRIES - 1); i++) { ASSERT_TRUE(static_cast(bparr[i])->getCount() == (i + 1)) << "test_move_elements_from_lower_to_higher_pos failed"; } ASSERT_TRUE(static_cast(bparr[NUM_ENTRIES -1])->getCount() == 0) << "test_move_elements_from_lower_to_higher_pos failed"; ASSERT_TRUE(checkElementPositions(bparr)) << "test_move_elements_from_lower_to_higher_pos failed"; releaseBigPtrArrayContent(bparr); } TEST_F(BigPtrArrayUnittest, test_move_elements_from_higher_to_lower_pos) { printMethodName("test_move_elements_from_higher_to_lower_pos\n"); BigPtrArray bparr; fillBigPtrArray(bparr, NUM_ENTRIES); dumpBigPtrArray(bparr); for (int i = NUM_ENTRIES - 1; i >= 1; i--) { bparr.Move(i, i - 1); dumpBigPtrArray(bparr); } ASSERT_TRUE(static_cast(bparr[0])->getCount() == (NUM_ENTRIES - 1)) << "test_move_elements_from_higher_to_lower_pos failed"; for (int i = 1; i < NUM_ENTRIES; i++) { ASSERT_TRUE(static_cast(bparr[i])->getCount() == (i - 1)) << "test_move_elements_from_higher_to_lower_pos failed"; } ASSERT_TRUE(checkElementPositions(bparr)) << "test_move_elements_from_higher_to_lower_pos failed"; releaseBigPtrArrayContent(bparr); } TEST_F(BigPtrArrayUnittest, test_move_to_same_position) { printMethodName("test_move_to_same_position\n"); BigPtrArray bparr; fillBigPtrArray(bparr, NUM_ENTRIES); dumpBigPtrArray(bparr); for (int i = 0; i < NUM_ENTRIES; i++) { bparr.Move(i, i); } #if RUN_OLD_FAILING_TESTS ASSERT_TRUE(checkElementPositions(bparr)) << "test_move_to_same_position failed"; #endif dumpBigPtrArray(bparr); for (int i = 0; i < NUM_ENTRIES; i++) { ASSERT_TRUE(static_cast(bparr[i])->getCount() == i) << "test_move_to_same_position failed"; } #if RUN_OLD_FAILING_TESTS ASSERT_TRUE(checkElementPositions(bparr)) << "test_move_to_same_position failed"; #endif releaseBigPtrArrayContent(bparr); dumpBigPtrArray(bparr); } TEST_F(BigPtrArrayUnittest, test_replace_elements) { printMethodName("test_replace_elements\n"); BigPtrArray bparr; fillBigPtrArray(bparr, NUM_ENTRIES); dumpBigPtrArray(bparr); for (int i = 0, j = NUM_ENTRIES - 1; i < NUM_ENTRIES; i++, j--) { delete bparr[i]; bparr.Replace(i, new BigPtrEntryMock(j)); dumpBigPtrArray(bparr); } for (int i = 0; i < NUM_ENTRIES; i++) { ASSERT_TRUE(static_cast(bparr[i])->getCount() == (NUM_ENTRIES - i - 1)) << "test_replace_elements failed"; } ASSERT_TRUE(checkElementPositions(bparr)) << "test_replace_elements failed"; releaseBigPtrArrayContent(bparr); } TEST_F(BigPtrArrayUnittest, test_for_each) { printMethodName("test_for_each\n"); BigPtrArray bparr; fillBigPtrArray(bparr, NUM_ENTRIES); dumpBigPtrArray(bparr); int addCount = 1; bparr.ForEach(AddToCount, &addCount); for (int i = 0; i < NUM_ENTRIES; i++) { ASSERT_TRUE(static_cast(bparr[i])->getCount() == (i+1)) << "test_for_each failed"; } releaseBigPtrArrayContent(bparr); dumpBigPtrArray(bparr); } TEST_F(BigPtrArrayUnittest, test_for_some1) { printMethodName("test_for_some1\n"); BigPtrArray bparr; fillBigPtrArray(bparr, NUM_ENTRIES); dumpBigPtrArray(bparr); int addCount = 1; bparr.ForEach(0, NUM_ENTRIES / 2, AddToCount, &addCount); int i = 0; for (/* */; i < NUM_ENTRIES / 2; i++) { ASSERT_TRUE(static_cast(bparr[i])->getCount() == (i+1)) << "test_for_some1 failed"; } for (/* */; i < NUM_ENTRIES; i++) { ASSERT_TRUE(static_cast(bparr[i])->getCount() == (i)) << "test_for_some1 failed"; } releaseBigPtrArrayContent(bparr); dumpBigPtrArray(bparr); } TEST_F(BigPtrArrayUnittest, test_for_some2) { printMethodName("test_for_some2\n"); BigPtrArray bparr; fillBigPtrArray(bparr, NUM_ENTRIES); dumpBigPtrArray(bparr); int addCount = 1; bparr.ForEach(NUM_ENTRIES / 2, NUM_ENTRIES, AddToCount, &addCount); int i = 0; for (/* */; i < NUM_ENTRIES / 2; i++) { ASSERT_TRUE(static_cast(bparr[i])->getCount() == (i)) << "test_for_some2 failed"; } for (/* */; i < NUM_ENTRIES; i++) { ASSERT_TRUE(static_cast(bparr[i])->getCount() == (i+1)) << "test_for_some2 failed"; } releaseBigPtrArrayContent(bparr); dumpBigPtrArray(bparr); } TEST_F(BigPtrArrayUnittest, test_for_some3) { printMethodName("test_for_some3\n"); BigPtrArray bparr; fillBigPtrArray(bparr, NUM_ENTRIES); dumpBigPtrArray(bparr); int addCount = 1; bparr.ForEach(0, 0, AddToCount, &addCount); for (int i = 0; i < NUM_ENTRIES; i++) { ASSERT_TRUE(static_cast(bparr[i])->getCount() == i) << "test_for_some3 failed"; } releaseBigPtrArrayContent(bparr); } const char* START = "START: "; const char* END = "END: "; class PerformanceTracer { public: public: PerformanceTracer(const string& methodName) : startString_(START), endString_(END) { startString_ += methodName; endString_ += methodName; RTL_LOGFILE_CONTEXT_TRACE(logFile, startString_.c_str()); } ~PerformanceTracer() { RTL_LOGFILE_CONTEXT_TRACE(logFile, endString_.c_str()); } private: string startString_; string endString_; }; class BigPtrArrayPerformanceTest : public ::testing::Test { public: BigPtrArrayPerformanceTest() { } protected: void test_insert_at_end(const char* numElements) { char buff[100] = { 0 }; strcat(buff, "test_insert_at_end "); strcat(buff, numElements); int n = atoi(numElements); PerformanceTracer tracer(buff); BigPtrArray bparr; for (int i = 0; i < n; i++) bparr.Insert(new BigPtrEntryMock(i), bparr.Count()); releaseBigPtrArrayContent(bparr); } void test_insert_at_front(const char* numElements) { char buff[100] = { 0 }; strcat(buff, "test_insert_at_front "); strcat(buff, numElements); int n = atoi(numElements); PerformanceTracer tracer(buff); BigPtrArray bparr; for (int i = 0; i < n; i++) bparr.Insert(new BigPtrEntryMock(i), 0); releaseBigPtrArrayContent(bparr); } }; TEST_F(BigPtrArrayPerformanceTest, test_insert_at_end_1000) { test_insert_at_end("1000"); } TEST_F(BigPtrArrayPerformanceTest, test_insert_at_end_10000) { test_insert_at_end("10000"); } TEST_F(BigPtrArrayPerformanceTest, test_insert_at_end_100000) { test_insert_at_end("100000"); } TEST_F(BigPtrArrayPerformanceTest, test_insert_at_end_1000000) { test_insert_at_end("1000000"); } TEST_F(BigPtrArrayPerformanceTest, test_insert_at_front_1000) { test_insert_at_front("1000"); } TEST_F(BigPtrArrayPerformanceTest, test_insert_at_front_10000) { test_insert_at_front("10000"); } TEST_F(BigPtrArrayPerformanceTest, test_insert_at_front_100000) { test_insert_at_front("100000"); } TEST_F(BigPtrArrayPerformanceTest, test_insert_at_front_1000000) { test_insert_at_front("1000000"); } //##################################### int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }