Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f04377abff | |||
| e82f678665 | |||
| 4db1b7bea5 | |||
| 32c5f14ed3 | |||
| cbd88c63b9 | |||
| 621e302a38 | |||
| 1db794b2cb | |||
| a1ccedb5bf | |||
| 189f8c3265 | |||
| 12238ebb52 | |||
| b033ac9f0b | |||
| a411589092 | |||
| 45673581ea |
+38
-19
@@ -1,22 +1,7 @@
|
|||||||
# 5.4.0-rc.5
|
# 5.4.1
|
||||||
- Changes from 5.4.0-rc.4
|
- Changes from 5.4.0
|
||||||
- Guidance
|
|
||||||
- Improved detection of obvious name changes
|
|
||||||
- Profiles
|
|
||||||
- The defautl profile for car now excludes HOV only routes in navigation by default
|
|
||||||
- Bugfixes
|
- Bugfixes
|
||||||
- Fixed a bug that could result in endless loops in combination with sliproads
|
- #3016: Fixes shared memory updates while queries are running
|
||||||
|
|
||||||
# 5.4.0-rc.4
|
|
||||||
- Changes from 5.4.0-rc.3
|
|
||||||
- Bugfixes
|
|
||||||
- Fixed a bug where roundabout intersections could result in breaking assertions when immediately exited
|
|
||||||
|
|
||||||
# 5.4.0-rc.3
|
|
||||||
- Changes from 5.4.0-rc.2
|
|
||||||
- Bugfixes
|
|
||||||
- BREAKING: Fixed a bug where some roads could be falsly identified as sliproadsi This change requires reprocessing datasets with osrm-extract and osrm-contract
|
|
||||||
- BREAKING: Fixed a bug that resulted in false names/ref/destination/pronunciation This change requires reprocessing datasets with osrm-extract and osrm-contract
|
|
||||||
|
|
||||||
# 5.4.0
|
# 5.4.0
|
||||||
- Changes from 5.3.0
|
- Changes from 5.3.0
|
||||||
@@ -42,10 +27,44 @@
|
|||||||
- Fixed a bug where post-processing instructions (e.g. left + left -> uturn) could result in false pronunciations
|
- Fixed a bug where post-processing instructions (e.g. left + left -> uturn) could result in false pronunciations
|
||||||
- Fixes a bug where a bearing range of zero would cause exhaustive graph traversals
|
- Fixes a bug where a bearing range of zero would cause exhaustive graph traversals
|
||||||
- Fixes a bug where certain looped geometries could cause an infinite loop during extraction
|
- Fixes a bug where certain looped geometries could cause an infinite loop during extraction
|
||||||
|
|
||||||
- Infrastructure:
|
- Infrastructure:
|
||||||
- Adds a feature to limit results in nearest service with a default of 100 in `osrm-routed`
|
- Adds a feature to limit results in nearest service with a default of 100 in `osrm-routed`
|
||||||
|
|
||||||
|
# 5.4.0-rc.7
|
||||||
|
- Chages from 5.4.0-rc.6
|
||||||
|
- Bugfixes re-introduce space between two entries in summaries
|
||||||
|
|
||||||
|
# 5.4.0-rc.6
|
||||||
|
- Changes from 5.4.0-rc.5
|
||||||
|
- Bugfixes
|
||||||
|
- fixed a bug where polyline decoding on a defective polyline could end up in out-of-bound access on a vector
|
||||||
|
- Guidance
|
||||||
|
- Summaries have been improved to consider references as well
|
||||||
|
|
||||||
|
# 5.4.0-rc.5
|
||||||
|
- Changes from 5.4.0-rc.4
|
||||||
|
- Guidance
|
||||||
|
- Improved detection of obvious name changes
|
||||||
|
- Profiles
|
||||||
|
- The default profile for car now excludes HOV-only routes in navigation by default
|
||||||
|
- Bugfixes
|
||||||
|
- Fixed a bug that could result in endless loops in combination with sliproads
|
||||||
|
|
||||||
|
# 5.4.0-rc.4
|
||||||
|
- Changes from 5.4.0-rc.3
|
||||||
|
- Bugfixes
|
||||||
|
- Fixed a bug where roundabout intersections could result in breaking assertions when immediately exited
|
||||||
|
|
||||||
|
# 5.4.0-rc.3
|
||||||
|
- Changes from 5.4.0-rc.2
|
||||||
|
- Bugfixes
|
||||||
|
- BREAKING: Fixed a bug where some roads could be falsly identified as sliproadsi This change requires reprocessing datasets with osrm-extract and osrm-contract
|
||||||
|
- BREAKING: Fixed a bug that resulted in false names/ref/destination/pronunciation This change requires reprocessing datasets with osrm-extract and osrm-contract
|
||||||
|
- `restrictions` is now used for namespaced restrictions and restriction exceptions (e.g. `restriction:motorcar=` as well as `except=motorcar`)
|
||||||
|
- replaced lhs/rhs profiles by using test defined profiles
|
||||||
|
- Trip Plugin
|
||||||
|
- changed internal behaviour to prefer the smallest lexicographic result over the largest one
|
||||||
|
|
||||||
# 5.3.0
|
# 5.3.0
|
||||||
- Changes from 5.3.0-rc.3
|
- Changes from 5.3.0-rc.3
|
||||||
- Guidance
|
- Guidance
|
||||||
|
|||||||
+2
-2
@@ -127,8 +127,8 @@ if(ENABLE_GOLD_LINKER)
|
|||||||
|
|
||||||
# Issue 2785: check gold binutils version and don't use gc-sections for versions prior 2.25
|
# Issue 2785: check gold binutils version and don't use gc-sections for versions prior 2.25
|
||||||
string(REGEX REPLACE ".*\\(GNU Binutils[^\\)0-9]+([0-9]+\\.[0-9]+)[^\\)]*\\).*" "\\1" GOLD_BINUTILS_VERSION "${LD_VERSION}")
|
string(REGEX REPLACE ".*\\(GNU Binutils[^\\)0-9]+([0-9]+\\.[0-9]+)[^\\)]*\\).*" "\\1" GOLD_BINUTILS_VERSION "${LD_VERSION}")
|
||||||
if ("${GOLD_BINUTILS_VERSION}" VERSION_LESS "2.25")
|
if ("${GOLD_BINUTILS_VERSION}" VERSION_LESS "2.26")
|
||||||
message(STATUS "Disabling gc-sections on gold binutils < 2.25, see: https://sourceware.org/bugzilla/show_bug.cgi?id=17639")
|
message(STATUS "Disabling gc-sections on gold binutils < 2.26, see: https://sourceware.org/bugzilla/show_bug.cgi?id=17639")
|
||||||
set(LD_AVOID_GC_SECTIONS TRUE)
|
set(LD_AVOID_GC_SECTIONS TRUE)
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
|
|||||||
+1
-1
@@ -34,7 +34,7 @@ int main(int argc, const char *argv[])
|
|||||||
config.use_shared_memory = false;
|
config.use_shared_memory = false;
|
||||||
|
|
||||||
// Routing machine with several services (such as Route, Table, Nearest, Trip, Match)
|
// Routing machine with several services (such as Route, Table, Nearest, Trip, Match)
|
||||||
OSRM osrm{config};
|
const OSRM osrm{config};
|
||||||
|
|
||||||
// The following shows how to use the Route service; configure this service
|
// The following shows how to use the Route service; configure this service
|
||||||
RouteParameters params;
|
RouteParameters params;
|
||||||
|
|||||||
@@ -0,0 +1,94 @@
|
|||||||
|
@routing @basic @car
|
||||||
|
Feature: Basic Routing
|
||||||
|
|
||||||
|
Background:
|
||||||
|
Given the profile "car"
|
||||||
|
Given a grid size of 500 meters
|
||||||
|
|
||||||
|
@smallest
|
||||||
|
Scenario: Summaries when routing on a simple network
|
||||||
|
Given the node map
|
||||||
|
| b | | | f |
|
||||||
|
| | | | |
|
||||||
|
| c | d | | g |
|
||||||
|
| | | | |
|
||||||
|
| a | | e | |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | name |
|
||||||
|
| acb | road |
|
||||||
|
| de | 1 st |
|
||||||
|
| cd | |
|
||||||
|
| dg | blvd |
|
||||||
|
| df | street |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | summary |
|
||||||
|
| a,e | road,,1 st,1 st | road, 1 st |
|
||||||
|
| a,d,f | road,,,street,street | road;street |
|
||||||
|
| a,e,f | road,,1 st,1 st,1 st,street,street | road, 1 st;1 st, street |
|
||||||
|
|
||||||
|
Scenario: Name Empty
|
||||||
|
Given the node map
|
||||||
|
| a | | b | | | c |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | name |
|
||||||
|
| ab | road |
|
||||||
|
| bc | |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | summary |
|
||||||
|
| a,c | road, | road |
|
||||||
|
|
||||||
|
Scenario: Name Empty But Ref
|
||||||
|
Given the node map
|
||||||
|
| a | | b | | | c |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | name | ref |
|
||||||
|
| ab | road | |
|
||||||
|
| bc | | 101 |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | summary |
|
||||||
|
| a,c | road, | road, 101 |
|
||||||
|
|
||||||
|
Scenario: Only Refs
|
||||||
|
Given the node map
|
||||||
|
| a | | b | | | c |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | name | ref |
|
||||||
|
| ab | | 100 |
|
||||||
|
| bc | | 101 |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | summary |
|
||||||
|
| a,c | , | 100, 101 |
|
||||||
|
|
||||||
|
Scenario: Single Ref
|
||||||
|
Given the node map
|
||||||
|
| a | | b | | | c |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | name | ref |
|
||||||
|
| ab | | |
|
||||||
|
| bc | | 101 |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | summary |
|
||||||
|
| a,c | ,, | 101 |
|
||||||
|
|
||||||
|
Scenario: Nothing
|
||||||
|
Given the node map
|
||||||
|
| a | | b | | | c |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | name |
|
||||||
|
| ab | |
|
||||||
|
| bc | |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | summary |
|
||||||
|
| a,c | , | |
|
||||||
+21
-3
@@ -51,8 +51,26 @@ module.exports = function () {
|
|||||||
} else {
|
} else {
|
||||||
this.TERMSIGNAL = 'SIGTERM';
|
this.TERMSIGNAL = 'SIGTERM';
|
||||||
this.EXE = '';
|
this.EXE = '';
|
||||||
// TODO autodetect if this was build with shared or static libraries
|
|
||||||
this.LIB = process.env.BUILD_SHARED_LIBS && '.so' || '.a';
|
// heuristically detect .so/.a suffix
|
||||||
|
this.LIB = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const dot_a = util.format('%s/libosrm%s', this.BIN_PATH, '.a');
|
||||||
|
fs.accessSync(dot_a, fs.F_OK);
|
||||||
|
this.LIB = '.a';
|
||||||
|
} catch(e) { /*nop*/ }
|
||||||
|
|
||||||
|
try {
|
||||||
|
const dot_so = util.format('%s/libosrm%s', this.BIN_PATH, '.so');
|
||||||
|
fs.accessSync(dot_so, fs.F_OK);
|
||||||
|
this.LIB = '.so';
|
||||||
|
} catch(e) { /*nop*/ }
|
||||||
|
|
||||||
|
if (!this.LIB) {
|
||||||
|
throw new Error('*** Unable to detect dynamic or static libosrm libraries');
|
||||||
|
}
|
||||||
|
|
||||||
this.QQ = '';
|
this.QQ = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +83,7 @@ module.exports = function () {
|
|||||||
|
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.info(util.format('Node Version', process.version));
|
console.info(util.format('Node Version', process.version));
|
||||||
if (parseInt(process.version.match(/v(\d)/)[1]) < 4) throw new Error('*** PLease upgrade to Node 4.+ to run OSRM cucumber tests');
|
if (parseInt(process.version.match(/v(\d)/)[1]) < 4) throw new Error('*** Please upgrade to Node 4.+ to run OSRM cucumber tests');
|
||||||
|
|
||||||
fs.exists(this.TEST_PATH, (exists) => {
|
fs.exists(this.TEST_PATH, (exists) => {
|
||||||
if (exists)
|
if (exists)
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ module.exports = function () {
|
|||||||
|
|
||||||
this.summary = (instructions) => {
|
this.summary = (instructions) => {
|
||||||
if (instructions) {
|
if (instructions) {
|
||||||
return instructions.legs.map(l => l.summary).join(',');
|
return instructions.legs.map(l => l.summary).join(';');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -53,9 +53,9 @@ Feature: Basic Routing
|
|||||||
| ab |
|
| ab |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | route | summary |
|
| from | to | route | summary |
|
||||||
| a | b | ab,ab | ab |
|
| a | b | ab,ab | ab |
|
||||||
| b | a | ab,ab | ab |
|
| b | a | ab,ab | ab |
|
||||||
|
|
||||||
@repeated
|
@repeated
|
||||||
Scenario: Check handling empty values
|
Scenario: Check handling empty values
|
||||||
|
|||||||
@@ -69,6 +69,21 @@ struct RouteParameters : public BaseParameters
|
|||||||
|
|
||||||
RouteParameters() = default;
|
RouteParameters() = default;
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
RouteParameters(const bool steps_,
|
||||||
|
const bool alternatives_,
|
||||||
|
const GeometriesType geometries_,
|
||||||
|
const OverviewType overview_,
|
||||||
|
const boost::optional<bool> continue_straight_,
|
||||||
|
Args... args_)
|
||||||
|
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
|
||||||
|
annotations{false}, geometries{geometries_}, overview{overview_},
|
||||||
|
continue_straight{continue_straight_}
|
||||||
|
// Once we perfectly-forward `args` (see #2990) this constructor can delegate to the one below.
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// RouteParameters constructor adding the `annotations` setting in a API-compatible way.
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
RouteParameters(const bool steps_,
|
RouteParameters(const bool steps_,
|
||||||
const bool alternatives_,
|
const bool alternatives_,
|
||||||
|
|||||||
+13
-12
@@ -1,7 +1,6 @@
|
|||||||
#ifndef ENGINE_HPP
|
#ifndef ENGINE_HPP
|
||||||
#define ENGINE_HPP
|
#define ENGINE_HPP
|
||||||
|
|
||||||
#include "storage/shared_barriers.hpp"
|
|
||||||
#include "engine/status.hpp"
|
#include "engine/status.hpp"
|
||||||
#include "util/json_container.hpp"
|
#include "util/json_container.hpp"
|
||||||
|
|
||||||
@@ -20,6 +19,11 @@ struct Object;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace storage
|
||||||
|
{
|
||||||
|
struct SharedBarriers;
|
||||||
|
}
|
||||||
|
|
||||||
// Fwd decls
|
// Fwd decls
|
||||||
namespace engine
|
namespace engine
|
||||||
{
|
{
|
||||||
@@ -52,10 +56,7 @@ class BaseDataFacade;
|
|||||||
class Engine final
|
class Engine final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Needs to be public
|
explicit Engine(const EngineConfig &config);
|
||||||
struct EngineLock;
|
|
||||||
|
|
||||||
explicit Engine(EngineConfig &config);
|
|
||||||
|
|
||||||
Engine(Engine &&) noexcept;
|
Engine(Engine &&) noexcept;
|
||||||
Engine &operator=(Engine &&) noexcept;
|
Engine &operator=(Engine &&) noexcept;
|
||||||
@@ -63,15 +64,15 @@ class Engine final
|
|||||||
// Impl. in cpp since for unique_ptr of incomplete types
|
// Impl. in cpp since for unique_ptr of incomplete types
|
||||||
~Engine();
|
~Engine();
|
||||||
|
|
||||||
Status Route(const api::RouteParameters ¶meters, util::json::Object &result);
|
Status Route(const api::RouteParameters ¶meters, util::json::Object &result) const;
|
||||||
Status Table(const api::TableParameters ¶meters, util::json::Object &result);
|
Status Table(const api::TableParameters ¶meters, util::json::Object &result) const;
|
||||||
Status Nearest(const api::NearestParameters ¶meters, util::json::Object &result);
|
Status Nearest(const api::NearestParameters ¶meters, util::json::Object &result) const;
|
||||||
Status Trip(const api::TripParameters ¶meters, util::json::Object &result);
|
Status Trip(const api::TripParameters ¶meters, util::json::Object &result) const;
|
||||||
Status Match(const api::MatchParameters ¶meters, util::json::Object &result);
|
Status Match(const api::MatchParameters ¶meters, util::json::Object &result) const;
|
||||||
Status Tile(const api::TileParameters ¶meters, std::string &result);
|
Status Tile(const api::TileParameters ¶meters, std::string &result) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<EngineLock> lock;
|
std::unique_ptr<storage::SharedBarriers> lock;
|
||||||
|
|
||||||
std::unique_ptr<plugins::ViaRoutePlugin> route_plugin;
|
std::unique_ptr<plugins::ViaRoutePlugin> route_plugin;
|
||||||
std::unique_ptr<plugins::TablePlugin> table_plugin;
|
std::unique_ptr<plugins::TablePlugin> table_plugin;
|
||||||
|
|||||||
@@ -6,6 +6,11 @@
|
|||||||
#include "engine/guidance/route_leg.hpp"
|
#include "engine/guidance/route_leg.hpp"
|
||||||
#include "engine/guidance/route_step.hpp"
|
#include "engine/guidance/route_step.hpp"
|
||||||
#include "engine/internal_route_result.hpp"
|
#include "engine/internal_route_result.hpp"
|
||||||
|
#include "util/typedefs.hpp"
|
||||||
|
|
||||||
|
#include <boost/algorithm/string/join.hpp>
|
||||||
|
#include <boost/range/adaptor/filtered.hpp>
|
||||||
|
#include <boost/range/adaptor/transformed.hpp>
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
@@ -107,7 +112,7 @@ std::array<std::uint32_t, SegmentNumber> summarizeRoute(const std::vector<PathDa
|
|||||||
});
|
});
|
||||||
|
|
||||||
std::array<std::uint32_t, SegmentNumber> summary;
|
std::array<std::uint32_t, SegmentNumber> summary;
|
||||||
std::fill(summary.begin(), summary.end(), 0);
|
std::fill(summary.begin(), summary.end(), EMPTY_NAMEID);
|
||||||
std::transform(segments.begin(),
|
std::transform(segments.begin(),
|
||||||
segments.end(),
|
segments.end(),
|
||||||
summary.begin(),
|
summary.begin(),
|
||||||
@@ -172,21 +177,28 @@ inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade,
|
|||||||
{
|
{
|
||||||
auto summary_array = detail::summarizeRoute<detail::MAX_USED_SEGMENTS>(
|
auto summary_array = detail::summarizeRoute<detail::MAX_USED_SEGMENTS>(
|
||||||
route_data, target_node, target_traversed_in_reverse);
|
route_data, target_node, target_traversed_in_reverse);
|
||||||
if (route_data.empty())
|
|
||||||
summary_array[0] = source_node.name_id;
|
|
||||||
|
|
||||||
BOOST_ASSERT(detail::MAX_USED_SEGMENTS > 0);
|
BOOST_ASSERT(detail::MAX_USED_SEGMENTS > 0);
|
||||||
BOOST_ASSERT(summary_array.begin() != summary_array.end());
|
BOOST_ASSERT(summary_array.begin() != summary_array.end());
|
||||||
summary = std::accumulate(std::next(summary_array.begin()),
|
|
||||||
summary_array.end(),
|
// transform a name_id into a string containing either the name, or -if the name is empty-
|
||||||
facade.GetNameForID(summary_array.front()),
|
// the reference.
|
||||||
[&facade](std::string previous, const std::uint32_t name_id) {
|
const auto name_id_to_string = [&](const NameID name_id) {
|
||||||
if (name_id != 0)
|
const auto name = facade.GetNameForID(name_id);
|
||||||
{
|
if (!name.empty())
|
||||||
previous += ", " + facade.GetNameForID(name_id);
|
return name;
|
||||||
}
|
else
|
||||||
return previous;
|
{
|
||||||
});
|
const auto ref = facade.GetRefForID(name_id);
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto not_empty = [&](const std::string &name) { return !name.empty(); };
|
||||||
|
|
||||||
|
const auto summary_names = summary_array | boost::adaptors::transformed(name_id_to_string) |
|
||||||
|
boost::adaptors::filtered(not_empty);
|
||||||
|
summary = boost::algorithm::join(summary_names, ", ");
|
||||||
}
|
}
|
||||||
|
|
||||||
return RouteLeg{duration, distance, summary, {}};
|
return RouteLeg{duration, distance, summary, {}};
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ class OSRM final
|
|||||||
* \return Status indicating success for the query or failure
|
* \return Status indicating success for the query or failure
|
||||||
* \see Status, RouteParameters and json::Object
|
* \see Status, RouteParameters and json::Object
|
||||||
*/
|
*/
|
||||||
Status Route(const RouteParameters ¶meters, json::Object &result);
|
Status Route(const RouteParameters ¶meters, json::Object &result) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Distance tables for coordinates.
|
* Distance tables for coordinates.
|
||||||
@@ -92,7 +92,7 @@ class OSRM final
|
|||||||
* \return Status indicating success for the query or failure
|
* \return Status indicating success for the query or failure
|
||||||
* \see Status, TableParameters and json::Object
|
* \see Status, TableParameters and json::Object
|
||||||
*/
|
*/
|
||||||
Status Table(const TableParameters ¶meters, json::Object &result);
|
Status Table(const TableParameters ¶meters, json::Object &result) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Nearest street segment for coordinate.
|
* Nearest street segment for coordinate.
|
||||||
@@ -101,7 +101,7 @@ class OSRM final
|
|||||||
* \return Status indicating success for the query or failure
|
* \return Status indicating success for the query or failure
|
||||||
* \see Status, NearestParameters and json::Object
|
* \see Status, NearestParameters and json::Object
|
||||||
*/
|
*/
|
||||||
Status Nearest(const NearestParameters ¶meters, json::Object &result);
|
Status Nearest(const NearestParameters ¶meters, json::Object &result) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trip: shortest round trip between coordinates.
|
* Trip: shortest round trip between coordinates.
|
||||||
@@ -110,7 +110,7 @@ class OSRM final
|
|||||||
* \return Status indicating success for the query or failure
|
* \return Status indicating success for the query or failure
|
||||||
* \see Status, TripParameters and json::Object
|
* \see Status, TripParameters and json::Object
|
||||||
*/
|
*/
|
||||||
Status Trip(const TripParameters ¶meters, json::Object &result);
|
Status Trip(const TripParameters ¶meters, json::Object &result) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Match: snaps noisy coordinate traces to the road network
|
* Match: snaps noisy coordinate traces to the road network
|
||||||
@@ -119,7 +119,7 @@ class OSRM final
|
|||||||
* \return Status indicating success for the query or failure
|
* \return Status indicating success for the query or failure
|
||||||
* \see Status, MatchParameters and json::Object
|
* \see Status, MatchParameters and json::Object
|
||||||
*/
|
*/
|
||||||
Status Match(const MatchParameters ¶meters, json::Object &result);
|
Status Match(const MatchParameters ¶meters, json::Object &result) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tile: vector tiles with internal graph representation
|
* Tile: vector tiles with internal graph representation
|
||||||
@@ -128,7 +128,7 @@ class OSRM final
|
|||||||
* \return Status indicating success for the query or failure
|
* \return Status indicating success for the query or failure
|
||||||
* \see Status, TileParameters and json::Object
|
* \see Status, TileParameters and json::Object
|
||||||
*/
|
*/
|
||||||
Status Tile(const TileParameters ¶meters, std::string &result);
|
Status Tile(const TileParameters ¶meters, std::string &result) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<engine::Engine> engine_;
|
std::unique_ptr<engine::Engine> engine_;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <boost/interprocess/sync/named_condition.hpp>
|
#include <boost/interprocess/sync/named_condition.hpp>
|
||||||
#include <boost/interprocess/sync/named_mutex.hpp>
|
#include <boost/interprocess/sync/named_mutex.hpp>
|
||||||
|
#include <boost/interprocess/sync/named_sharable_mutex.hpp>
|
||||||
|
|
||||||
namespace osrm
|
namespace osrm
|
||||||
{
|
{
|
||||||
@@ -13,25 +14,13 @@ struct SharedBarriers
|
|||||||
|
|
||||||
SharedBarriers()
|
SharedBarriers()
|
||||||
: pending_update_mutex(boost::interprocess::open_or_create, "pending_update"),
|
: pending_update_mutex(boost::interprocess::open_or_create, "pending_update"),
|
||||||
update_mutex(boost::interprocess::open_or_create, "update"),
|
query_mutex(boost::interprocess::open_or_create, "query")
|
||||||
query_mutex(boost::interprocess::open_or_create, "query"),
|
|
||||||
no_running_queries_condition(boost::interprocess::open_or_create, "no_running_queries"),
|
|
||||||
update_ongoing(false), number_of_queries(0)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mutex to protect access to the boolean variable
|
// Mutex to protect access to the boolean variable
|
||||||
boost::interprocess::named_mutex pending_update_mutex;
|
boost::interprocess::named_mutex pending_update_mutex;
|
||||||
boost::interprocess::named_mutex update_mutex;
|
boost::interprocess::named_sharable_mutex query_mutex;
|
||||||
boost::interprocess::named_mutex query_mutex;
|
|
||||||
|
|
||||||
// Condition that no update is running
|
|
||||||
boost::interprocess::named_condition no_running_queries_condition;
|
|
||||||
|
|
||||||
// Is there an ongoing update?
|
|
||||||
bool update_ongoing;
|
|
||||||
// Is there any query?
|
|
||||||
int number_of_queries;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+21
-68
@@ -1,5 +1,5 @@
|
|||||||
#include "engine/engine.hpp"
|
|
||||||
#include "engine/api/route_parameters.hpp"
|
#include "engine/api/route_parameters.hpp"
|
||||||
|
#include "engine/engine.hpp"
|
||||||
#include "engine/engine_config.hpp"
|
#include "engine/engine_config.hpp"
|
||||||
#include "engine/status.hpp"
|
#include "engine/status.hpp"
|
||||||
|
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
#include <boost/interprocess/sync/named_condition.hpp>
|
#include <boost/interprocess/sync/named_condition.hpp>
|
||||||
#include <boost/interprocess/sync/scoped_lock.hpp>
|
#include <boost/interprocess/sync/scoped_lock.hpp>
|
||||||
|
#include <boost/interprocess/sync/sharable_lock.hpp>
|
||||||
#include <boost/thread/lock_types.hpp>
|
#include <boost/thread/lock_types.hpp>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@@ -28,68 +29,17 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace osrm
|
|
||||||
{
|
|
||||||
namespace engine
|
|
||||||
{
|
|
||||||
struct Engine::EngineLock
|
|
||||||
{
|
|
||||||
// will only be initialized if shared memory is used
|
|
||||||
storage::SharedBarriers barrier;
|
|
||||||
// decrease number of concurrent queries
|
|
||||||
void DecreaseQueryCount();
|
|
||||||
// increase number of concurrent queries
|
|
||||||
void IncreaseQueryCount();
|
|
||||||
};
|
|
||||||
|
|
||||||
// decrease number of concurrent queries
|
|
||||||
void Engine::EngineLock::DecreaseQueryCount()
|
|
||||||
{
|
|
||||||
// lock query
|
|
||||||
boost::interprocess::scoped_lock<boost::interprocess::named_mutex> query_lock(
|
|
||||||
barrier.query_mutex);
|
|
||||||
|
|
||||||
// decrement query count
|
|
||||||
--(barrier.number_of_queries);
|
|
||||||
BOOST_ASSERT_MSG(0 <= barrier.number_of_queries, "invalid number of queries");
|
|
||||||
|
|
||||||
// notify all processes that were waiting for this condition
|
|
||||||
if (0 == barrier.number_of_queries)
|
|
||||||
{
|
|
||||||
barrier.no_running_queries_condition.notify_all();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// increase number of concurrent queries
|
|
||||||
void Engine::EngineLock::IncreaseQueryCount()
|
|
||||||
{
|
|
||||||
// lock update pending
|
|
||||||
boost::interprocess::scoped_lock<boost::interprocess::named_mutex> pending_lock(
|
|
||||||
barrier.pending_update_mutex);
|
|
||||||
|
|
||||||
// lock query
|
|
||||||
boost::interprocess::scoped_lock<boost::interprocess::named_mutex> query_lock(
|
|
||||||
barrier.query_mutex);
|
|
||||||
|
|
||||||
// unlock update pending
|
|
||||||
pending_lock.unlock();
|
|
||||||
|
|
||||||
// increment query count
|
|
||||||
++(barrier.number_of_queries);
|
|
||||||
}
|
|
||||||
} // ns engine
|
|
||||||
} // ns osrm
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
// Abstracted away the query locking into a template function
|
// Abstracted away the query locking into a template function
|
||||||
// Works the same for every plugin.
|
// Works the same for every plugin.
|
||||||
template <typename ParameterT, typename PluginT, typename ResultT>
|
template <typename ParameterT, typename PluginT, typename ResultT>
|
||||||
osrm::engine::Status RunQuery(const std::unique_ptr<osrm::engine::Engine::EngineLock> &lock,
|
osrm::engine::Status
|
||||||
osrm::engine::datafacade::BaseDataFacade &facade,
|
RunQuery(const std::unique_ptr<osrm::storage::SharedBarriers> &lock,
|
||||||
const ParameterT ¶meters,
|
osrm::engine::datafacade::BaseDataFacade &facade,
|
||||||
PluginT &plugin,
|
const ParameterT ¶meters,
|
||||||
ResultT &result)
|
PluginT &plugin,
|
||||||
|
ResultT &result)
|
||||||
{
|
{
|
||||||
if (!lock)
|
if (!lock)
|
||||||
{
|
{
|
||||||
@@ -97,7 +47,10 @@ osrm::engine::Status RunQuery(const std::unique_ptr<osrm::engine::Engine::Engine
|
|||||||
}
|
}
|
||||||
|
|
||||||
BOOST_ASSERT(lock);
|
BOOST_ASSERT(lock);
|
||||||
lock->IncreaseQueryCount();
|
// this locks aquires shared ownership of the query mutex: other requets are allowed
|
||||||
|
// to run, but data updates need to wait for all queries to finish until they can aquire an exclusive lock
|
||||||
|
boost::interprocess::sharable_lock<boost::interprocess::named_sharable_mutex> query_lock(
|
||||||
|
lock->query_mutex);
|
||||||
|
|
||||||
auto &shared_facade = static_cast<osrm::engine::datafacade::SharedDataFacade &>(facade);
|
auto &shared_facade = static_cast<osrm::engine::datafacade::SharedDataFacade &>(facade);
|
||||||
shared_facade.CheckAndReloadFacade();
|
shared_facade.CheckAndReloadFacade();
|
||||||
@@ -107,7 +60,6 @@ osrm::engine::Status RunQuery(const std::unique_ptr<osrm::engine::Engine::Engine
|
|||||||
|
|
||||||
osrm::engine::Status status = plugin.HandleRequest(parameters, result);
|
osrm::engine::Status status = plugin.HandleRequest(parameters, result);
|
||||||
|
|
||||||
lock->DecreaseQueryCount();
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,11 +76,12 @@ namespace osrm
|
|||||||
namespace engine
|
namespace engine
|
||||||
{
|
{
|
||||||
|
|
||||||
Engine::Engine(EngineConfig &config)
|
Engine::Engine(const EngineConfig &config)
|
||||||
|
: lock(config.use_shared_memory ? std::make_unique<storage::SharedBarriers>()
|
||||||
|
: std::unique_ptr<storage::SharedBarriers>())
|
||||||
{
|
{
|
||||||
if (config.use_shared_memory)
|
if (config.use_shared_memory)
|
||||||
{
|
{
|
||||||
lock = util::make_unique<EngineLock>();
|
|
||||||
query_data_facade = util::make_unique<datafacade::SharedDataFacade>();
|
query_data_facade = util::make_unique<datafacade::SharedDataFacade>();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -157,32 +110,32 @@ Engine::~Engine() = default;
|
|||||||
Engine::Engine(Engine &&) noexcept = default;
|
Engine::Engine(Engine &&) noexcept = default;
|
||||||
Engine &Engine::operator=(Engine &&) noexcept = default;
|
Engine &Engine::operator=(Engine &&) noexcept = default;
|
||||||
|
|
||||||
Status Engine::Route(const api::RouteParameters ¶ms, util::json::Object &result)
|
Status Engine::Route(const api::RouteParameters ¶ms, util::json::Object &result) const
|
||||||
{
|
{
|
||||||
return RunQuery(lock, *query_data_facade, params, *route_plugin, result);
|
return RunQuery(lock, *query_data_facade, params, *route_plugin, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Status Engine::Table(const api::TableParameters ¶ms, util::json::Object &result)
|
Status Engine::Table(const api::TableParameters ¶ms, util::json::Object &result) const
|
||||||
{
|
{
|
||||||
return RunQuery(lock, *query_data_facade, params, *table_plugin, result);
|
return RunQuery(lock, *query_data_facade, params, *table_plugin, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Status Engine::Nearest(const api::NearestParameters ¶ms, util::json::Object &result)
|
Status Engine::Nearest(const api::NearestParameters ¶ms, util::json::Object &result) const
|
||||||
{
|
{
|
||||||
return RunQuery(lock, *query_data_facade, params, *nearest_plugin, result);
|
return RunQuery(lock, *query_data_facade, params, *nearest_plugin, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Status Engine::Trip(const api::TripParameters ¶ms, util::json::Object &result)
|
Status Engine::Trip(const api::TripParameters ¶ms, util::json::Object &result) const
|
||||||
{
|
{
|
||||||
return RunQuery(lock, *query_data_facade, params, *trip_plugin, result);
|
return RunQuery(lock, *query_data_facade, params, *trip_plugin, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Status Engine::Match(const api::MatchParameters ¶ms, util::json::Object &result)
|
Status Engine::Match(const api::MatchParameters ¶ms, util::json::Object &result) const
|
||||||
{
|
{
|
||||||
return RunQuery(lock, *query_data_facade, params, *match_plugin, result);
|
return RunQuery(lock, *query_data_facade, params, *match_plugin, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Status Engine::Tile(const api::TileParameters ¶ms, std::string &result)
|
Status Engine::Tile(const api::TileParameters ¶ms, std::string &result) const
|
||||||
{
|
{
|
||||||
return RunQuery(lock, *query_data_facade, params, *tile_plugin, result);
|
return RunQuery(lock, *query_data_facade, params, *tile_plugin, result);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ std::vector<util::Coordinate> decodePolyline(const std::string &geometry_string)
|
|||||||
b = geometry_string.at(index++) - 63;
|
b = geometry_string.at(index++) - 63;
|
||||||
result |= (b & 0x1f) << shift;
|
result |= (b & 0x1f) << shift;
|
||||||
shift += 5;
|
shift += 5;
|
||||||
} while (b >= 0x20);
|
} while (b >= 0x20 && index < len);
|
||||||
int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
|
int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
|
||||||
lat += dlat;
|
lat += dlat;
|
||||||
|
|
||||||
@@ -111,7 +111,7 @@ std::vector<util::Coordinate> decodePolyline(const std::string &geometry_string)
|
|||||||
b = geometry_string.at(index++) - 63;
|
b = geometry_string.at(index++) - 63;
|
||||||
result |= (b & 0x1f) << shift;
|
result |= (b & 0x1f) << shift;
|
||||||
shift += 5;
|
shift += 5;
|
||||||
} while (b >= 0x20);
|
} while (b >= 0x20 && index < len);
|
||||||
int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
|
int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
|
||||||
lng += dlng;
|
lng += dlng;
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -21,32 +21,32 @@ OSRM &OSRM::operator=(OSRM &&) noexcept = default;
|
|||||||
|
|
||||||
// Forward to implementation
|
// Forward to implementation
|
||||||
|
|
||||||
engine::Status OSRM::Route(const engine::api::RouteParameters ¶ms, util::json::Object &result)
|
engine::Status OSRM::Route(const engine::api::RouteParameters ¶ms, util::json::Object &result) const
|
||||||
{
|
{
|
||||||
return engine_->Route(params, result);
|
return engine_->Route(params, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
engine::Status OSRM::Table(const engine::api::TableParameters ¶ms, json::Object &result)
|
engine::Status OSRM::Table(const engine::api::TableParameters ¶ms, json::Object &result) const
|
||||||
{
|
{
|
||||||
return engine_->Table(params, result);
|
return engine_->Table(params, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
engine::Status OSRM::Nearest(const engine::api::NearestParameters ¶ms, json::Object &result)
|
engine::Status OSRM::Nearest(const engine::api::NearestParameters ¶ms, json::Object &result) const
|
||||||
{
|
{
|
||||||
return engine_->Nearest(params, result);
|
return engine_->Nearest(params, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
engine::Status OSRM::Trip(const engine::api::TripParameters ¶ms, json::Object &result)
|
engine::Status OSRM::Trip(const engine::api::TripParameters ¶ms, json::Object &result) const
|
||||||
{
|
{
|
||||||
return engine_->Trip(params, result);
|
return engine_->Trip(params, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
engine::Status OSRM::Match(const engine::api::MatchParameters ¶ms, json::Object &result)
|
engine::Status OSRM::Match(const engine::api::MatchParameters ¶ms, json::Object &result) const
|
||||||
{
|
{
|
||||||
return engine_->Match(params, result);
|
return engine_->Match(params, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
engine::Status OSRM::Tile(const engine::api::TileParameters ¶ms, std::string &result)
|
engine::Status OSRM::Tile(const engine::api::TileParameters ¶ms, std::string &result) const
|
||||||
{
|
{
|
||||||
return engine_->Tile(params, result);
|
return engine_->Tile(params, result);
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-17
@@ -42,11 +42,6 @@ namespace osrm
|
|||||||
namespace storage
|
namespace storage
|
||||||
{
|
{
|
||||||
|
|
||||||
using RTreeLeaf = engine::datafacade::BaseDataFacade::RTreeLeaf;
|
|
||||||
using RTreeNode =
|
|
||||||
util::StaticRTree<RTreeLeaf, util::ShM<util::Coordinate, true>::vector, true>::TreeNode;
|
|
||||||
using QueryGraph = util::StaticGraph<contractor::QueryEdge::EdgeData>;
|
|
||||||
|
|
||||||
// delete a shared memory region. report warning if it could not be deleted
|
// delete a shared memory region. report warning if it could not be deleted
|
||||||
void deleteRegion(const SharedDataType region)
|
void deleteRegion(const SharedDataType region)
|
||||||
{
|
{
|
||||||
@@ -76,6 +71,11 @@ void deleteRegion(const SharedDataType region)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using RTreeLeaf = engine::datafacade::BaseDataFacade::RTreeLeaf;
|
||||||
|
using RTreeNode =
|
||||||
|
util::StaticRTree<RTreeLeaf, util::ShM<util::Coordinate, true>::vector, true>::TreeNode;
|
||||||
|
using QueryGraph = util::StaticGraph<contractor::QueryEdge::EdgeData>;
|
||||||
|
|
||||||
Storage::Storage(StorageConfig config_) : config(std::move(config_)) {}
|
Storage::Storage(StorageConfig config_) : config(std::move(config_)) {}
|
||||||
|
|
||||||
int Storage::Run()
|
int Storage::Run()
|
||||||
@@ -738,20 +738,15 @@ int Storage::Run()
|
|||||||
SharedDataTimestamp *data_timestamp_ptr =
|
SharedDataTimestamp *data_timestamp_ptr =
|
||||||
static_cast<SharedDataTimestamp *>(data_type_memory->Ptr());
|
static_cast<SharedDataTimestamp *>(data_type_memory->Ptr());
|
||||||
|
|
||||||
boost::interprocess::scoped_lock<boost::interprocess::named_mutex> query_lock(
|
|
||||||
barrier.query_mutex);
|
|
||||||
|
|
||||||
// notify all processes that were waiting for this condition
|
|
||||||
if (0 < barrier.number_of_queries)
|
|
||||||
{
|
{
|
||||||
barrier.no_running_queries_condition.wait(query_lock);
|
boost::interprocess::scoped_lock<boost::interprocess::named_sharable_mutex> query_lock(barrier.query_mutex);
|
||||||
}
|
|
||||||
|
|
||||||
data_timestamp_ptr->layout = layout_region;
|
data_timestamp_ptr->layout = layout_region;
|
||||||
data_timestamp_ptr->data = data_region;
|
data_timestamp_ptr->data = data_region;
|
||||||
data_timestamp_ptr->timestamp += 1;
|
data_timestamp_ptr->timestamp += 1;
|
||||||
deleteRegion(previous_data_region);
|
deleteRegion(previous_data_region);
|
||||||
deleteRegion(previous_layout_region);
|
deleteRegion(previous_layout_region);
|
||||||
|
}
|
||||||
util::SimpleLogger().Write() << "all data loaded";
|
util::SimpleLogger().Write() << "all data loaded";
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|||||||
@@ -10,6 +10,5 @@ int main()
|
|||||||
osrm::storage::SharedBarriers barrier;
|
osrm::storage::SharedBarriers barrier;
|
||||||
barrier.pending_update_mutex.unlock();
|
barrier.pending_update_mutex.unlock();
|
||||||
barrier.query_mutex.unlock();
|
barrier.query_mutex.unlock();
|
||||||
barrier.update_mutex.unlock();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user