/* * Copyright (c) 2014, Siemens AG. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include static bool DescendingComparisonFunction(double lhs, double rhs) { if (lhs < rhs) { return true; } else { return false; } } QuickSortTest::QuickSortTest() { CreateUnit("Different data structures") .Add(&QuickSortTest::TestDataStructures, this); CreateUnit("Function Pointers").Add(&QuickSortTest::TestFunctionPointers, this); CreateUnit("Ranges").Add(&QuickSortTest::TestRanges, this); CreateUnit("Block sizes").Add(&QuickSortTest::TestBlockSizes, this); CreateUnit("Policies").Add(&QuickSortTest::TestPolicy, this); CreateUnit("Stress test").Add(&QuickSortTest::StressTest, this); } void QuickSortTest::TestDataStructures() { using embb::algorithms::QuickSort; using embb::algorithms::ExecutionPolicy; int array[kCountSize]; std::vector vector(kCountSize); std::deque deque(kCountSize); for (size_t i = 0; i < kCountSize; i++) { array[i] = static_cast(i+2); vector[i] = static_cast(i+2); deque[i] = static_cast(i+2); } std::vector vector_copy(vector); std::sort(vector_copy.begin(), vector_copy.end()); QuickSort(array, array + kCountSize, std::less()); QuickSort(vector.begin(), vector.end()); QuickSort(array, array + kCountSize, std::less(), ExecutionPolicy(), 1); QuickSort(deque.begin(), deque.end()); for (size_t i = 0; i < kCountSize; i++) { PT_EXPECT_EQ(vector_copy[i], array[i]); PT_EXPECT_EQ(vector_copy[i], vector[i]); PT_EXPECT_EQ(vector_copy[i], deque[i]); } } void QuickSortTest::TestFunctionPointers() { using embb::algorithms::QuickSort; std::vector vector(kCountSize); for (size_t i = 0; i < kCountSize; i++) { vector[i] = static_cast(i + 2); } std::vector vector_copy(vector); std::sort(vector_copy.begin(), vector_copy.end(), &DescendingComparisonFunction); QuickSort(vector.begin(), vector.end(), &DescendingComparisonFunction); for (size_t i = 0; i < kCountSize; i++) { PT_EXPECT_EQ(vector_copy[i], vector[i]); } } void QuickSortTest::TestRanges() { using embb::algorithms::QuickSort; size_t count = 4; std::vector init(count); std::vector vector(count); std::vector vector_copy(count); for (size_t i = 0; i < count; i++) { init[i] = static_cast(i+2); } // Ommit first element vector = init; vector_copy = init; std::sort(vector_copy.begin() + 1, vector_copy.end(), std::greater()); QuickSort(vector.begin() + 1, vector.end(), std::greater()); for (size_t i = 0; i < count; i++) { PT_EXPECT_EQ(vector_copy[i], vector[i]); } // Ommit last element vector = init; vector_copy = init; std::sort(vector_copy.begin(), vector_copy.end() - 1, std::greater()); QuickSort(vector.begin(), vector.end() - 1, std::greater()); for (size_t i = 0; i < count; i++) { PT_EXPECT_EQ(vector_copy[i], vector[i]); } // Ommit first and last element vector = init; vector_copy = init; std::sort(vector_copy.begin() + 1, vector_copy.end() - 1, std::greater()); QuickSort(vector.begin() + 1, vector.end() - 1, std::greater()); for (size_t i = 0; i < count; i++) { PT_EXPECT_EQ(vector_copy[i], vector[i]); } // Only do first two elements vector = init; vector_copy = init; std::sort(vector_copy.begin(), vector_copy.begin() + 2, std::greater()); QuickSort(vector.begin(), vector.begin() + 2, std::greater()); for (size_t i = 0; i < count; i++) { PT_EXPECT_EQ(vector_copy[i], vector[i]); } // Only do last two elements vector = init; vector_copy = init; std::sort(vector_copy.end() - 2, vector_copy.end(), std::greater()); QuickSort(vector.end() - 2, vector.end(), std::greater()); for (size_t i = 0; i < count; i++) { PT_EXPECT_EQ(vector_copy[i], vector[i]); } // Only do second & third elements vector = init; vector_copy = init; std::sort(vector_copy.begin() + 1, vector_copy.begin() + 3, std::greater()); QuickSort(vector.begin() + 1, vector.begin() + 3, std::greater()); for (size_t i = 0; i < count; i++) { PT_EXPECT_EQ(vector_copy[i], vector[i]); } } void QuickSortTest::TestBlockSizes() { using embb::algorithms::QuickSort; using embb::algorithms::ExecutionPolicy; size_t count = 4; std::vector init(count); std::vector vector(count); std::vector vector_copy(count); for (size_t i = 0; i < count; i++) { init[i] = static_cast(i+2); } vector_copy = init; std::sort(vector_copy.begin(), vector_copy.end(), std::greater()); for (size_t block_size = 1; block_size < count + 2; block_size++) { vector = init; QuickSort(vector.begin(), vector.end(), std::greater(), ExecutionPolicy(), block_size); for (size_t i = 0; i < count; i++) { PT_EXPECT_EQ(vector[i], vector_copy[i]); } } } void QuickSortTest::TestPolicy() { using embb::algorithms::QuickSort; using embb::algorithms::ExecutionPolicy; size_t count = 4; std::vector init(count); std::vector vector(count); std::vector vector_copy(count); for (size_t i = 0; i < count; i++) { init[i] = static_cast(i+2); } vector = init; vector_copy = init; std::sort(vector_copy.begin(), vector_copy.end(), std::greater()); QuickSort(vector.begin(), vector.end(), std::greater(), ExecutionPolicy()); for (size_t i = 0; i < count; i++) { PT_EXPECT_EQ(vector_copy[i], vector[i]); } vector = init; QuickSort(vector.begin(), vector.end(), std::greater(), ExecutionPolicy(true)); for (size_t i = 0; i < count; i++) { PT_EXPECT_EQ(vector_copy[i], vector[i]); } vector = init; QuickSort(vector.begin(), vector.end(), std::greater(), ExecutionPolicy(false)); for (size_t i = 0; i < count; i++) { PT_EXPECT_EQ(vector_copy[i], vector[i]); } vector = init; QuickSort(vector.begin(), vector.end(), std::greater(), ExecutionPolicy(true, 1)); for (size_t i = 0; i < count; i++) { PT_EXPECT_EQ(vector_copy[i], vector[i]); } } void QuickSortTest::StressTest() { using embb::algorithms::QuickSort; size_t count = embb::mtapi::Node::GetInstance().GetCoreCount() *10; std::vector large_vector(count); std::vector vector_copy(count); for (size_t i = 0; i < count; i++) { large_vector[i] = static_cast((i + 2) % 1000); } vector_copy = large_vector; std::sort(vector_copy.begin(), vector_copy.end(), std::greater()); QuickSort(large_vector.begin(), large_vector.end(), std::greater()); for (size_t i = 0; i < count; i++) { PT_EXPECT_EQ(large_vector[i], vector_copy[i]); } }