First step of moving turn penalty update to own function
This commit is contained in:
parent
acbaecf45d
commit
5ab882759d
@ -379,6 +379,78 @@ void saveDatasourcesNames(const UpdaterConfig &config)
|
|||||||
|
|
||||||
extractor::io::write(config.datasource_names_path, sources);
|
extractor::io::write(config.datasource_names_path, sources);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using TurnWeightAndDuration = std::tuple<std::vector<TurnPenalty>, std::vector<TurnPenalty>, bool>;
|
||||||
|
TurnWeightAndDuration
|
||||||
|
loadAndUpdateTurnPenalties(const UpdaterConfig &config,
|
||||||
|
const extractor::ProfileProperties &profile_properties,
|
||||||
|
const TurnLookupTable &turn_penalty_lookup)
|
||||||
|
{
|
||||||
|
const auto weight_multiplier = profile_properties.GetWeightMultiplier();
|
||||||
|
const auto turn_penalties_index_region =
|
||||||
|
mmapFile(config.turn_penalties_index_path, boost::interprocess::read_only);
|
||||||
|
|
||||||
|
std::vector<TurnPenalty> turn_weight_penalties;
|
||||||
|
std::vector<TurnPenalty> turn_duration_penalties;
|
||||||
|
|
||||||
|
const auto load_turn_weight_penalties = [&] {
|
||||||
|
using storage::io::FileReader;
|
||||||
|
FileReader file(config.turn_weight_penalties_path, FileReader::HasNoFingerprint);
|
||||||
|
file.DeserializeVector(turn_weight_penalties);
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto load_turn_duration_penalties = [&] {
|
||||||
|
using storage::io::FileReader;
|
||||||
|
FileReader file(config.turn_duration_penalties_path, FileReader::HasNoFingerprint);
|
||||||
|
file.DeserializeVector(turn_duration_penalties);
|
||||||
|
};
|
||||||
|
|
||||||
|
tbb::parallel_invoke(load_turn_weight_penalties, load_turn_duration_penalties);
|
||||||
|
|
||||||
|
bool fallback_to_duration = false;
|
||||||
|
if (turn_duration_penalties.empty())
|
||||||
|
{ // Copy-on-write for duration penalties as turn weight penalties
|
||||||
|
turn_duration_penalties = turn_weight_penalties;
|
||||||
|
fallback_to_duration = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mapped file pointer for turn indices
|
||||||
|
const extractor::lookup::TurnIndexBlock *turn_index_blocks =
|
||||||
|
reinterpret_cast<const extractor::lookup::TurnIndexBlock *>(
|
||||||
|
turn_penalties_index_region.get_address());
|
||||||
|
BOOST_ASSERT(is_aligned<extractor::lookup::TurnIndexBlock>(turn_index_blocks));
|
||||||
|
|
||||||
|
for (std::uint64_t edge_index = 0; edge_index < turn_weight_penalties.size(); ++edge_index)
|
||||||
|
{
|
||||||
|
// Get the turn penalty and update to the new value if required
|
||||||
|
const auto &turn_index = turn_index_blocks[edge_index];
|
||||||
|
auto turn_weight_penalty = turn_weight_penalties[edge_index];
|
||||||
|
auto turn_duration_penalty = turn_duration_penalties[edge_index];
|
||||||
|
if (auto value = turn_penalty_lookup(turn_index))
|
||||||
|
{
|
||||||
|
turn_duration_penalty =
|
||||||
|
boost::numeric_cast<TurnPenalty>(std::round(value->duration * 10.));
|
||||||
|
turn_weight_penalty = boost::numeric_cast<TurnPenalty>(std::round(
|
||||||
|
std::isfinite(value->weight) ? value->weight * weight_multiplier
|
||||||
|
: turn_duration_penalty * weight_multiplier / 10.));
|
||||||
|
|
||||||
|
turn_duration_penalties[edge_index] = turn_duration_penalty;
|
||||||
|
turn_weight_penalties[edge_index] = turn_weight_penalty;
|
||||||
|
|
||||||
|
// Is fallback of duration to weight values allowed
|
||||||
|
fallback_to_duration &= (turn_duration_penalty == turn_weight_penalty);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (turn_weight_penalty < 0)
|
||||||
|
{
|
||||||
|
util::Log(logWARNING) << "Negative turn penalty at " << turn_index.from_id << ", "
|
||||||
|
<< turn_index.via_id << ", " << turn_index.to_id
|
||||||
|
<< ": turn penalty " << turn_weight_penalty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_tuple(std::move(turn_weight_penalties), std::move(turn_duration_penalties), fallback_to_duration);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Updater::NumNodesAndEdges Updater::LoadAndUpdateEdgeExpandedGraph() const
|
Updater::NumNodesAndEdges Updater::LoadAndUpdateEdgeExpandedGraph() const
|
||||||
@ -400,7 +472,6 @@ Updater::LoadAndUpdateEdgeExpandedGraph(std::vector<extractor::EdgeBasedEdge> &e
|
|||||||
storage::io::FileReader profile_properties_file(config.profile_properties_path,
|
storage::io::FileReader profile_properties_file(config.profile_properties_path,
|
||||||
storage::io::FileReader::HasNoFingerprint);
|
storage::io::FileReader::HasNoFingerprint);
|
||||||
profile_properties_file.ReadInto<extractor::ProfileProperties>(&profile_properties, 1);
|
profile_properties_file.ReadInto<extractor::ProfileProperties>(&profile_properties, 1);
|
||||||
auto weight_multiplier = profile_properties.GetWeightMultiplier();
|
|
||||||
|
|
||||||
if (config.segment_speed_lookup_paths.size() + config.turn_penalty_lookup_paths.size() > 255)
|
if (config.segment_speed_lookup_paths.size() + config.turn_penalty_lookup_paths.size() > 255)
|
||||||
throw util::exception("Limit of 255 segment speed and turn penalty files each reached" +
|
throw util::exception("Limit of 255 segment speed and turn penalty files each reached" +
|
||||||
@ -414,14 +485,6 @@ Updater::LoadAndUpdateEdgeExpandedGraph(std::vector<extractor::EdgeBasedEdge> &e
|
|||||||
const bool update_edge_weights = !config.segment_speed_lookup_paths.empty();
|
const bool update_edge_weights = !config.segment_speed_lookup_paths.empty();
|
||||||
const bool update_turn_penalties = !config.turn_penalty_lookup_paths.empty();
|
const bool update_turn_penalties = !config.turn_penalty_lookup_paths.empty();
|
||||||
|
|
||||||
const auto turn_penalties_index_region = [&] {
|
|
||||||
if (update_edge_weights || update_turn_penalties)
|
|
||||||
{
|
|
||||||
return mmapFile(config.turn_penalties_index_path, boost::interprocess::read_only);
|
|
||||||
}
|
|
||||||
return boost::interprocess::mapped_region();
|
|
||||||
}();
|
|
||||||
|
|
||||||
// Set the struct packing to 1 byte word sizes. This prevents any padding. We only use
|
// Set the struct packing to 1 byte word sizes. This prevents any padding. We only use
|
||||||
// this struct once, so any alignment penalty is trivial. If this is *not* done, then
|
// this struct once, so any alignment penalty is trivial. If this is *not* done, then
|
||||||
// the struct will be padded out by an extra 4 bytes, and sizeof() will mean we read
|
// the struct will be padded out by an extra 4 bytes, and sizeof() will mean we read
|
||||||
@ -462,8 +525,6 @@ Updater::LoadAndUpdateEdgeExpandedGraph(std::vector<extractor::EdgeBasedEdge> &e
|
|||||||
edge_based_edge_list.reserve(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";
|
util::Log() << "Reading " << graph_header.number_of_edges << " edges from the edge based graph";
|
||||||
|
|
||||||
auto turn_penalty_lookup = csv::readTurnValues(config.turn_penalty_lookup_paths);
|
|
||||||
|
|
||||||
storage::io::FileReader edges_input_file(config.osrm_input_path.string() + ".edges",
|
storage::io::FileReader edges_input_file(config.osrm_input_path.string() + ".edges",
|
||||||
storage::io::FileReader::HasNoFingerprint);
|
storage::io::FileReader::HasNoFingerprint);
|
||||||
std::vector<extractor::OriginalEdgeData> edge_data(edges_input_file.ReadElementCount64());
|
std::vector<extractor::OriginalEdgeData> edge_data(edges_input_file.ReadElementCount64());
|
||||||
@ -490,35 +551,35 @@ Updater::LoadAndUpdateEdgeExpandedGraph(std::vector<extractor::EdgeBasedEdge> &e
|
|||||||
|
|
||||||
std::vector<TurnPenalty> turn_weight_penalties;
|
std::vector<TurnPenalty> turn_weight_penalties;
|
||||||
std::vector<TurnPenalty> turn_duration_penalties;
|
std::vector<TurnPenalty> turn_duration_penalties;
|
||||||
|
bool fallback_to_duration = true;
|
||||||
const auto maybe_load_turn_weight_penalties = [&] {
|
if (update_turn_penalties)
|
||||||
if (!update_edge_weights && !update_turn_penalties)
|
{
|
||||||
return;
|
auto turn_penalty_lookup = csv::readTurnValues(config.turn_penalty_lookup_paths);
|
||||||
using storage::io::FileReader;
|
std::tie(turn_weight_penalties, turn_duration_penalties, fallback_to_duration) =
|
||||||
FileReader file(config.turn_weight_penalties_path, FileReader::HasNoFingerprint);
|
loadAndUpdateTurnPenalties(config, profile_properties, turn_penalty_lookup);
|
||||||
file.DeserializeVector(turn_weight_penalties);
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto maybe_load_turn_duration_penalties = [&] {
|
|
||||||
if (!update_edge_weights && !update_turn_penalties)
|
|
||||||
return;
|
|
||||||
using storage::io::FileReader;
|
|
||||||
FileReader file(config.turn_duration_penalties_path, FileReader::HasNoFingerprint);
|
|
||||||
file.DeserializeVector(turn_duration_penalties);
|
|
||||||
};
|
|
||||||
|
|
||||||
tbb::parallel_invoke(maybe_load_turn_weight_penalties, maybe_load_turn_duration_penalties);
|
|
||||||
|
|
||||||
if ((update_edge_weights || update_turn_penalties) && turn_duration_penalties.empty())
|
|
||||||
{ // Copy-on-write for duration penalties as turn weight penalties
|
|
||||||
turn_duration_penalties = turn_weight_penalties;
|
|
||||||
}
|
}
|
||||||
|
else if (update_edge_weights)
|
||||||
|
{
|
||||||
|
const auto load_turn_weight_penalties = [&] {
|
||||||
|
using storage::io::FileReader;
|
||||||
|
FileReader file(config.turn_weight_penalties_path, FileReader::HasNoFingerprint);
|
||||||
|
file.DeserializeVector(turn_weight_penalties);
|
||||||
|
};
|
||||||
|
|
||||||
// Mapped file pointer for turn indices
|
const auto load_turn_duration_penalties = [&] {
|
||||||
const extractor::lookup::TurnIndexBlock *turn_index_blocks =
|
using storage::io::FileReader;
|
||||||
reinterpret_cast<const extractor::lookup::TurnIndexBlock *>(
|
FileReader file(config.turn_duration_penalties_path, FileReader::HasNoFingerprint);
|
||||||
turn_penalties_index_region.get_address());
|
file.DeserializeVector(turn_duration_penalties);
|
||||||
BOOST_ASSERT(is_aligned<extractor::lookup::TurnIndexBlock>(turn_index_blocks));
|
};
|
||||||
|
|
||||||
|
tbb::parallel_invoke(load_turn_weight_penalties, load_turn_duration_penalties);
|
||||||
|
if (turn_duration_penalties.empty())
|
||||||
|
{ // Copy-on-write for duration penalties as turn weight penalties
|
||||||
|
turn_duration_penalties = turn_weight_penalties;
|
||||||
|
fallback_to_duration = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Mapped file pointers for edge-based graph edges
|
// Mapped file pointers for edge-based graph edges
|
||||||
auto edge_based_edge_ptr = reinterpret_cast<const extractor::EdgeBasedEdge *>(
|
auto edge_based_edge_ptr = reinterpret_cast<const extractor::EdgeBasedEdge *>(
|
||||||
@ -526,7 +587,6 @@ Updater::LoadAndUpdateEdgeExpandedGraph(std::vector<extractor::EdgeBasedEdge> &e
|
|||||||
sizeof(EdgeBasedGraphHeader));
|
sizeof(EdgeBasedGraphHeader));
|
||||||
BOOST_ASSERT(is_aligned<extractor::EdgeBasedEdge>(edge_based_edge_ptr));
|
BOOST_ASSERT(is_aligned<extractor::EdgeBasedEdge>(edge_based_edge_ptr));
|
||||||
|
|
||||||
bool fallback_to_duration = true;
|
|
||||||
for (std::uint64_t edge_index = 0; edge_index < graph_header.number_of_edges; ++edge_index)
|
for (std::uint64_t edge_index = 0; edge_index < graph_header.number_of_edges; ++edge_index)
|
||||||
{
|
{
|
||||||
// Make a copy of the data from the memory map
|
// Make a copy of the data from the memory map
|
||||||
@ -605,44 +665,23 @@ Updater::LoadAndUpdateEdgeExpandedGraph(std::vector<extractor::EdgeBasedEdge> &e
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Get the turn penalty and update to the new value if required
|
// Get the turn penalty and update to the new value if required
|
||||||
const auto &turn_index = turn_index_blocks[edge_index];
|
|
||||||
auto turn_weight_penalty = turn_weight_penalties[edge_index];
|
auto turn_weight_penalty = turn_weight_penalties[edge_index];
|
||||||
auto turn_duration_penalty = turn_duration_penalties[edge_index];
|
auto turn_duration_penalty = turn_duration_penalties[edge_index];
|
||||||
if (auto value = turn_penalty_lookup(turn_index))
|
const auto num_nodes = segment_data.GetForwardGeometry(geometry_id.id).size();
|
||||||
|
const auto weight_min_value = static_cast<EdgeWeight>(num_nodes);
|
||||||
|
if (turn_weight_penalty + new_weight < weight_min_value)
|
||||||
{
|
{
|
||||||
turn_duration_penalty =
|
util::Log(logWARNING) << "turn penalty " << turn_weight_penalty
|
||||||
boost::numeric_cast<TurnPenalty>(std::round(value->duration * 10.));
|
<< " is too negative: clamping turn weight to "
|
||||||
turn_weight_penalty = boost::numeric_cast<TurnPenalty>(
|
<< weight_min_value;
|
||||||
std::round(std::isfinite(value->weight)
|
|
||||||
? value->weight * weight_multiplier
|
|
||||||
: turn_duration_penalty * weight_multiplier / 10.));
|
|
||||||
|
|
||||||
const auto num_nodes = segment_data.GetForwardGeometry(geometry_id.id).size();
|
turn_weight_penalty = weight_min_value - new_weight;
|
||||||
const auto weight_min_value = static_cast<EdgeWeight>(num_nodes);
|
|
||||||
if (turn_weight_penalty + new_weight < weight_min_value)
|
|
||||||
{
|
|
||||||
util::Log(logWARNING) << "turn penalty " << turn_weight_penalty << " for turn "
|
|
||||||
<< turn_index.from_id << ", " << turn_index.via_id << ", "
|
|
||||||
<< turn_index.to_id
|
|
||||||
<< " is too negative: clamping turn weight to "
|
|
||||||
<< weight_min_value;
|
|
||||||
|
|
||||||
turn_weight_penalty = weight_min_value - new_weight;
|
|
||||||
}
|
|
||||||
|
|
||||||
turn_duration_penalties[edge_index] = turn_duration_penalty;
|
|
||||||
turn_weight_penalties[edge_index] = turn_weight_penalty;
|
|
||||||
|
|
||||||
// Is fallback of duration to weight values allowed
|
|
||||||
fallback_to_duration &= (turn_duration_penalty == turn_weight_penalty);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (turn_weight_penalty < 0)
|
turn_weight_penalties[edge_index] = turn_weight_penalty;
|
||||||
{
|
|
||||||
util::Log(logWARNING) << "Negative turn penalty at " << turn_index.from_id << ", "
|
// Is fallback of duration to weight values allowed
|
||||||
<< turn_index.via_id << ", " << turn_index.to_id
|
fallback_to_duration &= (turn_duration_penalty == turn_weight_penalty);
|
||||||
<< ": turn penalty " << turn_weight_penalty;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update edge weight
|
// Update edge weight
|
||||||
inbuffer.data.weight = new_weight + turn_weight_penalty;
|
inbuffer.data.weight = new_weight + turn_weight_penalty;
|
||||||
|
Loading…
Reference in New Issue
Block a user