blob: 344d8c970eee010fc6138d3e7516da306f027c15 [file] [log] [blame]
/**************************************************************
*
* 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 <testshl/simpleheader.hxx>
#include <bparr.hxx>
#include <string>
#include <stdlib.h>
#include <rtl/logfile.hxx>
#undef ENABLE_DEBUG_OUTPUT
using namespace std;
namespace /* private */
{
const int NUM_ENTRIES = 100000;
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<BigPtrEntryMock* const>(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<BigPtrEntryMock*>(bparr[i])->Position(), static_cast<BigPtrEntryMock*>(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<BigPtrEntryMock*>(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 CppUnit::TestFixture
{
public:
BigPtrArrayUnittest()
{
}
/** Test constructor/destructor
The size of the BigPtrArray
aka the 'Count' should be 0
initially.
*/
void test_ctor()
{
printMethodName("test_ctor\n");
BigPtrArray bparr;
CPPUNIT_ASSERT_MESSAGE
(
"BigPtrArray ctor failed",
bparr.Count() == 0
);
}
void 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);
CPPUNIT_ASSERT_MESSAGE
(
"test_insert_entries_at_front failed",
(bparr.Count() == oldCount + 1)
)
}
RTL_LOGFILE_CONTEXT_TRACE(logFile, "END: test_insert_entries_at_front");
for (int i = 0, j = NUM_ENTRIES - 1; i < NUM_ENTRIES; i++, j--)
{
CPPUNIT_ASSERT_MESSAGE
(
"test_insert_entries_at_front failed",
static_cast<BigPtrEntryMock*>(bparr[i])->getCount() == j
)
}
CPPUNIT_ASSERT_MESSAGE
(
"test_insert_entries_at_front failed",
checkElementPositions(bparr)
)
releaseBigPtrArrayContent(bparr);
dumpBigPtrArray(bparr);
}
void 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");
CPPUNIT_ASSERT_MESSAGE
(
"test_insert_entries_in_the_middle failed",
(oldCount + 1 == bparr.Count() && static_cast<BigPtrEntryMock*>(bparr[bparr.Count() / 2])->getCount() == NUM_ENTRIES)
)
CPPUNIT_ASSERT_MESSAGE
(
"test_insert_entries_in_the_middle failed",
checkElementPositions(bparr)
)
releaseBigPtrArrayContent(bparr);
dumpBigPtrArray(bparr);
}
void 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");
CPPUNIT_ASSERT_MESSAGE
(
"test_insert_at_already_used_index failed",
(oldCount + 5 == bparr.Count())
)
for (int i = 0, j = -5; i < bparr.Count(); i++, j++)
{
CPPUNIT_ASSERT_MESSAGE
(
"test_insert_at_already_used_index failed",
static_cast<BigPtrEntryMock*>(bparr[i])->getCount() == j
)
}
CPPUNIT_ASSERT_MESSAGE
(
"test_insert_at_already_used_index failed",
checkElementPositions(bparr)
)
releaseBigPtrArrayContent(bparr);
dumpBigPtrArray(bparr);
}
void 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());
CPPUNIT_ASSERT_MESSAGE
(
"test_insert_at_end failed",
(oldCount + 1 == bparr.Count() && static_cast<BigPtrEntryMock*>(bparr[bparr.Count()-1])->getCount() == NUM_ENTRIES)
)
CPPUNIT_ASSERT_MESSAGE
(
"test_insert_at_end failed",
checkElementPositions(bparr)
)
releaseBigPtrArrayContent(bparr);
dumpBigPtrArray(bparr);
}
void 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
CPPUNIT_ASSERT_MESSAGE
(
"test_remove_at_front failed (wrong count)",
(oldCount - 1 == bparr.Count())
)
for (int j = 0, k = i + 1; j < bparr.Count(); j++, k++)
{
CPPUNIT_ASSERT_MESSAGE
(
"test_remove_at_front failed",
static_cast<BigPtrEntryMock*>(bparr[j])->getCount() == k
)
}
CPPUNIT_ASSERT_MESSAGE
(
"test_remove_at_front failed",
checkElementPositions(bparr)
)
dumpBigPtrArray(bparr);
}
RTL_LOGFILE_CONTEXT_TRACE(logFile, "END: test_remove_at_front");
}
void 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);
CPPUNIT_ASSERT_MESSAGE
(
"test_remove_at_back failed (wrong count)",
(oldCount - 1 == bparr.Count())
)
for (int j = 0; j < bparr.Count(); j++)
{
CPPUNIT_ASSERT_MESSAGE
(
"test_remove_at_back failed",
static_cast<BigPtrEntryMock*>(bparr[j])->getCount() == j
)
}
CPPUNIT_ASSERT_MESSAGE
(
"test_remove_at_back failed",
checkElementPositions(bparr)
)
dumpBigPtrArray(bparr);
}
}
void 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<BigPtrEntryMock*>(bparr[bparr.Count() / 2])->getCount();
delete bparr[bparr.Count() / 2];
bparr.Remove(bparr.Count() / 2);
CPPUNIT_ASSERT_MESSAGE
(
"test_remove_in_the_middle failed (wrong count)",
(oldCount - 1 == bparr.Count())
)
for (int i = 0; i < bparr.Count(); i++)
{
CPPUNIT_ASSERT_MESSAGE
(
"test_remove_in_the_middle failed",
static_cast<BigPtrEntryMock*>(bparr[i])->getCount() != oldElement
)
}
CPPUNIT_ASSERT_MESSAGE
(
"test_remove_in_the_middle failed",
checkElementPositions(bparr)
)
dumpBigPtrArray(bparr);
}
RTL_LOGFILE_CONTEXT_TRACE(logFile, "END: test_remove_in_the_middle");
}
void 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);
CPPUNIT_ASSERT_MESSAGE
(
"test_remove_multiple_elements_at_once failed",
(oldCount - nRemove == bparr.Count())
)
CPPUNIT_ASSERT_MESSAGE
(
"test_remove_multiple_elements_at_once failed",
checkElementPositions(bparr)
)
dumpBigPtrArray(bparr);
}
}
void 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());
CPPUNIT_ASSERT_MESSAGE
(
"test_remove_all_elements_at_once failed",
bparr.Count() == 0
)
dumpBigPtrArray(bparr);
}
void 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++)
{
CPPUNIT_ASSERT_MESSAGE
(
"test_move_elements_from_lower_to_higher_pos failed",
static_cast<BigPtrEntryMock*>(bparr[i])->getCount() == (i + 1)
)
}
CPPUNIT_ASSERT_MESSAGE
(
"test_move_elements_from_lower_to_higher_pos failed",
static_cast<BigPtrEntryMock*>(bparr[NUM_ENTRIES -1])->getCount() == 0
)
CPPUNIT_ASSERT_MESSAGE
(
"test_move_elements_from_lower_to_higher_pos failed",
checkElementPositions(bparr)
)
releaseBigPtrArrayContent(bparr);
}
void 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);
}
CPPUNIT_ASSERT_MESSAGE
(
"test_move_elements_from_higher_to_lower_pos failed",
static_cast<BigPtrEntryMock*>(bparr[0])->getCount() == (NUM_ENTRIES - 1)
)
for (int i = 1; i < NUM_ENTRIES; i++)
{
CPPUNIT_ASSERT_MESSAGE
(
"test_move_elements_from_higher_to_lower_pos failed",
static_cast<BigPtrEntryMock*>(bparr[i])->getCount() == (i - 1)
)
}
CPPUNIT_ASSERT_MESSAGE
(
"test_move_elements_from_higher_to_lower_pos failed",
checkElementPositions(bparr)
)
releaseBigPtrArrayContent(bparr);
}
void 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);
}
dumpBigPtrArray(bparr);
for (int i = 0; i < NUM_ENTRIES; i++)
{
CPPUNIT_ASSERT_MESSAGE
(
"test_move_to_same_position failed",
static_cast<BigPtrEntryMock*>(bparr[i])->getCount() == i
)
}
CPPUNIT_ASSERT_MESSAGE
(
"test_move_to_same_position failed",
checkElementPositions(bparr)
)
releaseBigPtrArrayContent(bparr);
dumpBigPtrArray(bparr);
}
void 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++)
{
CPPUNIT_ASSERT_MESSAGE
(
"test_replace_elements failed",
static_cast<BigPtrEntryMock*>(bparr[i])->getCount() == (NUM_ENTRIES - i - 1)
)
}
CPPUNIT_ASSERT_MESSAGE
(
"test_replace_elements failed",
checkElementPositions(bparr)
)
releaseBigPtrArrayContent(bparr);
}
void 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++)
{
CPPUNIT_ASSERT_MESSAGE
(
"test_for_each failed",
static_cast<BigPtrEntryMock*>(bparr[i])->getCount() == (i+1)
)
}
releaseBigPtrArrayContent(bparr);
dumpBigPtrArray(bparr);
}
void 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++)
{
CPPUNIT_ASSERT_MESSAGE
(
"test_for_some1 failed",
static_cast<BigPtrEntryMock*>(bparr[i])->getCount() == (i+1)
)
}
for (/* */; i < NUM_ENTRIES; i++)
{
CPPUNIT_ASSERT_MESSAGE
(
"test_for_some1 failed",
static_cast<BigPtrEntryMock*>(bparr[i])->getCount() == (i)
)
}
releaseBigPtrArrayContent(bparr);
dumpBigPtrArray(bparr);
}
void 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++)
{
CPPUNIT_ASSERT_MESSAGE
(
"test_for_some2 failed",
static_cast<BigPtrEntryMock*>(bparr[i])->getCount() == (i)
)
}
for (/* */; i < NUM_ENTRIES; i++)
{
CPPUNIT_ASSERT_MESSAGE
(
"test_for_some2 failed",
static_cast<BigPtrEntryMock*>(bparr[i])->getCount() == (i+1)
)
}
releaseBigPtrArrayContent(bparr);
dumpBigPtrArray(bparr);
}
void 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++)
{
CPPUNIT_ASSERT_MESSAGE
(
"test_for_some3 failed",
static_cast<BigPtrEntryMock*>(bparr[i])->getCount() == i
)
}
releaseBigPtrArrayContent(bparr);
}
CPPUNIT_TEST_SUITE(BigPtrArrayUnittest);
CPPUNIT_TEST(test_ctor);
CPPUNIT_TEST(test_insert_entries_at_front);
CPPUNIT_TEST(test_insert_entries_in_the_middle);
CPPUNIT_TEST(test_insert_at_already_used_index);
CPPUNIT_TEST(test_insert_at_end);
CPPUNIT_TEST(test_remove_at_front);
CPPUNIT_TEST(test_remove_at_back);
CPPUNIT_TEST(test_remove_in_the_middle);
CPPUNIT_TEST(test_remove_multiple_elements_at_once);
CPPUNIT_TEST(test_remove_all_elements_at_once);
CPPUNIT_TEST(test_move_elements_from_lower_to_higher_pos);
CPPUNIT_TEST(test_move_elements_from_higher_to_lower_pos);
CPPUNIT_TEST(test_replace_elements);
CPPUNIT_TEST(test_for_each);
CPPUNIT_TEST(test_for_some1);
CPPUNIT_TEST(test_for_some2);
CPPUNIT_TEST(test_for_some3);
CPPUNIT_TEST_SUITE_END();
};
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 CppUnit::TestFixture
{
public:
BigPtrArrayPerformanceTest()
{
}
void test_insert_at_end_1000()
{ test_insert_at_end("1000"); }
void test_insert_at_end_10000()
{ test_insert_at_end("10000"); }
void test_insert_at_end_100000()
{ test_insert_at_end("100000"); }
void test_insert_at_end_1000000()
{ test_insert_at_end("1000000"); }
void test_insert_at_front_1000()
{ test_insert_at_front("1000"); }
void test_insert_at_front_10000()
{ test_insert_at_front("10000"); }
void test_insert_at_front_100000()
{ test_insert_at_front("100000"); }
void test_insert_at_front_1000000()
{ test_insert_at_front("1000000"); }
CPPUNIT_TEST_SUITE(BigPtrArrayPerformanceTest);
CPPUNIT_TEST(test_insert_at_end_1000);
CPPUNIT_TEST(test_insert_at_end_10000);
CPPUNIT_TEST(test_insert_at_end_100000);
CPPUNIT_TEST(test_insert_at_end_1000000);
CPPUNIT_TEST(test_insert_at_front_1000);
CPPUNIT_TEST(test_insert_at_front_10000);
CPPUNIT_TEST(test_insert_at_front_100000);
CPPUNIT_TEST(test_insert_at_front_1000000);
CPPUNIT_TEST_SUITE_END();
private:
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);
}
};
//#####################################
// register test suites
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(BigPtrArrayUnittest, "BigPtrArrayUnittest");
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(BigPtrArrayPerformanceTest, "BigPtrArrayPerformanceTest");
NOADDITIONAL;