Add test for BinaryHeap
This commit is contained in:
parent
9f9fde1f2b
commit
8d46ee85f1
@ -41,8 +41,9 @@ add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/Util/FingerPrint.cpp FingerPrint.c
|
|||||||
VERBATIM)
|
VERBATIM)
|
||||||
|
|
||||||
add_custom_target(FingerPrintConfigure DEPENDS ${CMAKE_SOURCE_DIR}/Util/FingerPrint.cpp)
|
add_custom_target(FingerPrintConfigure DEPENDS ${CMAKE_SOURCE_DIR}/Util/FingerPrint.cpp)
|
||||||
|
add_custom_target(tests DEPENDS datastructure-tests)
|
||||||
|
|
||||||
set(BOOST_COMPONENTS date_time filesystem iostreams program_options regex system thread)
|
set(BOOST_COMPONENTS date_time filesystem iostreams program_options regex system thread unit_test_framework)
|
||||||
|
|
||||||
configure_file(
|
configure_file(
|
||||||
${CMAKE_SOURCE_DIR}/Util/GitDescription.cpp.in
|
${CMAKE_SOURCE_DIR}/Util/GitDescription.cpp.in
|
||||||
@ -65,6 +66,7 @@ file(GLOB CoordinateGlob DataStructures/Coordinate.cpp)
|
|||||||
file(GLOB AlgorithmGlob Algorithms/*.cpp)
|
file(GLOB AlgorithmGlob Algorithms/*.cpp)
|
||||||
file(GLOB HttpGlob Server/Http/*.cpp)
|
file(GLOB HttpGlob Server/Http/*.cpp)
|
||||||
file(GLOB LibOSRMGlob Library/*.cpp)
|
file(GLOB LibOSRMGlob Library/*.cpp)
|
||||||
|
file(GLOB DataStructureTestsGlob UnitTests/DataStructures/*.cpp)
|
||||||
|
|
||||||
set(
|
set(
|
||||||
OSRMSources
|
OSRMSources
|
||||||
@ -84,6 +86,9 @@ add_dependencies(FINGERPRINT FingerPrintConfigure)
|
|||||||
add_executable(osrm-routed routed.cpp ${ServerGlob})
|
add_executable(osrm-routed routed.cpp ${ServerGlob})
|
||||||
add_executable(osrm-datastore datastore.cpp)
|
add_executable(osrm-datastore datastore.cpp)
|
||||||
|
|
||||||
|
# Unit tests
|
||||||
|
add_executable(datastructure-tests EXCLUDE_FROM_ALL UnitTests/datastructure_tests.cpp ${DataStructureTestsGlob})
|
||||||
|
|
||||||
# Check the release mode
|
# Check the release mode
|
||||||
if(NOT CMAKE_BUILD_TYPE MATCHES Debug)
|
if(NOT CMAKE_BUILD_TYPE MATCHES Debug)
|
||||||
set(CMAKE_BUILD_TYPE Release)
|
set(CMAKE_BUILD_TYPE Release)
|
||||||
@ -114,6 +119,8 @@ if(CMAKE_BUILD_TYPE MATCHES Release)
|
|||||||
endif (HAS_LTO_FLAG)
|
endif (HAS_LTO_FLAG)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
add_definitions(-DBOOST_TEST_DYN_LINK)
|
||||||
|
|
||||||
# Configuring compilers
|
# Configuring compilers
|
||||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||||
# using Clang
|
# using Clang
|
||||||
@ -190,6 +197,8 @@ target_link_libraries(osrm-prepare ${Boost_LIBRARIES} FINGERPRINT GITDESCRIPTION
|
|||||||
target_link_libraries(osrm-routed ${Boost_LIBRARIES} ${OPTIONAL_SOCKET_LIBS} OSRM FINGERPRINT GITDESCRIPTION)
|
target_link_libraries(osrm-routed ${Boost_LIBRARIES} ${OPTIONAL_SOCKET_LIBS} OSRM FINGERPRINT GITDESCRIPTION)
|
||||||
target_link_libraries(osrm-datastore ${Boost_LIBRARIES} FINGERPRINT GITDESCRIPTION COORDLIB)
|
target_link_libraries(osrm-datastore ${Boost_LIBRARIES} FINGERPRINT GITDESCRIPTION COORDLIB)
|
||||||
|
|
||||||
|
target_link_libraries(datastructure-tests ${Boost_LIBRARIES})
|
||||||
|
|
||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
target_link_libraries(osrm-extract ${CMAKE_THREAD_LIBS_INIT})
|
target_link_libraries(osrm-extract ${CMAKE_THREAD_LIBS_INIT})
|
||||||
target_link_libraries(osrm-datastore ${CMAKE_THREAD_LIBS_INIT})
|
target_link_libraries(osrm-datastore ${CMAKE_THREAD_LIBS_INIT})
|
||||||
|
154
UnitTests/DataStructures/BinaryHeapTest.cpp
Normal file
154
UnitTests/DataStructures/BinaryHeapTest.cpp
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
#include "../../DataStructures/BinaryHeap.h"
|
||||||
|
#include "../../typedefs.h"
|
||||||
|
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
#include <boost/test/test_case_template.hpp>
|
||||||
|
#include <boost/mpl/list.hpp>
|
||||||
|
|
||||||
|
#include <random>
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE(binary_heap)
|
||||||
|
|
||||||
|
struct TestData
|
||||||
|
{
|
||||||
|
unsigned value;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef NodeID TestNodeID;
|
||||||
|
typedef int TestKey;
|
||||||
|
typedef int TestWeight;
|
||||||
|
typedef boost::mpl::list<ArrayStorage<TestNodeID, TestKey>,
|
||||||
|
MapStorage<TestNodeID, TestKey>,
|
||||||
|
UnorderedMapStorage<TestNodeID, TestKey>> storage_types;
|
||||||
|
|
||||||
|
|
||||||
|
template<unsigned NUM_ELEM>
|
||||||
|
struct RandomDataFixture
|
||||||
|
{
|
||||||
|
RandomDataFixture()
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < NUM_ELEM; i++)
|
||||||
|
{
|
||||||
|
data.push_back(TestData {i*3});
|
||||||
|
weights.push_back((i+1)*100);
|
||||||
|
ids.push_back(i);
|
||||||
|
order.push_back(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Choosen by a fair W20 dice roll
|
||||||
|
std::mt19937 g(15);
|
||||||
|
|
||||||
|
std::shuffle(order.begin(), order.end(), g);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<TestData> data;
|
||||||
|
std::vector<TestWeight> weights;
|
||||||
|
std::vector<TestNodeID> ids;
|
||||||
|
std::vector<unsigned> order;
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr unsigned NUM_NODES = 100;
|
||||||
|
|
||||||
|
BOOST_FIXTURE_TEST_CASE_TEMPLATE(insert_test, T, storage_types, RandomDataFixture<NUM_NODES>)
|
||||||
|
{
|
||||||
|
BinaryHeap<TestNodeID, TestKey, TestWeight, TestData, T> heap(NUM_NODES);
|
||||||
|
|
||||||
|
TestWeight min_weight = std::numeric_limits<TestWeight>::max();
|
||||||
|
TestNodeID min_id;
|
||||||
|
|
||||||
|
for (unsigned idx : order)
|
||||||
|
{
|
||||||
|
BOOST_CHECK(!heap.WasInserted(ids[idx]));
|
||||||
|
|
||||||
|
heap.Insert(ids[idx], weights[idx], data[idx]);
|
||||||
|
|
||||||
|
BOOST_CHECK(heap.WasInserted(ids[idx]));
|
||||||
|
|
||||||
|
if (weights[idx] < min_weight)
|
||||||
|
{
|
||||||
|
min_weight = weights[idx];
|
||||||
|
min_id = ids[idx];
|
||||||
|
}
|
||||||
|
BOOST_CHECK_EQUAL(min_id, heap.Min());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto id : ids)
|
||||||
|
{
|
||||||
|
const auto& d = heap.GetData(id);
|
||||||
|
BOOST_CHECK_EQUAL(d.value, data[id].value);
|
||||||
|
|
||||||
|
const auto& w = heap.GetKey(id);
|
||||||
|
BOOST_CHECK_EQUAL(w, weights[id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FIXTURE_TEST_CASE_TEMPLATE(delete_min_test, T, storage_types, RandomDataFixture<NUM_NODES>)
|
||||||
|
{
|
||||||
|
BinaryHeap<TestNodeID, TestKey, TestWeight, TestData, T> heap(NUM_NODES);
|
||||||
|
|
||||||
|
for (unsigned idx : order)
|
||||||
|
{
|
||||||
|
heap.Insert(ids[idx], weights[idx], data[idx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto id : ids)
|
||||||
|
{
|
||||||
|
BOOST_CHECK(!heap.WasRemoved(id));
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(heap.Min(), id);
|
||||||
|
BOOST_CHECK_EQUAL(id, heap.DeleteMin());
|
||||||
|
if (id+1 < NUM_NODES)
|
||||||
|
BOOST_CHECK_EQUAL(heap.Min(), id+1);
|
||||||
|
|
||||||
|
BOOST_CHECK(heap.WasRemoved(id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FIXTURE_TEST_CASE_TEMPLATE(delete_all_test, T, storage_types, RandomDataFixture<NUM_NODES>)
|
||||||
|
{
|
||||||
|
BinaryHeap<TestNodeID, TestKey, TestWeight, TestData, T> heap(NUM_NODES);
|
||||||
|
|
||||||
|
for (unsigned idx : order)
|
||||||
|
{
|
||||||
|
heap.Insert(ids[idx], weights[idx], data[idx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
heap.DeleteAll();
|
||||||
|
|
||||||
|
BOOST_CHECK(heap.Empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FIXTURE_TEST_CASE_TEMPLATE(decrease_key_test, T, storage_types, RandomDataFixture<10>)
|
||||||
|
{
|
||||||
|
BinaryHeap<TestNodeID, TestKey, TestWeight, TestData, T> heap(10);
|
||||||
|
|
||||||
|
for (unsigned idx : order)
|
||||||
|
{
|
||||||
|
heap.Insert(ids[idx], weights[idx], data[idx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<TestNodeID> rids(ids);
|
||||||
|
std::reverse(rids.begin(), rids.end());
|
||||||
|
|
||||||
|
for (auto id : rids)
|
||||||
|
{
|
||||||
|
TestNodeID min_id = heap.Min();
|
||||||
|
TestWeight min_weight = heap.GetKey(min_id);
|
||||||
|
|
||||||
|
// decrease weight until we reach min weight
|
||||||
|
while (weights[id] > min_weight)
|
||||||
|
{
|
||||||
|
heap.DecreaseKey(id, weights[id]);
|
||||||
|
BOOST_CHECK_EQUAL(heap.Min(), min_id);
|
||||||
|
weights[id]--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// make weight smaller than min
|
||||||
|
weights[id] -= 2;
|
||||||
|
heap.DecreaseKey(id, weights[id]);
|
||||||
|
BOOST_CHECK_EQUAL(heap.Min(), id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
8
UnitTests/datastructure_tests.cpp
Normal file
8
UnitTests/datastructure_tests.cpp
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#define BOOST_TEST_MODULE datastructure tests
|
||||||
|
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file will contain an automatically generated main function.
|
||||||
|
*/
|
||||||
|
|
Loading…
Reference in New Issue
Block a user