From 28a8154cee9d75041a3516df1080e7db21791334 Mon Sep 17 00:00:00 2001 From: Michael Krasnyk Date: Tue, 7 Feb 2017 20:55:02 +0100 Subject: [PATCH] check weights consistency after updates --- features/testbot/weight.feature | 12 +++---- src/contractor/contractor.cpp | 55 ++++++++++++++++++++++++++++++++- 2 files changed, 60 insertions(+), 7 deletions(-) diff --git a/features/testbot/weight.feature b/features/testbot/weight.feature index 14b24c5cc..dcae9025a 100644 --- a/features/testbot/weight.feature +++ b/features/testbot/weight.feature @@ -215,7 +215,7 @@ Feature: Weight tests end function turn_function (turn) print (turn.angle) - turn.weight = turn.angle / 100 + turn.weight = 2 + turn.angle / 100 turn.duration = turn.angle end """ @@ -234,11 +234,11 @@ Feature: Weight tests When I route I should get | waypoints | route | distance | weights | times | - | a,c | , | 40m +-.1 | 3.119,0 | 289.9s,0s | - | a,e | ,, | 60m +-.1 | 3.119,1.11,0 | 289.9s,100s,0s | - | e,a | ,, | 60m +-.1 | 0.211,2.22,0 | 10.1s,200s,0s | - | e,d | ,, | 40m +-.1 | 2.009,1.11,0 | 189.9s,100s,0s | - | d,e | ,, | 40m +-.1 | 0.211,1.11,0 | 10.1s,100s,0s | + | a,c | , | 40m +-.1 | 5.119,0 | 289.9s,0s | + | a,e | ,, | 60m +-.1 | 5.119,1.11,0 | 289.9s,100s,0s | + | e,a | ,, | 60m +-.1 | 2.21,2.22,0 | 10.1s,200s,0s | + | e,d | ,, | 40m +-.1 | 4.009,1.11,0 | 189.9s,100s,0s | + | d,e | ,, | 40m +-.1 | 2.21,1.11,0 | 10.1s,100s,0s | Scenario: Step weights -- segment_function with speed and turn updates Given the profile file "testbot" extended with diff --git a/src/contractor/contractor.cpp b/src/contractor/contractor.cpp index f677faca1..e279cf9e0 100644 --- a/src/contractor/contractor.cpp +++ b/src/contractor/contractor.cpp @@ -116,6 +116,51 @@ template inline bool is_aligned(const void *pointer) static_assert(sizeof(T) % alignof(T) == 0, "pointer can not be used as an array pointer"); return reinterpret_cast(pointer) % alignof(T) == 0; } + +void CheckWeightsConsistency( + const osrm::contractor::ContractorConfig &config, + const std::vector &edge_based_edge_list) +{ + using Reader = osrm::storage::io::FileReader; + using OriginalEdgeData = osrm::extractor::OriginalEdgeData; + + Reader geometry_file(config.geometry_path, Reader::HasNoFingerprint); + const auto number_of_indices = geometry_file.ReadElementCount32(); + std::vector geometry_indices(number_of_indices); + geometry_file.ReadInto(geometry_indices); + + const auto number_of_compressed_geometries = geometry_file.ReadElementCount32(); + BOOST_ASSERT(geometry_indices.back() == number_of_compressed_geometries); + if (number_of_compressed_geometries == 0) + return; + + std::vector geometry_node_list(number_of_compressed_geometries); + std::vector forward_weight_list(number_of_compressed_geometries); + std::vector reverse_weight_list(number_of_compressed_geometries); + geometry_file.ReadInto(geometry_node_list.data(), number_of_compressed_geometries); + geometry_file.ReadInto(forward_weight_list.data(), number_of_compressed_geometries); + geometry_file.ReadInto(reverse_weight_list.data(), number_of_compressed_geometries); + + Reader edges_input_file(config.osrm_input_path.string() + ".edges", Reader::HasNoFingerprint); + std::vector current_edge_data(edges_input_file.ReadElementCount64()); + edges_input_file.ReadInto(current_edge_data); + + for (auto &edge : edge_based_edge_list) + { + BOOST_ASSERT(edge.edge_id < current_edge_data.size()); + auto geometry_id = current_edge_data[edge.edge_id].via_geometry; + BOOST_ASSERT(geometry_id.id < geometry_indices.size()); + + const auto &weights = geometry_id.forward ? forward_weight_list : reverse_weight_list; + const int shift = static_cast(geometry_id.forward); + const auto first = weights.begin() + geometry_indices.at(geometry_id.id) + shift; + const auto last = weights.begin() + geometry_indices.at(geometry_id.id + 1) - 1 + shift; + EdgeWeight weight = std::accumulate(first, last, 0); + + BOOST_ASSERT(weight <= edge.weight); + } +} + } // anon ns BOOST_FUSION_ADAPT_STRUCT(Segment, (decltype(Segment::from), from)(decltype(Segment::to), to)) @@ -454,7 +499,7 @@ Contractor::LoadEdgeExpandedGraph(const ContractorConfig &config, throw util::exception("Incompatible file version" + SOURCE_REF); } - edge_based_edge_list.resize(graph_header.number_of_edges); + edge_based_edge_list.reserve(graph_header.number_of_edges); util::Log() << "Reading " << graph_header.number_of_edges << " edges from the edge based graph"; auto segment_speed_lookup = CSVFilesParser( @@ -873,6 +918,14 @@ Contractor::LoadEdgeExpandedGraph(const ContractorConfig &config, [&] { save_penalties(config.turn_duration_penalties_path, turn_duration_penalties); }); } +#if !defined(NDEBUG) + if (!update_turn_penalties) + { // don't check weights consistency with turn updates that can break assertion + // condition with turn weight penalties negative updates + CheckWeightsConsistency(config, edge_based_edge_list); + } +#endif + util::Log() << "Done reading edges"; return graph_header.max_edge_id; }