Compare commits

..

7 Commits

Author SHA1 Message Date
Siarhei Fedartsou c87ed8ebc0 Merge with master 2024-05-21 19:39:30 +02:00
Siarhei Fedartsou f19d64970a Merge branch 'master' into pr-6611 2024-05-21 19:35:50 +02:00
Dennis Luxen 56d2d4dacd Merge branch 'master' into boost_optional_merge 2024-05-06 17:39:54 +02:00
Mugr Rex 1107a14a2c Removed nodejs
Seems like my local build is ok, but in CI
the references to engine are still there
so I am reverting code in /nodejs to master
2023-04-24 19:16:27 +02:00
Mugr Rex 5b23b11129 Readded updater
Must have been lost while concating everything into one commit
2023-04-24 19:10:04 +02:00
Mugr Rex 23fb96c4f2 Fixed error in /nodejs 2023-04-21 13:16:14 +02:00
Mugr Rex 45bfe937aa Final merge commit 2023-04-20 16:04:04 +02:00
387 changed files with 22361 additions and 16804 deletions
+1 -11
View File
@@ -13,10 +13,6 @@ Checks: >
-bugprone-forward-declaration-namespace, -bugprone-forward-declaration-namespace,
-bugprone-sizeof-expression, -bugprone-sizeof-expression,
-bugprone-throw-keyword-missing, -bugprone-throw-keyword-missing,
-bugprone-chained-comparison,
-bugprone-incorrect-enable-if,
-bugprone-switch-missing-default-case,
-bugprone-empty-catch,
-clang-analyzer-*, -clang-analyzer-*,
-clang-diagnostic-deprecated-declarations, -clang-diagnostic-deprecated-declarations,
-clang-diagnostic-constant-conversion, -clang-diagnostic-constant-conversion,
@@ -53,13 +49,11 @@ Checks: >
-misc-misplaced-const, -misc-misplaced-const,
-misc-definitions-in-headers, -misc-definitions-in-headers,
-misc-unused-parameters, -misc-unused-parameters,
-misc-include-cleaner,
modernize-concat-nested-namespaces, modernize-concat-nested-namespaces,
modernize-use-using, modernize-use-using,
performance-*, performance-*,
-performance-noexcept-move-constructor,
-performance-no-int-to-ptr, -performance-no-int-to-ptr,
-performance-enum-size,
-performance-avoid-endl,
readability-*, readability-*,
-readability-avoid-const-params-in-decls, -readability-avoid-const-params-in-decls,
-readability-braces-around-statements, -readability-braces-around-statements,
@@ -88,10 +82,6 @@ Checks: >
-readability-make-member-function-const, -readability-make-member-function-const,
-readability-redundant-string-init, -readability-redundant-string-init,
-readability-non-const-parameter, -readability-non-const-parameter,
-readability-redundant-inline-specifier,
-readability-avoid-nested-conditional-operator,
-readability-avoid-return-with-void-value,
-readability-redundant-casting,
-readability-static-accessed-through-instance -readability-static-accessed-through-instance
WarningsAsErrors: '*' WarningsAsErrors: '*'
+192 -279
View File
@@ -15,6 +15,7 @@ env:
CCACHE_TEMPDIR: /tmp/.ccache-temp CCACHE_TEMPDIR: /tmp/.ccache-temp
CCACHE_COMPRESS: 1 CCACHE_COMPRESS: 1
CASHER_TIME_OUT: 599 # one second less than 10m to avoid 10m timeout error: https://github.com/Project-OSRM/osrm-backend/issues/2742 CASHER_TIME_OUT: 599 # one second less than 10m to avoid 10m timeout error: https://github.com/Project-OSRM/osrm-backend/issues/2742
CCACHE_VERSION: 3.3.1
CMAKE_VERSION: 3.21.2 CMAKE_VERSION: 3.21.2
ENABLE_NODE_BINDINGS: "ON" ENABLE_NODE_BINDINGS: "ON"
@@ -30,11 +31,11 @@ jobs:
env: env:
BUILD_TYPE: Release BUILD_TYPE: Release
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- run: pip install "conan<2.0.0" - run: pip install "conan<2.0.0"
- run: conan --version - run: conan --version
- run: cmake --version - run: cmake --version
- uses: actions/setup-node@v4 - uses: actions/setup-node@v3
with: with:
node-version: 18 node-version: 18
- run: node --version - run: node --version
@@ -46,32 +47,15 @@ jobs:
echo PUBLISH=$([[ "${GITHUB_REF:-}" == "refs/tags/v${PACKAGE_JSON_VERSION}" ]] && echo "On" || echo "Off") >> $GITHUB_ENV echo PUBLISH=$([[ "${GITHUB_REF:-}" == "refs/tags/v${PACKAGE_JSON_VERSION}" ]] && echo "On" || echo "Off") >> $GITHUB_ENV
- run: npm install --ignore-scripts - run: npm install --ignore-scripts
- run: npm link --ignore-scripts - run: npm link --ignore-scripts
- uses: microsoft/setup-msbuild@v1.1
- name: Build - name: Build
run: |
.\scripts\ci\windows-build.bat
- name: Run node tests
shell: bash shell: bash
run: | run: |
mkdir build ./lib/binding/osrm-datastore.exe test/data/ch/monaco.osrm
cd build node test/nodejs/index.js
cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_CONAN=ON -DENABLE_NODE_BINDINGS=ON ..
cmake --build . --config Release
# TODO: MSVC goes out of memory when building our tests
# - name: Run tests
# shell: bash
# run: |
# cd build
# cmake --build . --config Release --target tests
# # TODO: run tests
# - name: Run node tests
# shell: bash
# run: |
# ./lib/binding/osrm-extract.exe -p profiles/car.lua test/data/monaco.osm.pbf
# mkdir -p test/data/ch
# cp test/data/monaco.osrm* test/data/ch/
# ./lib/binding/osrm-contract.exe test/data/ch/monaco.osrm
# ./lib/binding/osrm-datastore.exe test/data/ch/monaco.osrm
# node test/nodejs/index.js
- name: Build Node package - name: Build Node package
shell: bash shell: bash
run: ./scripts/ci/node_package.sh run: ./scripts/ci/node_package.sh
@@ -92,13 +76,13 @@ jobs:
format-taginfo-docs: format-taginfo-docs:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Use Node.js - name: Use Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v3
with: with:
node-version: 18 node-version: 18
- name: Enable Node.js cache - name: Enable Node.js cache
uses: actions/cache@v4 uses: actions/cache@v3
with: with:
path: ~/.npm path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
@@ -122,9 +106,9 @@ jobs:
continue-on-error: false continue-on-error: false
steps: steps:
- name: Check out the repo - name: Check out the repo
uses: actions/checkout@v4 uses: actions/checkout@v3
- name: Enable osm.pbf cache - name: Enable osm.pbf cache
uses: actions/cache@v4 uses: actions/cache@v3
with: with:
path: berlin-latest.osm.pbf path: berlin-latest.osm.pbf
key: v1-berlin-osm-pbf key: v1-berlin-osm-pbf
@@ -164,178 +148,178 @@ jobs:
strategy: strategy:
matrix: matrix:
include: include:
# - name: gcc-13-debug-cov - name: gcc-13-debug-cov
# continue-on-error: false continue-on-error: false
# node: 20 node: 20
# runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
# BUILD_TOOLS: ON BUILD_TOOLS: ON
# BUILD_TYPE: Debug BUILD_TYPE: Debug
# CCOMPILER: gcc-13 CCOMPILER: gcc-13
# CUCUMBER_TIMEOUT: 20000 CUCUMBER_TIMEOUT: 20000
# CXXCOMPILER: g++-13 CXXCOMPILER: g++-13
# ENABLE_COVERAGE: ON ENABLE_COVERAGE: ON
# - name: clang-15-debug-asan-ubsan - name: clang-15-debug-asan-ubsan
# continue-on-error: false continue-on-error: false
# node: 20 node: 20
# runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
# BUILD_TOOLS: ON BUILD_TOOLS: ON
# BUILD_TYPE: Debug BUILD_TYPE: Debug
# CCOMPILER: clang-15 CCOMPILER: clang-15
# CUCUMBER_TIMEOUT: 20000 CUCUMBER_TIMEOUT: 20000
# CXXCOMPILER: clang++-15 CXXCOMPILER: clang++-15
# ENABLE_SANITIZER: ON ENABLE_SANITIZER: ON
# TARGET_ARCH: x86_64-asan-ubsan TARGET_ARCH: x86_64-asan-ubsan
# OSRM_CONNECTION_RETRIES: 10 OSRM_CONNECTION_RETRIES: 10
# OSRM_CONNECTION_EXP_BACKOFF_COEF: 1.5 OSRM_CONNECTION_EXP_BACKOFF_COEF: 1.5
# - name: clang-15-release - name: clang-15-release
# continue-on-error: false continue-on-error: false
# node: 18 node: 18
# runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
# BUILD_TOOLS: ON BUILD_TOOLS: ON
# BUILD_TYPE: Release BUILD_TYPE: Release
# CCOMPILER: clang-15 CCOMPILER: clang-15
# CXXCOMPILER: clang++-15 CXXCOMPILER: clang++-15
# CUCUMBER_TIMEOUT: 60000 CUCUMBER_TIMEOUT: 60000
# - name: clang-15-debug - name: clang-15-debug
# continue-on-error: false continue-on-error: false
# node: 18 node: 18
# runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
# BUILD_TOOLS: ON BUILD_TOOLS: ON
# BUILD_TYPE: Debug BUILD_TYPE: Debug
# CCOMPILER: clang-15 CCOMPILER: clang-15
# CXXCOMPILER: clang++-15 CXXCOMPILER: clang++-15
# CUCUMBER_TIMEOUT: 60000 CUCUMBER_TIMEOUT: 60000
# - name: clang-18-debug-clang-tidy - name: clang-15-debug-clang-tidy
# continue-on-error: false continue-on-error: false
# node: 18 node: 18
# runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
# BUILD_TOOLS: ON BUILD_TOOLS: ON
# BUILD_TYPE: Debug BUILD_TYPE: Debug
# CCOMPILER: clang-18 CCOMPILER: clang-15
# CXXCOMPILER: clang++-18 CXXCOMPILER: clang++-15
# CUCUMBER_TIMEOUT: 60000 CUCUMBER_TIMEOUT: 60000
# ENABLE_CLANG_TIDY: ON ENABLE_CLANG_TIDY: ON
# - name: clang-14-release - name: clang-14-release
# continue-on-error: false continue-on-error: false
# node: 18 node: 18
# runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
# BUILD_TOOLS: ON BUILD_TOOLS: ON
# BUILD_TYPE: Release BUILD_TYPE: Release
# CCOMPILER: clang-14 CCOMPILER: clang-14
# CXXCOMPILER: clang++-14 CXXCOMPILER: clang++-14
# CUCUMBER_TIMEOUT: 60000 CUCUMBER_TIMEOUT: 60000
# - name: clang-13-release - name: clang-13-release
# continue-on-error: false continue-on-error: false
# node: 18 node: 18
# runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
# BUILD_TOOLS: ON BUILD_TOOLS: ON
# BUILD_TYPE: Release BUILD_TYPE: Release
# CCOMPILER: clang-13 CCOMPILER: clang-13
# CXXCOMPILER: clang++-13 CXXCOMPILER: clang++-13
# CUCUMBER_TIMEOUT: 60000 CUCUMBER_TIMEOUT: 60000
# - name: conan-linux-debug-asan-ubsan - name: conan-linux-debug-asan-ubsan
# continue-on-error: false continue-on-error: false
# node: 18 node: 18
# runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
# BUILD_TOOLS: ON BUILD_TOOLS: ON
# BUILD_TYPE: Release BUILD_TYPE: Release
# CCOMPILER: clang-15 CCOMPILER: clang-15
# CXXCOMPILER: clang++-15 CXXCOMPILER: clang++-15
# ENABLE_CONAN: ON ENABLE_CONAN: ON
# ENABLE_SANITIZER: ON ENABLE_SANITIZER: ON
# - name: conan-linux-release - name: conan-linux-release
# continue-on-error: false continue-on-error: false
# node: 18 node: 18
# runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
# BUILD_TOOLS: ON BUILD_TOOLS: ON
# BUILD_TYPE: Release BUILD_TYPE: Release
# CCOMPILER: clang-15 CCOMPILER: clang-15
# CXXCOMPILER: clang++-15 CXXCOMPILER: clang++-15
# ENABLE_CONAN: ON ENABLE_CONAN: ON
- name: gcc-14-release - name: gcc-13-release
continue-on-error: false continue-on-error: false
node: 20 node: 20
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
BUILD_TOOLS: ON BUILD_TOOLS: ON
BUILD_TYPE: Release BUILD_TYPE: Release
CCOMPILER: gcc-14 CCOMPILER: gcc-13
CXXCOMPILER: g++-14 CXXCOMPILER: g++-13
CXXFLAGS: '-Wno-array-bounds -Wno-uninitialized' CXXFLAGS: '-Wno-array-bounds -Wno-uninitialized'
# - name: gcc-13-release - name: gcc-12-release
# continue-on-error: false continue-on-error: false
# node: 20 node: 20
# runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
# BUILD_TOOLS: ON BUILD_TOOLS: ON
# BUILD_TYPE: Release BUILD_TYPE: Release
# CCOMPILER: gcc-13 CCOMPILER: gcc-12
# CXXCOMPILER: g++-13 CXXCOMPILER: g++-12
# CXXFLAGS: '-Wno-array-bounds -Wno-uninitialized' CXXFLAGS: '-Wno-array-bounds -Wno-uninitialized'
# - name: gcc-12-release - name: gcc-11-release
# continue-on-error: false continue-on-error: false
# node: 20 node: 20
# runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
# BUILD_TOOLS: ON BUILD_TOOLS: ON
# BUILD_TYPE: Release BUILD_TYPE: Release
# CCOMPILER: gcc-12 CCOMPILER: gcc-11
# CXXCOMPILER: g++-12 CXXCOMPILER: g++-11
# CXXFLAGS: '-Wno-array-bounds -Wno-uninitialized'
# - name: conan-linux-release-node - name: conan-linux-release-node
# build_node_package: true build_node_package: true
# continue-on-error: false continue-on-error: false
# node: 20 node: 20
# runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
# BUILD_TYPE: Release BUILD_TYPE: Release
# CCOMPILER: clang-13 CCOMPILER: clang-13
# CXXCOMPILER: clang++-13 CXXCOMPILER: clang++-13
# ENABLE_CONAN: ON ENABLE_CONAN: ON
# NODE_PACKAGE_TESTS_ONLY: ON NODE_PACKAGE_TESTS_ONLY: ON
# - name: conan-linux-debug-node - name: conan-linux-debug-node
# build_node_package: true build_node_package: true
# continue-on-error: false continue-on-error: false
# node: 20 node: 20
# runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
# BUILD_TYPE: Debug BUILD_TYPE: Debug
# CCOMPILER: clang-13 CCOMPILER: clang-13
# CXXCOMPILER: clang++-13 CXXCOMPILER: clang++-13
# ENABLE_CONAN: ON ENABLE_CONAN: ON
# NODE_PACKAGE_TESTS_ONLY: ON NODE_PACKAGE_TESTS_ONLY: ON
# - name: conan-macos-x64-release-node - name: conan-macos-x64-release-node
# build_node_package: true build_node_package: true
# continue-on-error: true continue-on-error: true
# node: 20 node: 20
# runs-on: macos-13 # x86_64 runs-on: macos-13 # x86_64
# BUILD_TYPE: Release BUILD_TYPE: Release
# CCOMPILER: clang CCOMPILER: clang
# CXXCOMPILER: clang++ CXXCOMPILER: clang++
# CUCUMBER_TIMEOUT: 60000 CUCUMBER_TIMEOUT: 60000
# ENABLE_ASSERTIONS: ON ENABLE_ASSERTIONS: ON
# ENABLE_CONAN: ON ENABLE_CONAN: ON
- name: conan-macos-arm64-release-node
build_node_package: true
continue-on-error: true
node: 20
runs-on: macos-14 # arm64
BUILD_TYPE: Release
CCOMPILER: clang
CXXCOMPILER: clang++
CUCUMBER_TIMEOUT: 60000
ENABLE_ASSERTIONS: ON
ENABLE_CONAN: ON
# - name: conan-macos-arm64-release-node
# build_node_package: true
# continue-on-error: true
# node: 20
# runs-on: macos-14 # arm64
# BUILD_TYPE: Release
# CCOMPILER: clang
# CXXCOMPILER: clang++
# CUCUMBER_TIMEOUT: 60000
# ENABLE_ASSERTIONS: ON
# ENABLE_CONAN: ON
name: ${{ matrix.name}} name: ${{ matrix.name}}
continue-on-error: ${{ matrix.continue-on-error }} continue-on-error: ${{ matrix.continue-on-error }}
runs-on: ${{ matrix.runs-on }} runs-on: ${{ matrix.runs-on }}
@@ -358,46 +342,44 @@ jobs:
OSRM_CONNECTION_RETRIES: ${{ matrix.OSRM_CONNECTION_RETRIES }} OSRM_CONNECTION_RETRIES: ${{ matrix.OSRM_CONNECTION_RETRIES }}
OSRM_CONNECTION_EXP_BACKOFF_COEF: ${{ matrix.OSRM_CONNECTION_EXP_BACKOFF_COEF }} OSRM_CONNECTION_EXP_BACKOFF_COEF: ${{ matrix.OSRM_CONNECTION_EXP_BACKOFF_COEF }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Build machine architecture - name: Build machine architecture
run: uname -m run: uname -m
- name: Use Node.js - name: Use Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v3
with: with:
node-version: ${{ matrix.node }} node-version: ${{ matrix.node }}
- name: Enable Node.js cache - name: Enable Node.js cache
uses: actions/cache@v4 uses: actions/cache@v3
with: with:
path: ~/.npm path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: | restore-keys: |
${{ runner.os }}-node- ${{ runner.os }}-node-
- name: Enable compiler cache - name: Enable compiler cache
uses: actions/cache@v4 uses: actions/cache@v3
with: with:
path: ~/.ccache path: ~/.ccache
key: ccache-${{ matrix.name }}-${{ github.sha }} key: ccache-${{ matrix.name }}-${{ github.sha }}
restore-keys: | restore-keys: |
ccache-${{ matrix.name }}- ccache-${{ matrix.name }}-
- name: Enable Conan cache - name: Enable Conan cache
uses: actions/cache@v4 uses: actions/cache@v3
with: with:
path: ~/.conan path: ~/.conan
key: v9-conan-${{ matrix.name }}-${{ github.sha }} key: v9-conan-${{ matrix.name }}-${{ github.sha }}
restore-keys: | restore-keys: |
v9-conan-${{ matrix.name }}- v9-conan-${{ matrix.name }}-
- name: Enable test cache - name: Enable test cache
uses: actions/cache@v4 uses: actions/cache@v3
with: with:
path: ${{github.workspace}}/test/cache path: ${{github.workspace}}/test/cache
key: v4-test-${{ matrix.name }}-${{ github.sha }} key: v4-test-${{ matrix.name }}-${{ github.sha }}
restore-keys: | restore-keys: |
v4-test-${{ matrix.name }}- v4-test-${{ matrix.name }}-
- name: Prepare environment - name: Prepare environment
run: | run: |
echo "CCACHE_DIR=$HOME/.ccache" >> $GITHUB_ENV
mkdir -p $HOME/.ccache
PACKAGE_JSON_VERSION=$(node -e "console.log(require('./package.json').version)") PACKAGE_JSON_VERSION=$(node -e "console.log(require('./package.json').version)")
echo PUBLISH=$([[ "${GITHUB_REF:-}" == "refs/tags/v${PACKAGE_JSON_VERSION}" ]] && echo "On" || echo "Off") >> $GITHUB_ENV echo PUBLISH=$([[ "${GITHUB_REF:-}" == "refs/tags/v${PACKAGE_JSON_VERSION}" ]] && echo "On" || echo "Off") >> $GITHUB_ENV
echo "OSRM_INSTALL_DIR=${GITHUB_WORKSPACE}/install-osrm" >> $GITHUB_ENV echo "OSRM_INSTALL_DIR=${GITHUB_WORKSPACE}/install-osrm" >> $GITHUB_ENV
@@ -414,36 +396,7 @@ jobs:
elif [[ "${RUNNER_OS}" == "macOS" ]]; then elif [[ "${RUNNER_OS}" == "macOS" ]]; then
echo "JOBS=$((`sysctl -n hw.ncpu` + 1))" >> $GITHUB_ENV echo "JOBS=$((`sysctl -n hw.ncpu` + 1))" >> $GITHUB_ENV
fi fi
# See: https://github.com/actions/toolkit/issues/946#issuecomment-1590016041
# We need it to be able to access system folders while restoring cached Boost below
- name: Give tar root ownership
if: runner.os == 'Linux' && matrix.ENABLE_CONAN != 'ON'
run: sudo chown root /bin/tar && sudo chmod u+s /bin/tar
- name: Cache Boost
if: runner.os == 'Linux' && matrix.ENABLE_CONAN != 'ON'
id: cache-boost
uses: actions/cache@v4
with:
path: |
/usr/local/include/boost
/usr/local/lib/libboost*
key: v1-boost-${{ runner.os }}-${{ runner.arch }}-${{ matrix.runs-on }}
restore-keys: |
v1-boost-${{ runner.os }}-${{ runner.arch }}-${{ matrix.runs-on }}
- name: Install Boost
if: steps.cache-boost.outputs.cache-hit != 'true' && runner.os == 'Linux' && matrix.ENABLE_CONAN != 'ON'
run: |
BOOST_VERSION="1.85.0"
BOOST_VERSION_UNDERSCORE="${BOOST_VERSION//./_}"
wget -q https://boostorg.jfrog.io/artifactory/main/release/${BOOST_VERSION}/source/boost_${BOOST_VERSION_UNDERSCORE}.tar.gz
tar xzf boost_${BOOST_VERSION_UNDERSCORE}.tar.gz
cd boost_${BOOST_VERSION_UNDERSCORE}
sudo ./bootstrap.sh
sudo ./b2 install
cd ..
sudo rm -rf boost_${BOOST_VERSION_UNDERSCORE}*
- name: Install dev dependencies - name: Install dev dependencies
run: | run: |
python3 -m pip install "conan<2.0.0" || python3 -m pip install "conan<2.0.0" --break-system-packages python3 -m pip install "conan<2.0.0" || python3 -m pip install "conan<2.0.0" --break-system-packages
@@ -464,7 +417,7 @@ jobs:
# Linux dev packages # Linux dev packages
if [ "${ENABLE_CONAN}" != "ON" ]; then if [ "${ENABLE_CONAN}" != "ON" ]; then
sudo apt-get update -y sudo apt-get update -y
sudo apt-get install -y libbz2-dev libxml2-dev libzip-dev liblua5.2-dev sudo apt-get install -y libbz2-dev libxml2-dev libzip-dev liblua5.2-dev libboost-all-dev
if [[ "${CCOMPILER}" != clang-* ]]; then if [[ "${CCOMPILER}" != clang-* ]]; then
sudo apt-get install -y ${CXXCOMPILER} sudo apt-get install -y ${CXXCOMPILER}
fi fi
@@ -474,7 +427,7 @@ jobs:
fi fi
# TBB # TBB
TBB_VERSION=2021.12.0 TBB_VERSION=2021.3.0
if [[ "${RUNNER_OS}" == "Linux" ]]; then if [[ "${RUNNER_OS}" == "Linux" ]]; then
TBB_URL="https://github.com/oneapi-src/oneTBB/releases/download/v${TBB_VERSION}/oneapi-tbb-${TBB_VERSION}-lin.tgz" TBB_URL="https://github.com/oneapi-src/oneTBB/releases/download/v${TBB_VERSION}/oneapi-tbb-${TBB_VERSION}-lin.tgz"
elif [[ "${RUNNER_OS}" == "macOS" ]]; then elif [[ "${RUNNER_OS}" == "macOS" ]]; then
@@ -505,8 +458,8 @@ jobs:
run: | run: |
echo "Using ${JOBS} jobs" echo "Using ${JOBS} jobs"
pushd ${OSRM_BUILD_DIR} pushd ${OSRM_BUILD_DIR}
ccache --zero-stats
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \ cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
-DENABLE_CONAN=${ENABLE_CONAN:-OFF} \ -DENABLE_CONAN=${ENABLE_CONAN:-OFF} \
-DENABLE_ASSERTIONS=${ENABLE_ASSERTIONS:-OFF} \ -DENABLE_ASSERTIONS=${ENABLE_ASSERTIONS:-OFF} \
@@ -523,7 +476,7 @@ jobs:
if [[ "${NODE_PACKAGE_TESTS_ONLY}" != "ON" ]]; then if [[ "${NODE_PACKAGE_TESTS_ONLY}" != "ON" ]]; then
make tests --jobs=${JOBS} make tests --jobs=${JOBS}
make benchmarks --jobs=${JOBS} make benchmarks --jobs=${JOBS}
ccache -s
sudo make install sudo make install
if [[ "${RUNNER_OS}" == "Linux" ]]; then if [[ "${RUNNER_OS}" == "Linux" ]]; then
echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${OSRM_INSTALL_DIR}/lib" >> $GITHUB_ENV echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${OSRM_INSTALL_DIR}/lib" >> $GITHUB_ENV
@@ -558,7 +511,7 @@ jobs:
- name: Use Node 18 - name: Use Node 18
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == 'ON' }} if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == 'ON' }}
uses: actions/setup-node@v4 uses: actions/setup-node@v3
with: with:
node-version: 18 node-version: 18
- name: Run Node package tests on Node 18 - name: Run Node package tests on Node 18
@@ -568,7 +521,7 @@ jobs:
npm run nodejs-tests npm run nodejs-tests
- name: Use Node 20 - name: Use Node 20
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == 'ON' }} if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == 'ON' }}
uses: actions/setup-node@v4 uses: actions/setup-node@v3
with: with:
node-version: 20 node-version: 20
- name: Run Node package tests on Node 20 - name: Run Node package tests on Node 20
@@ -578,7 +531,7 @@ jobs:
npm run nodejs-tests npm run nodejs-tests
- name: Use Node latest - name: Use Node latest
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == 'ON' }} if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == 'ON' }}
uses: actions/setup-node@v4 uses: actions/setup-node@v3
with: with:
node-version: latest node-version: latest
- name: Run Node package tests on Node-latest - name: Run Node package tests on Node-latest
@@ -588,7 +541,7 @@ jobs:
npm run nodejs-tests npm run nodejs-tests
- name: Upload test logs - name: Upload test logs
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v3
if: failure() if: failure()
with: with:
name: logs name: logs
@@ -604,7 +557,7 @@ jobs:
# # Uploading report to CodeCov # # Uploading report to CodeCov
# - name: Upload code coverage # - name: Upload code coverage
# if: ${{ matrix.ENABLE_COVERAGE == 'ON' }} # if: ${{ matrix.ENABLE_COVERAGE == 'ON' }}
# uses: codecov/codecov-action@v4 # uses: codecov/codecov-action@v1
# with: # with:
# files: coverage.info # files: coverage.info
# name: codecov-osrm-backend # name: codecov-osrm-backend
@@ -626,77 +579,41 @@ jobs:
omitNameDuringUpdate: true omitNameDuringUpdate: true
replacesArtifacts: true replacesArtifacts: true
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
- name: Show CCache statistics
run: |
ccache -p
ccache -s
benchmarks: benchmarks:
if: github.event_name == 'pull_request' if: github.event_name == 'pull_request'
needs: [format-taginfo-docs] needs: [format-taginfo-docs]
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
env: env:
CCOMPILER: gcc-12 #clang-13 CCOMPILER: clang-13
CXXCOMPILER: g++-12 #clang++-13 CXXCOMPILER: clang++-13
CC: gcc-12 #clang-13 CC: clang-13
CXX: g++-12 #clang++-13 CXX: clang++-13
CXXFLAGS: '-Wno-array-bounds -Wno-uninitialized'
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }} PR_NUMBER: ${{ github.event.pull_request.number }}
GITHUB_REPOSITORY: ${{ github.repository }} GITHUB_REPOSITORY: ${{ github.repository }}
RUN_BIG_BENCHMARK: ${{ contains(github.event.pull_request.labels.*.name, 'Performance') }}
steps: steps:
- name: Enable data.osm.pbf cache
if: ${{ ! env.RUN_BIG_BENCHMARK }}
uses: actions/cache@v4
with:
path: ~/data.osm.pbf
key: v1-data-osm-pbf
restore-keys: |
v1-data-osm-pbf
- name: Enable compiler cache - name: Enable compiler cache
uses: actions/cache@v4 uses: actions/cache@v3
with: with:
path: ~/.ccache path: ~/.ccache
key: v1-ccache-benchmarks-${{ github.sha }} key: v1-ccache-benchmarks-${{ github.sha }}
restore-keys: | restore-keys: |
v1-ccache-benchmarks- v1-ccache-benchmarks-
- name: Enable Conan cache - name: Enable Conan cache
uses: actions/cache@v4 uses: actions/cache@v3
with: with:
path: ~/.conan path: ~/.conan
key: v1-conan-benchmarks-${{ github.sha }} key: v1-conan-benchmarks-${{ github.sha }}
restore-keys: | restore-keys: |
v1-conan-benchmarks- v1-conan-benchmarks-
- name: Checkout PR Branch - name: Checkout PR Branch
uses: actions/checkout@v4 uses: actions/checkout@v3
with: with:
ref: ${{ github.head_ref }} ref: ${{ github.head_ref }}
path: pr path: pr
- name: Install dependencies - run: python3 -m pip install "conan<2.0.0" "requests==2.31.0"
run: |
python3 -m pip install "conan<2.0.0" "requests==2.31.0" "numpy==1.26.4" #--break-system-packages
sudo apt-get update -y && sudo apt-get install ccache
- name: Prepare data
run: |
if [ "$RUN_BIG_BENCHMARK" = "true" ]; then
rm -rf ~/data.osm.pbf
wget http://download.geofabrik.de/europe/poland-latest.osm.pbf -O ~/data.osm.pbf --quiet
gunzip -c ./pr/test/data/poland_gps_traces.csv.gz > ~/gps_traces.csv
else
if [ ! -f "~/data.osm.pbf" ]; then
wget http://download.geofabrik.de/europe/germany/berlin-latest.osm.pbf -O ~/data.osm.pbf
else
echo "Using cached data.osm.pbf"
fi
gunzip -c ./pr/test/data/berlin_gps_traces.csv.gz > ~/gps_traces.csv
fi
- name: Prepare environment
run: |
echo "CCACHE_DIR=$HOME/.ccache" >> $GITHUB_ENV
mkdir -p $HOME/.ccache
ccache --zero-stats
ccache --max-size=256M
- name: Build PR Branch - name: Build PR Branch
run: | run: |
mkdir -p pr/build mkdir -p pr/build
@@ -707,7 +624,7 @@ jobs:
cd .. cd ..
make -C test/data make -C test/data
- name: Checkout Base Branch - name: Checkout Base Branch
uses: actions/checkout@v4 uses: actions/checkout@v3
with: with:
ref: ${{ github.event.pull_request.base.ref }} ref: ${{ github.event.pull_request.base.ref }}
path: base path: base
@@ -726,10 +643,6 @@ jobs:
- name: Post Benchmark Results - name: Post Benchmark Results
run: | run: |
python3 pr/scripts/ci/post_benchmark_results.py base_results pr_results python3 pr/scripts/ci/post_benchmark_results.py base_results pr_results
- name: Show CCache statistics
run: |
ccache -p
ccache -s
ci-complete: ci-complete:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
+1 -19
View File
@@ -1,17 +1,12 @@
# Unreleased # Unreleased
- Changes from 5.27.1 - Changes from 5.27.1
- Features - Features
- REMOVED: Remove all core-CH left-overs [#6920](https://github.com/Project-OSRM/osrm-backend/pull/6920)
- ADDED: Add support for a keepalive_timeout flag. [#6674](https://github.com/Project-OSRM/osrm-backend/pull/6674) - ADDED: Add support for a keepalive_timeout flag. [#6674](https://github.com/Project-OSRM/osrm-backend/pull/6674)
- ADDED: Add support for a default_radius flag. [#6575](https://github.com/Project-OSRM/osrm-backend/pull/6575) - ADDED: Add support for a default_radius flag. [#6575](https://github.com/Project-OSRM/osrm-backend/pull/6575)
- ADDED: Add support for disabling feature datasets. [#6666](https://github.com/Project-OSRM/osrm-backend/pull/6666) - ADDED: Add support for disabling feature datasets. [#6666](https://github.com/Project-OSRM/osrm-backend/pull/6666)
- ADDED: Add support for opposite approach request parameter. [#6842](https://github.com/Project-OSRM/osrm-backend/pull/6842) - ADDED: Add support for opposite approach request parameter. [#6842](https://github.com/Project-OSRM/osrm-backend/pull/6842)
- ADDED: Add support for accessing edge flags in `process_segment` [#6658](https://github.com/Project-OSRM/osrm-backend/pull/6658) - ADDED: Add support for accessing edge flags in `process_segment` [#6658](https://github.com/Project-OSRM/osrm-backend/pull/6658)
- Build: - Build:
- CHANGED: Upgrade clang-format to version 15. [#6919](https://github.com/Project-OSRM/osrm-backend/pull/6919)
- CHANGED: Use Debian Bookworm as base Docker image [#6904](https://github.com/Project-OSRM/osrm-backend/pull/6904)
- CHANGED: Upgrade CI actions to latest versions [#6893](https://github.com/Project-OSRM/osrm-backend/pull/6893)
- CHANGED: Remove outdated warnings #6894 [#6894](https://github.com/Project-OSRM/osrm-backend/pull/6894)
- ADDED: Add CI job which builds OSRM with gcc 12. [#6455](https://github.com/Project-OSRM/osrm-backend/pull/6455) - ADDED: Add CI job which builds OSRM with gcc 12. [#6455](https://github.com/Project-OSRM/osrm-backend/pull/6455)
- CHANGED: Upgrade to clang-tidy 15. [#6439](https://github.com/Project-OSRM/osrm-backend/pull/6439) - CHANGED: Upgrade to clang-tidy 15. [#6439](https://github.com/Project-OSRM/osrm-backend/pull/6439)
- CHANGED: Update actions/cache to v3. [#6420](https://github.com/Project-OSRM/osrm-backend/pull/6420) - CHANGED: Update actions/cache to v3. [#6420](https://github.com/Project-OSRM/osrm-backend/pull/6420)
@@ -24,19 +19,7 @@
- NodeJS: - NodeJS:
- CHANGED: Use node-api instead of NAN. [#6452](https://github.com/Project-OSRM/osrm-backend/pull/6452) - CHANGED: Use node-api instead of NAN. [#6452](https://github.com/Project-OSRM/osrm-backend/pull/6452)
- Misc: - Misc:
- FIXED: Fix bugprone-unused-return-value clang-tidy warning. [#6934](https://github.com/Project-OSRM/osrm-backend/pull/6934) - CHANGED: Partial fix migration from boost::optional to std::optional [#6551](https://github.com/Project-OSRM/osrm-backend/issues/6551), see also [#6592](https://github.com/Project-OSRM/osrm-backend/issues/6592)
- FIXED: Fix performance-noexcept-move-constructor clang-tidy warning. [#6931](https://github.com/Project-OSRM/osrm-backend/pull/6933)
- FIXED: Fix performance-noexcept-swap clang-tidy warning. [#6931](https://github.com/Project-OSRM/osrm-backend/pull/6931)
- CHANGED: Use custom struct instead of std::pair in QueryHeap. [#6921](https://github.com/Project-OSRM/osrm-backend/pull/6921)
- CHANGED: Use std::string_view::starts_with instead of boost::starts_with. [#6918](https://github.com/Project-OSRM/osrm-backend/pull/6918)
- CHANGED: Get rid of boost::math::constants::* and M_PI in favor of std::numbers. [#6916](https://github.com/Project-OSRM/osrm-backend/pull/6916)
- CHANGED: Make constants in PackedVector constexpr. [#6917](https://github.com/Project-OSRM/osrm-backend/pull/6917)
- CHANGED: Use std::variant instead of mapbox::util::variant. [#6903](https://github.com/Project-OSRM/osrm-backend/pull/6903)
- CHANGED: Bump rapidjson to version f9d53419e912910fd8fa57d5705fa41425428c35 [#6906](https://github.com/Project-OSRM/osrm-backend/pull/6906)
- CHANGED: Bump mapbox/variant to version 1.2.0 [#6898](https://github.com/Project-OSRM/osrm-backend/pull/6898)
- CHANGED: Avoid copy of std::function-based callback in path unpacking [#6895](https://github.com/Project-OSRM/osrm-backend/pull/6895)
- CHANGED: Replace boost::hash by std::hash [#6892](https://github.com/Project-OSRM/osrm-backend/pull/6892)
- CHANGED: Partial fix migration from boost::optional to std::optional [#6551](https://github.com/Project-OSRM/osrm-backend/issues/6551)
- CHANGED: Update Conan Boost version to 1.85.0. [#6868](https://github.com/Project-OSRM/osrm-backend/pull/6868) - CHANGED: Update Conan Boost version to 1.85.0. [#6868](https://github.com/Project-OSRM/osrm-backend/pull/6868)
- FIXED: Fix an error in a RouteParameters AnnotationsType operator overload. [#6646](https://github.com/Project-OSRM/osrm-backend/pull/6646) - FIXED: Fix an error in a RouteParameters AnnotationsType operator overload. [#6646](https://github.com/Project-OSRM/osrm-backend/pull/6646)
- ADDED: Add support for "unlimited" to be passed as a value for the default-radius and max-matching-radius flags. [#6599](https://github.com/Project-OSRM/osrm-backend/pull/6599) - ADDED: Add support for "unlimited" to be passed as a value for the default-radius and max-matching-radius flags. [#6599](https://github.com/Project-OSRM/osrm-backend/pull/6599)
@@ -66,7 +49,6 @@
- FIXED: Remove force-loop checks for routes with u-turns [#6858](https://github.com/Project-OSRM/osrm-backend/pull/6858) - FIXED: Remove force-loop checks for routes with u-turns [#6858](https://github.com/Project-OSRM/osrm-backend/pull/6858)
- FIXED: Correctly check runtime search conditions for forcing routing steps [#6866](https://github.com/Project-OSRM/osrm-backend/pull/6866) - FIXED: Correctly check runtime search conditions for forcing routing steps [#6866](https://github.com/Project-OSRM/osrm-backend/pull/6866)
- Map Matching: - Map Matching:
- CHANGED: Optimise path distance calculation in MLD map matching even more. [#6884](https://github.com/Project-OSRM/osrm-backend/pull/6884)
- CHANGED: Optimise path distance calculation in MLD map matching. [#6876](https://github.com/Project-OSRM/osrm-backend/pull/6876) - CHANGED: Optimise path distance calculation in MLD map matching. [#6876](https://github.com/Project-OSRM/osrm-backend/pull/6876)
- CHANGED: Optimise R-tree queries in the case of map matching. [#6881](https://github.com/Project-OSRM/osrm-backend/pull/6876) - CHANGED: Optimise R-tree queries in the case of map matching. [#6881](https://github.com/Project-OSRM/osrm-backend/pull/6876)
- Debug tiles: - Debug tiles:
+7 -3
View File
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.18) cmake_minimum_required(VERSION 3.18)
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_EXTENSIONS OFF)
@@ -31,7 +31,7 @@ option(ENABLE_ASSERTIONS "Use assertions in release mode" OFF)
option(ENABLE_DEBUG_LOGGING "Use debug logging in release mode" OFF) option(ENABLE_DEBUG_LOGGING "Use debug logging in release mode" OFF)
option(ENABLE_COVERAGE "Build with coverage instrumentalisation" OFF) option(ENABLE_COVERAGE "Build with coverage instrumentalisation" OFF)
option(ENABLE_SANITIZER "Use memory sanitizer for Debug build" OFF) option(ENABLE_SANITIZER "Use memory sanitizer for Debug build" OFF)
option(ENABLE_LTO "Use LTO if available" ON) option(ENABLE_LTO "Use LTO if available" OFF)
option(ENABLE_FUZZING "Fuzz testing using LLVM's libFuzzer" OFF) option(ENABLE_FUZZING "Fuzz testing using LLVM's libFuzzer" OFF)
option(ENABLE_NODE_BINDINGS "Build NodeJs bindings" OFF) option(ENABLE_NODE_BINDINGS "Build NodeJs bindings" OFF)
option(ENABLE_CLANG_TIDY "Enables clang-tidy checks" OFF) option(ENABLE_CLANG_TIDY "Enables clang-tidy checks" OFF)
@@ -120,7 +120,8 @@ endif()
include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/include/) include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/include/)
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/include/) include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/include/)
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/sol2/include) include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/sol2-3.3.0/include)
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/variant/include)
set(BOOST_COMPONENTS date_time chrono filesystem iostreams program_options regex system thread unit_test_framework) set(BOOST_COMPONENTS date_time chrono filesystem iostreams program_options regex system thread unit_test_framework)
@@ -266,6 +267,7 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
add_dependency_defines(-DBOOST_LIB_DIAGNOSTIC) add_dependency_defines(-DBOOST_LIB_DIAGNOSTIC)
add_dependency_defines(-D_CRT_SECURE_NO_WARNINGS) add_dependency_defines(-D_CRT_SECURE_NO_WARNINGS)
add_dependency_defines(-DNOMINMAX) # avoid min and max macros that can break compilation add_dependency_defines(-DNOMINMAX) # avoid min and max macros that can break compilation
add_dependency_defines(-D_USE_MATH_DEFINES) #needed for M_PI with cmath.h
add_dependency_defines(-D_WIN32_WINNT=0x0501) add_dependency_defines(-D_WIN32_WINNT=0x0501)
add_dependency_defines(-DXML_STATIC) add_dependency_defines(-DXML_STATIC)
find_library(ws2_32_LIBRARY_PATH ws2_32) find_library(ws2_32_LIBRARY_PATH ws2_32)
@@ -605,6 +607,7 @@ if (BUILD_ROUTED)
set_property(TARGET osrm-routed PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE) set_property(TARGET osrm-routed PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
endif() endif()
file(GLOB VariantGlob third_party/variant/include/mapbox/*.hpp)
file(GLOB FlatbuffersGlob third_party/flatbuffers/include/flatbuffers/*.h) file(GLOB FlatbuffersGlob third_party/flatbuffers/include/flatbuffers/*.h)
file(GLOB LibraryGlob include/osrm/*.hpp) file(GLOB LibraryGlob include/osrm/*.hpp)
file(GLOB ParametersGlob include/engine/api/*_parameters.hpp) file(GLOB ParametersGlob include/engine/api/*_parameters.hpp)
@@ -624,6 +627,7 @@ install(FILES ${ContractorHeader} DESTINATION include/osrm/contractor)
install(FILES ${LibraryGlob} DESTINATION include/osrm) install(FILES ${LibraryGlob} DESTINATION include/osrm)
install(FILES ${ParametersGlob} DESTINATION include/osrm/engine/api) install(FILES ${ParametersGlob} DESTINATION include/osrm/engine/api)
install(FILES ${ApiHeader} DESTINATION include/osrm/engine/api) install(FILES ${ApiHeader} DESTINATION include/osrm/engine/api)
install(FILES ${VariantGlob} DESTINATION include/mapbox)
install(FILES ${FlatbuffersGlob} DESTINATION include/flatbuffers) install(FILES ${FlatbuffersGlob} DESTINATION include/flatbuffers)
install(TARGETS osrm-extract DESTINATION bin) install(TARGETS osrm-extract DESTINATION bin)
install(TARGETS osrm-partition DESTINATION bin) install(TARGETS osrm-partition DESTINATION bin)
+1 -1
View File
@@ -55,7 +55,7 @@ function(_get_msvc_ide_version result)
set(${result} 15 PARENT_SCOPE) set(${result} 15 PARENT_SCOPE)
elseif(NOT MSVC_VERSION VERSION_LESS 1920 AND MSVC_VERSION VERSION_LESS 1930) elseif(NOT MSVC_VERSION VERSION_LESS 1920 AND MSVC_VERSION VERSION_LESS 1930)
set(${result} 16 PARENT_SCOPE) set(${result} 16 PARENT_SCOPE)
elseif(NOT MSVC_VERSION VERSION_LESS 1930 AND MSVC_VERSION VERSION_LESS 1950) elseif(NOT MSVC_VERSION VERSION_LESS 1930 AND MSVC_VERSION VERSION_LESS 1940)
set(${result} 17 PARENT_SCOPE) set(${result} 17 PARENT_SCOPE)
else() else()
message(FATAL_ERROR "Conan: Unknown MSVC compiler version [${MSVC_VERSION}]") message(FATAL_ERROR "Conan: Unknown MSVC compiler version [${MSVC_VERSION}]")
+15 -8
View File
@@ -50,7 +50,9 @@ add_warning(all)
add_warning(extra) add_warning(extra)
add_warning(pedantic) add_warning(pedantic)
add_warning(error) # treat all warnings as errors add_warning(error) # treat all warnings as errors
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_warning(strict-overflow=2)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
add_warning(strict-overflow=1) add_warning(strict-overflow=1)
endif() endif()
add_warning(suggest-override) add_warning(suggest-override)
@@ -77,10 +79,15 @@ add_warning(sizeof-array-argument)
add_warning(switch-bool) add_warning(switch-bool)
add_warning(tautological-compare) add_warning(tautological-compare)
add_warning(trampolines) add_warning(trampolines)
# these warnings are not enabled by default no_warning(c++17-extensions)
# no_warning(name-of-warning) # TODO: these warnings are not enabled by default, but we consider them as useful and good to enable in the future
no_warning(deprecated-comma-subscript) no_warning(implicit-int-conversion)
no_warning(comma-subscript) no_warning(implicit-float-conversion)
no_warning(ambiguous-reversed-operator) no_warning(unused-member-function)
no_warning(restrict) no_warning(old-style-cast)
no_warning(free-nonheap-object) no_warning(non-virtual-dtor)
no_warning(float-conversion)
no_warning(sign-conversion)
no_warning(shorten-64-to-32)
no_warning(padded)
no_warning(missing-noreturn)
+7 -8
View File
@@ -1,15 +1,15 @@
FROM debian:bookworm-slim as builder FROM debian:bullseye-slim as builder
ARG DOCKER_TAG ARG DOCKER_TAG
ARG BUILD_CONCURRENCY ARG BUILD_CONCURRENCY
RUN mkdir -p /src && mkdir -p /opt RUN mkdir -p /src && mkdir -p /opt
RUN apt-get update && \ RUN apt-get update && \
apt-get -y --no-install-recommends install ca-certificates cmake make git gcc g++ libbz2-dev libxml2-dev wget \ apt-get -y --no-install-recommends install ca-certificates cmake make git gcc g++ libbz2-dev libxml2-dev wget \
libzip-dev libboost1.81-all-dev lua5.4 liblua5.4-dev pkg-config -o APT::Install-Suggests=0 -o APT::Install-Recommends=0 libzip-dev libboost1.74-all-dev lua5.4 liblua5.4-dev pkg-config -o APT::Install-Suggests=0 -o APT::Install-Recommends=0
RUN NPROC=${BUILD_CONCURRENCY:-$(nproc)} && \ RUN NPROC=${BUILD_CONCURRENCY:-$(nproc)} && \
ldconfig /usr/local/lib && \ ldconfig /usr/local/lib && \
git clone --branch v2021.12.0 --single-branch https://github.com/oneapi-src/oneTBB.git && \ git clone --branch v2021.3.0 --single-branch https://github.com/oneapi-src/oneTBB.git && \
cd oneTBB && \ cd oneTBB && \
mkdir build && \ mkdir build && \
cd build && \ cd build && \
@@ -21,7 +21,6 @@ COPY . /src
WORKDIR /src WORKDIR /src
RUN NPROC=${BUILD_CONCURRENCY:-$(nproc)} && \ RUN NPROC=${BUILD_CONCURRENCY:-$(nproc)} && \
export CXXFLAGS="-Wno-array-bounds -Wno-uninitialized" && \
echo "Building OSRM ${DOCKER_TAG}" && \ echo "Building OSRM ${DOCKER_TAG}" && \
git show --format="%H" | head -n1 > /opt/OSRM_GITSHA && \ git show --format="%H" | head -n1 > /opt/OSRM_GITSHA && \
echo "Building OSRM gitsha $(cat /opt/OSRM_GITSHA)" && \ echo "Building OSRM gitsha $(cat /opt/OSRM_GITSHA)" && \
@@ -43,15 +42,15 @@ RUN NPROC=${BUILD_CONCURRENCY:-$(nproc)} && \
# Multistage build to reduce image size - https://docs.docker.com/engine/userguide/eng-image/multistage-build/#use-multi-stage-builds # Multistage build to reduce image size - https://docs.docker.com/engine/userguide/eng-image/multistage-build/#use-multi-stage-builds
# Only the content below ends up in the image, this helps remove /src from the image (which is large) # Only the content below ends up in the image, this helps remove /src from the image (which is large)
FROM debian:bookworm-slim as runstage FROM debian:bullseye-slim as runstage
COPY --from=builder /usr/local /usr/local COPY --from=builder /usr/local /usr/local
COPY --from=builder /opt /opt COPY --from=builder /opt /opt
RUN apt-get update && \ RUN apt-get update && \
apt-get install -y --no-install-recommends libboost-program-options1.81.0 libboost-regex1.81.0 \ apt-get install -y --no-install-recommends libboost-program-options1.74.0 libboost-regex1.74.0 \
libboost-date-time1.81.0 libboost-chrono1.81.0 libboost-filesystem1.81.0 \ libboost-date-time1.74.0 libboost-chrono1.74.0 libboost-filesystem1.74.0 \
libboost-iostreams1.81.0 libboost-system1.81.0 libboost-thread1.81.0 \ libboost-iostreams1.74.0 libboost-system1.74.0 libboost-thread1.74.0 \
expat liblua5.4-0 && \ expat liblua5.4-0 && \
rm -rf /var/lib/apt/lists/* && \ rm -rf /var/lib/apt/lists/* && \
# add /usr/local/lib to ldconfig to allow loading libraries from there # add /usr/local/lib to ldconfig to allow loading libraries from there
+1 -1
View File
@@ -21,7 +21,7 @@ var osrm = new OSRM('network.osrm');
**Parameters** **Parameters**
- `options` **([Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object) \| [String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String))** Options for creating an OSRM object or string to the `.osrm` file. (optional, default `{shared_memory:true}`) - `options` **([Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object) \| [String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String))** Options for creating an OSRM object or string to the `.osrm` file. (optional, default `{shared_memory:true}`)
- `options.algorithm` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** The algorithm to use for routing. Can be 'CH', or 'MLD'. Default is 'CH'. - `options.algorithm` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** The algorithm to use for routing. Can be 'CH', 'CoreCH' or 'MLD'. Default is 'CH'.
Make sure you prepared the dataset with the correct toolchain. Make sure you prepared the dataset with the correct toolchain.
- `options.shared_memory` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Connects to the persistent shared memory datastore. - `options.shared_memory` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Connects to the persistent shared memory datastore.
This requires you to run `osrm-datastore` prior to creating an `OSRM` object. This requires you to run `osrm-datastore` prior to creating an `OSRM` object.
+7 -7
View File
@@ -57,15 +57,15 @@ int main(int argc, const char *argv[])
// Execute routing request, this does the heavy lifting // Execute routing request, this does the heavy lifting
const auto status = osrm.Route(params, result); const auto status = osrm.Route(params, result);
auto &json_result = std::get<json::Object>(result); auto &json_result = result.get<json::Object>();
if (status == Status::Ok) if (status == Status::Ok)
{ {
auto &routes = std::get<json::Array>(json_result.values["routes"]); auto &routes = json_result.values["routes"].get<json::Array>();
// Let's just use the first route // Let's just use the first route
auto &route = std::get<json::Object>(routes.values.at(0)); auto &route = routes.values.at(0).get<json::Object>();
const auto distance = std::get<json::Number>(route.values["distance"]).value; const auto distance = route.values["distance"].get<json::Number>().value;
const auto duration = std::get<json::Number>(route.values["duration"]).value; const auto duration = route.values["duration"].get<json::Number>().value;
// Warn users if extract does not contain the default coordinates from above // Warn users if extract does not contain the default coordinates from above
if (distance == 0 || duration == 0) if (distance == 0 || duration == 0)
@@ -80,8 +80,8 @@ int main(int argc, const char *argv[])
} }
else if (status == Status::Error) else if (status == Status::Error)
{ {
const auto code = std::get<json::String>(json_result.values["code"]).value; const auto code = json_result.values["code"].get<json::String>().value;
const auto message = std::get<json::String>(json_result.values["message"]).value; const auto message = json_result.values["message"].get<json::String>().value;
std::cout << "Code: " << code << "\n"; std::cout << "Code: " << code << "\n";
std::cout << "Message: " << code << "\n"; std::cout << "Message: " << code << "\n";
+128
View File
@@ -0,0 +1,128 @@
#ifndef ITERATOR_BASED_CRC32_H
#define ITERATOR_BASED_CRC32_H
#if defined(__x86_64__) && !defined(__MINGW64__)
#include <cpuid.h>
#endif
#include <boost/crc.hpp> // for boost::crc_32_type
#include <iterator>
namespace osrm::contractor
{
class IteratorbasedCRC32
{
public:
bool UsingHardware() const { return use_hardware_implementation; }
IteratorbasedCRC32() : crc(0) { use_hardware_implementation = DetectHardwareSupport(); }
template <class Iterator> unsigned operator()(Iterator iter, const Iterator end)
{
unsigned crc = 0;
while (iter != end)
{
using value_type = typename std::iterator_traits<Iterator>::value_type;
const char *data = reinterpret_cast<const char *>(&(*iter));
if (use_hardware_implementation)
{
crc = ComputeInHardware(data, sizeof(value_type));
}
else
{
crc = ComputeInSoftware(data, sizeof(value_type));
}
++iter;
}
return crc;
}
private:
bool DetectHardwareSupport() const
{
static const int sse42_bit = 0x00100000;
const unsigned ecx = cpuid();
const bool sse42_found = (ecx & sse42_bit) != 0;
return sse42_found;
}
unsigned ComputeInSoftware(const char *str, unsigned len)
{
crc_processor.process_bytes(str, len);
return crc_processor.checksum();
}
// adapted from http://byteworm.com/2010/10/13/crc32/
unsigned ComputeInHardware(const char *str, unsigned len)
{
#if defined(__x86_64__)
unsigned q = len / sizeof(unsigned);
unsigned r = len % sizeof(unsigned);
unsigned *p = (unsigned *)str;
// crc=0;
while (q--)
{
__asm__ __volatile__(".byte 0xf2, 0xf, 0x38, 0xf1, 0xf1;"
: "=S"(crc)
: "0"(crc), "c"(*p));
++p;
}
str = reinterpret_cast<char *>(p);
while (r--)
{
__asm__ __volatile__(".byte 0xf2, 0xf, 0x38, 0xf1, 0xf1;"
: "=S"(crc)
: "0"(crc), "c"(*str));
++str;
}
#else
(void)str;
(void)len;
#endif
return crc;
}
inline unsigned cpuid() const
{
unsigned eax = 0, ebx = 0, ecx = 0, edx = 0;
// on X64 this calls hardware cpuid(.) instr. otherwise a dummy impl.
__get_cpuid(1, &eax, &ebx, &ecx, &edx);
return ecx;
}
#if defined(__MINGW64__) || defined(_MSC_VER) || !defined(__x86_64__)
inline void __get_cpuid(int /*param*/,
unsigned * /*eax*/,
unsigned * /*ebx*/,
unsigned *ecx,
unsigned * /*edx*/) const
{
*ecx = 0;
}
#endif
boost::crc_optimal<32, 0x1EDC6F41, 0x0, 0x0, true, true> crc_processor;
unsigned crc;
bool use_hardware_implementation;
};
struct RangebasedCRC32
{
template <typename Iteratable> unsigned operator()(const Iteratable &iterable)
{
return crc32(std::begin(iterable), std::end(iterable));
}
bool UsingHardware() const { return crc32.UsingHardware(); }
private:
IteratorbasedCRC32 crc32;
};
} // namespace osrm::contractor
#endif /* ITERATOR_BASED_CRC32_H */
+3 -2
View File
@@ -2,7 +2,7 @@
#define ENGINE_API_BASE_RESULT_HPP #define ENGINE_API_BASE_RESULT_HPP
#include <flatbuffers/flatbuffers.h> #include <flatbuffers/flatbuffers.h>
#include <variant> #include <mapbox/variant.hpp>
#include <string> #include <string>
@@ -10,7 +10,8 @@
namespace osrm::engine::api namespace osrm::engine::api
{ {
using ResultT = std::variant<util::json::Object, std::string, flatbuffers::FlatBufferBuilder>; using ResultT =
mapbox::util::variant<util::json::Object, std::string, flatbuffers::FlatBufferBuilder>;
} // namespace osrm::engine::api } // namespace osrm::engine::api
#endif #endif
+2 -2
View File
@@ -41,7 +41,7 @@ inline bool hasValidLanes(const guidance::IntermediateIntersection &intersection
return intersection.lanes.lanes_in_turn > 0; return intersection.lanes.lanes_in_turn > 0;
} }
util::json::Value coordinateToLonLat(const util::Coordinate &coordinate); util::json::Array coordinateToLonLat(const util::Coordinate &coordinate);
/** /**
* Ensures that a bearing value is a whole number, and clamped to the range 0-359 * Ensures that a bearing value is a whole number, and clamped to the range 0-359
@@ -79,7 +79,7 @@ util::json::Object makeGeoJSONGeometry(ForwardIter begin, ForwardIter end)
coordinates.values.push_back(location); coordinates.values.push_back(location);
coordinates.values.push_back(location); coordinates.values.push_back(location);
} }
geojson.values["coordinates"] = util::json::Value{std::move(coordinates)}; geojson.values["coordinates"] = std::move(coordinates);
return geojson; return geojson;
} }
+3 -3
View File
@@ -30,14 +30,14 @@ class MatchAPI final : public RouteAPI
osrm::engine::api::ResultT &response) const osrm::engine::api::ResultT &response) const
{ {
BOOST_ASSERT(sub_matchings.size() == sub_routes.size()); BOOST_ASSERT(sub_matchings.size() == sub_routes.size());
if (std::holds_alternative<flatbuffers::FlatBufferBuilder>(response)) if (response.is<flatbuffers::FlatBufferBuilder>())
{ {
auto &fb_result = std::get<flatbuffers::FlatBufferBuilder>(response); auto &fb_result = response.get<flatbuffers::FlatBufferBuilder>();
MakeResponse(sub_matchings, sub_routes, fb_result); MakeResponse(sub_matchings, sub_routes, fb_result);
} }
else else
{ {
auto &json_result = std::get<util::json::Object>(response); auto &json_result = response.get<util::json::Object>();
MakeResponse(sub_matchings, sub_routes, json_result); MakeResponse(sub_matchings, sub_routes, json_result);
} }
} }
+3 -3
View File
@@ -29,14 +29,14 @@ class NearestAPI final : public BaseAPI
BOOST_ASSERT(phantom_nodes.size() == 1); BOOST_ASSERT(phantom_nodes.size() == 1);
BOOST_ASSERT(parameters.coordinates.size() == 1); BOOST_ASSERT(parameters.coordinates.size() == 1);
if (std::holds_alternative<flatbuffers::FlatBufferBuilder>(response)) if (response.is<flatbuffers::FlatBufferBuilder>())
{ {
auto &fb_result = std::get<flatbuffers::FlatBufferBuilder>(response); auto &fb_result = response.get<flatbuffers::FlatBufferBuilder>();
MakeResponse(phantom_nodes, fb_result); MakeResponse(phantom_nodes, fb_result);
} }
else else
{ {
auto &json_result = std::get<util::json::Object>(response); auto &json_result = response.get<util::json::Object>();
MakeResponse(phantom_nodes, json_result); MakeResponse(phantom_nodes, json_result);
} }
} }
+27 -25
View File
@@ -50,14 +50,14 @@ class RouteAPI : public BaseAPI
{ {
BOOST_ASSERT(!raw_routes.routes.empty()); BOOST_ASSERT(!raw_routes.routes.empty());
if (std::holds_alternative<flatbuffers::FlatBufferBuilder>(response)) if (response.is<flatbuffers::FlatBufferBuilder>())
{ {
auto &fb_result = std::get<flatbuffers::FlatBufferBuilder>(response); auto &fb_result = response.get<flatbuffers::FlatBufferBuilder>();
MakeResponse(raw_routes, waypoint_candidates, fb_result); MakeResponse(raw_routes, waypoint_candidates, fb_result);
} }
else else
{ {
auto &json_result = std::get<util::json::Object>(response); auto &json_result = response.get<util::json::Object>();
MakeResponse(raw_routes, waypoint_candidates, json_result); MakeResponse(raw_routes, waypoint_candidates, json_result);
} }
} }
@@ -158,8 +158,8 @@ class RouteAPI : public BaseAPI
} }
template <typename ForwardIter> template <typename ForwardIter>
std::variant<flatbuffers::Offset<flatbuffers::String>, mapbox::util::variant<flatbuffers::Offset<flatbuffers::String>,
flatbuffers::Offset<flatbuffers::Vector<const fbresult::Position *>>> flatbuffers::Offset<flatbuffers::Vector<const fbresult::Position *>>>
MakeGeometry(flatbuffers::FlatBufferBuilder &builder, ForwardIter begin, ForwardIter end) const MakeGeometry(flatbuffers::FlatBufferBuilder &builder, ForwardIter begin, ForwardIter end) const
{ {
if (parameters.geometries == RouteParameters::GeometriesType::Polyline) if (parameters.geometries == RouteParameters::GeometriesType::Polyline)
@@ -408,8 +408,8 @@ class RouteAPI : public BaseAPI
// Fill geometry // Fill geometry
auto overview = MakeOverview(leg_geometries); auto overview = MakeOverview(leg_geometries);
std::variant<flatbuffers::Offset<flatbuffers::String>, mapbox::util::variant<flatbuffers::Offset<flatbuffers::String>,
flatbuffers::Offset<flatbuffers::Vector<const fbresult::Position *>>> flatbuffers::Offset<flatbuffers::Vector<const fbresult::Position *>>>
geometry; geometry;
if (overview) if (overview)
{ {
@@ -426,7 +426,8 @@ class RouteAPI : public BaseAPI
routeObject.add_legs(legs_vector); routeObject.add_legs(legs_vector);
if (overview) if (overview)
{ {
std::visit(GeometryVisitor<fbresult::RouteObjectBuilder>(routeObject), geometry); mapbox::util::apply_visitor(GeometryVisitor<fbresult::RouteObjectBuilder>(routeObject),
geometry);
} }
return routeObject.Finish(); return routeObject.Finish();
@@ -442,22 +443,23 @@ class RouteAPI : public BaseAPI
if (requested_annotations & RouteParameters::AnnotationsType::Speed) if (requested_annotations & RouteParameters::AnnotationsType::Speed)
{ {
double prev_speed = 0; double prev_speed = 0;
speed = GetAnnotations<float>( speed =
fb_result, GetAnnotations<float>(fb_result,
leg_geometry, leg_geometry,
[&prev_speed](const guidance::LegGeometry::Annotation &anno) [&prev_speed](const guidance::LegGeometry::Annotation &anno)
{ {
if (anno.duration < std::numeric_limits<float>::min()) if (anno.duration < std::numeric_limits<float>::min())
{ {
return prev_speed; return prev_speed;
} }
else else
{ {
auto speed = std::round(anno.distance / anno.duration * 10.) / 10.; auto speed =
prev_speed = speed; round(anno.distance / anno.duration * 10.) / 10.;
return util::json::clamp_float(speed); prev_speed = speed;
} return util::json::clamp_float(speed);
}); }
});
} }
flatbuffers::Offset<flatbuffers::Vector<uint32_t>> duration; flatbuffers::Offset<flatbuffers::Vector<uint32_t>> duration;
@@ -643,7 +645,7 @@ class RouteAPI : public BaseAPI
stepBuilder.add_rotary_pronunciation(rotary_pronunciation_string); stepBuilder.add_rotary_pronunciation(rotary_pronunciation_string);
stepBuilder.add_intersections(intersections_vector); stepBuilder.add_intersections(intersections_vector);
stepBuilder.add_maneuver(maneuver_buffer); stepBuilder.add_maneuver(maneuver_buffer);
std::visit(GeometryVisitor<fbresult::StepBuilder>(stepBuilder), geometry); mapbox::util::apply_visitor(GeometryVisitor<fbresult::StepBuilder>(stepBuilder), geometry);
return stepBuilder.Finish(); return stepBuilder.Finish();
}; };
+14 -18
View File
@@ -50,14 +50,14 @@ class TableAPI final : public BaseAPI
const std::vector<TableCellRef> &fallback_speed_cells, const std::vector<TableCellRef> &fallback_speed_cells,
osrm::engine::api::ResultT &response) const osrm::engine::api::ResultT &response) const
{ {
if (std::holds_alternative<flatbuffers::FlatBufferBuilder>(response)) if (response.is<flatbuffers::FlatBufferBuilder>())
{ {
auto &fb_result = std::get<flatbuffers::FlatBufferBuilder>(response); auto &fb_result = response.get<flatbuffers::FlatBufferBuilder>();
MakeResponse(tables, candidates, fallback_speed_cells, fb_result); MakeResponse(tables, candidates, fallback_speed_cells, fb_result);
} }
else else
{ {
auto &json_result = std::get<util::json::Object>(response); auto &json_result = response.get<util::json::Object>();
MakeResponse(tables, candidates, fallback_speed_cells, json_result); MakeResponse(tables, candidates, fallback_speed_cells, json_result);
} }
} }
@@ -377,8 +377,7 @@ class TableAPI final : public BaseAPI
return util::json::Value( return util::json::Value(
util::json::Number(from_alias<double>(duration) / 10.)); util::json::Number(from_alias<double>(duration) / 10.));
}); });
json_table.values.push_back(std::move(json_row));
json_table.values.push_back(util::json::Value{json_row});
} }
return json_table; return json_table;
} }
@@ -407,7 +406,7 @@ class TableAPI final : public BaseAPI
return util::json::Value(util::json::Number( return util::json::Value(util::json::Number(
std::round(from_alias<double>(distance) * 10) / 10.)); std::round(from_alias<double>(distance) * 10) / 10.));
}); });
json_table.values.push_back(util::json::Value{json_row}); json_table.values.push_back(std::move(json_row));
} }
return json_table; return json_table;
} }
@@ -416,18 +415,15 @@ class TableAPI final : public BaseAPI
MakeEstimatesTable(const std::vector<TableCellRef> &fallback_speed_cells) const MakeEstimatesTable(const std::vector<TableCellRef> &fallback_speed_cells) const
{ {
util::json::Array json_table; util::json::Array json_table;
std::for_each( std::for_each(fallback_speed_cells.begin(),
fallback_speed_cells.begin(), fallback_speed_cells.end(),
fallback_speed_cells.end(), [&](const auto &cell)
[&](const auto &cell) {
{ util::json::Array row;
util::json::Array row; row.values.push_back(util::json::Number(cell.row));
util::json::Value jCellRow{util::json::Number(static_cast<double>(cell.row))}; row.values.push_back(util::json::Number(cell.column));
util::json::Value jCellColumn{util::json::Number(static_cast<double>(cell.column))}; json_table.values.push_back(std::move(row));
row.values.push_back(jCellRow); });
row.values.push_back(jCellColumn);
json_table.values.push_back(util::json::Value{row});
});
return json_table; return json_table;
} }
+3 -3
View File
@@ -27,14 +27,14 @@ class TripAPI final : public RouteAPI
{ {
BOOST_ASSERT(sub_trips.size() == sub_routes.size()); BOOST_ASSERT(sub_trips.size() == sub_routes.size());
if (std::holds_alternative<flatbuffers::FlatBufferBuilder>(response)) if (response.is<flatbuffers::FlatBufferBuilder>())
{ {
auto &fb_result = std::get<flatbuffers::FlatBufferBuilder>(response); auto &fb_result = response.get<flatbuffers::FlatBufferBuilder>();
MakeResponse(sub_trips, sub_routes, candidates, fb_result); MakeResponse(sub_trips, sub_routes, candidates, fb_result);
} }
else else
{ {
auto &json_result = std::get<util::json::Object>(response); auto &json_result = response.get<util::json::Object>();
MakeResponse(sub_trips, sub_routes, candidates, json_result); MakeResponse(sub_trips, sub_routes, candidates, json_result);
} }
} }
@@ -55,7 +55,7 @@ template <> class AlgorithmDataFacade<CH>
virtual EdgeID FindSmallestEdge(const NodeID edge_based_node_from, virtual EdgeID FindSmallestEdge(const NodeID edge_based_node_from,
const NodeID edge_based_node_to, const NodeID edge_based_node_to,
const std::function<bool(const EdgeData &)> &filter) const = 0; const std::function<bool(EdgeData)> filter) const = 0;
}; };
template <> class AlgorithmDataFacade<MLD> template <> class AlgorithmDataFacade<MLD>
@@ -130,10 +130,9 @@ class ContiguousInternalMemoryAlgorithmDataFacade<CH> : public datafacade::Algor
edge_based_node_from, edge_based_node_to, result); edge_based_node_from, edge_based_node_to, result);
} }
EdgeID EdgeID FindSmallestEdge(const NodeID edge_based_node_from,
FindSmallestEdge(const NodeID edge_based_node_from, const NodeID edge_based_node_to,
const NodeID edge_based_node_to, std::function<bool(EdgeData)> filter) const override final
const std::function<bool(const EdgeData &)> &filter) const override final
{ {
return m_query_graph.FindSmallestEdge(edge_based_node_from, edge_based_node_to, filter); return m_query_graph.FindSmallestEdge(edge_based_node_from, edge_based_node_to, filter);
} }
+6 -1
View File
@@ -54,10 +54,14 @@ namespace osrm::engine
* *
* In addition, shared memory can be used for datasets loaded with osrm-datastore. * In addition, shared memory can be used for datasets loaded with osrm-datastore.
* *
* You can chose between two algorithms: * You can chose between three algorithms:
* - Algorithm::CH * - Algorithm::CH
* Contraction Hierarchies, extremely fast queries but slow pre-processing. The default right * Contraction Hierarchies, extremely fast queries but slow pre-processing. The default right
* now. * now.
* - Algorithm::CoreCH
* Deprecated, to be removed in v6.0
* Contraction Hierachies with partial contraction for faster pre-processing but slower
* queries.
* - Algorithm::MLD * - Algorithm::MLD
* Multi Level Dijkstra, moderately fast in both pre-processing and query. * Multi Level Dijkstra, moderately fast in both pre-processing and query.
* *
@@ -70,6 +74,7 @@ struct EngineConfig final
enum class Algorithm enum class Algorithm
{ {
CH, CH,
CoreCH, // Deprecated, will be removed in v6.0
MLD MLD
}; };
-2
View File
@@ -12,8 +12,6 @@
#include "osrm/coordinate.hpp" #include "osrm/coordinate.hpp"
#include <boost/optional.hpp>
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
#include <iterator> #include <iterator>
+5 -3
View File
@@ -1,6 +1,7 @@
#ifndef OSRM_ENGINE_GUIDANCE_COLLAPSE_HPP #ifndef OSRM_ENGINE_GUIDANCE_COLLAPSE_HPP
#include "engine/guidance/route_step.hpp" #include "engine/guidance/route_step.hpp"
#include "util/attributes.hpp"
#include <type_traits> #include <type_traits>
#include <vector> #include <vector>
@@ -11,15 +12,16 @@ namespace osrm::engine::guidance
// Multiple possible reasons can result in unnecessary/confusing instructions // Multiple possible reasons can result in unnecessary/confusing instructions
// Collapsing such turns into a single turn instruction, we give a clearer // Collapsing such turns into a single turn instruction, we give a clearer
// set of instructions that is not cluttered by unnecessary turns/name changes. // set of instructions that is not cluttered by unnecessary turns/name changes.
[[nodiscard]] std::vector<RouteStep> collapseTurnInstructions(std::vector<RouteStep> steps); OSRM_ATTR_WARN_UNUSED
std::vector<RouteStep> collapseTurnInstructions(std::vector<RouteStep> steps);
// Multiple possible reasons can result in unnecessary/confusing instructions // Multiple possible reasons can result in unnecessary/confusing instructions
// A prime example would be a segregated intersection. Turning around at this // A prime example would be a segregated intersection. Turning around at this
// intersection would result in two instructions to turn left. // intersection would result in two instructions to turn left.
// Collapsing such turns into a single turn instruction, we give a clearer // Collapsing such turns into a single turn instruction, we give a clearer
// set of instructions that is not cluttered by unnecessary turns/name changes. // set of instructions that is not cluttered by unnecessary turns/name changes.
[[nodiscard]] std::vector<RouteStep> OSRM_ATTR_WARN_UNUSED
collapseSegregatedTurnInstructions(std::vector<RouteStep> steps); std::vector<RouteStep> collapseSegregatedTurnInstructions(std::vector<RouteStep> steps);
// A combined turn is a set of two instructions that actually form a single turn, as far as we // A combined turn is a set of two instructions that actually form a single turn, as far as we
// perceive it. A u-turn consisting of two left turns is one such example. But there are also lots // perceive it. A u-turn consisting of two left turns is one such example. But there are also lots
@@ -3,6 +3,7 @@
#include "guidance/turn_instruction.hpp" #include "guidance/turn_instruction.hpp"
#include "engine/guidance/route_step.hpp" #include "engine/guidance/route_step.hpp"
#include "util/attributes.hpp"
#include "util/bearing.hpp" #include "util/bearing.hpp"
#include "util/guidance/name_announcements.hpp" #include "util/guidance/name_announcements.hpp"
@@ -165,7 +166,8 @@ inline bool areSameSide(const RouteStep &lhs, const RouteStep &rhs)
} }
// do this after invalidating any steps to compress the step array again // do this after invalidating any steps to compress the step array again
[[nodiscard]] inline std::vector<RouteStep> removeNoTurnInstructions(std::vector<RouteStep> steps) OSRM_ATTR_WARN_UNUSED
inline std::vector<RouteStep> removeNoTurnInstructions(std::vector<RouteStep> steps)
{ {
// finally clean up the post-processed instructions. // finally clean up the post-processed instructions.
// Remove all invalid instructions from the set of instructions. // Remove all invalid instructions from the set of instructions.
+6 -5
View File
@@ -1,10 +1,11 @@
#ifndef OSRM_ENGINE_GUIDANCE_LANE_PROCESSING_HPP_ #ifndef OSRM_ENGINE_GUIDANCE_LANE_PROCESSING_HPP_
#define OSRM_ENGINE_GUIDANCE_LANE_PROCESSING_HPP_ #define OSRM_ENGINE_GUIDANCE_LANE_PROCESSING_HPP_
#include "engine/guidance/route_step.hpp"
#include <vector> #include <vector>
#include "engine/guidance/route_step.hpp"
#include "util/attributes.hpp"
namespace osrm::engine::guidance namespace osrm::engine::guidance
{ {
@@ -13,9 +14,9 @@ namespace osrm::engine::guidance
// we anticipate lane changes emitting only matching lanes early on. // we anticipate lane changes emitting only matching lanes early on.
// the second parameter describes the duration that we feel two segments need to be apart to count // the second parameter describes the duration that we feel two segments need to be apart to count
// as separate maneuvers. // as separate maneuvers.
[[nodiscard]] std::vector<RouteStep> OSRM_ATTR_WARN_UNUSED
anticipateLaneChange(std::vector<RouteStep> steps, std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
const double min_distance_needed_for_lane_change = 200); const double min_distance_needed_for_lane_change = 200);
} // namespace osrm::engine::guidance } // namespace osrm::engine::guidance
+12 -8
View File
@@ -5,6 +5,7 @@
#include "engine/guidance/leg_geometry.hpp" #include "engine/guidance/leg_geometry.hpp"
#include "engine/guidance/route_step.hpp" #include "engine/guidance/route_step.hpp"
#include "engine/phantom_node.hpp" #include "engine/phantom_node.hpp"
#include "util/attributes.hpp"
#include <vector> #include <vector>
@@ -12,7 +13,8 @@ namespace osrm::engine::guidance
{ {
// passed as none-reference to modify in-place and move out again // passed as none-reference to modify in-place and move out again
[[nodiscard]] std::vector<RouteStep> handleRoundabouts(std::vector<RouteStep> steps); OSRM_ATTR_WARN_UNUSED
std::vector<RouteStep> handleRoundabouts(std::vector<RouteStep> steps);
// trim initial/final segment of very short length. // trim initial/final segment of very short length.
// This function uses in/out parameter passing to modify both steps and geometry in place. // This function uses in/out parameter passing to modify both steps and geometry in place.
@@ -22,21 +24,23 @@ namespace osrm::engine::guidance
void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry); void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry);
// assign relative locations to depart/arrive instructions // assign relative locations to depart/arrive instructions
[[nodiscard]] std::vector<RouteStep> assignRelativeLocations(std::vector<RouteStep> steps, OSRM_ATTR_WARN_UNUSED
const LegGeometry &geometry, std::vector<RouteStep> assignRelativeLocations(std::vector<RouteStep> steps,
const PhantomNode &source_node, const LegGeometry &geometry,
const PhantomNode &target_node); const PhantomNode &source_node,
const PhantomNode &target_node);
// collapse suppressed instructions remaining into intersections array // collapse suppressed instructions remaining into intersections array
[[nodiscard]] std::vector<RouteStep> buildIntersections(std::vector<RouteStep> steps); OSRM_ATTR_WARN_UNUSED
std::vector<RouteStep> buildIntersections(std::vector<RouteStep> steps);
// postProcess will break the connection between the leg geometry // postProcess will break the connection between the leg geometry
// for which a segment is supposed to represent exactly the coordinates // for which a segment is supposed to represent exactly the coordinates
// between routing maneuvers and the route steps itself. // between routing maneuvers and the route steps itself.
// If required, we can get both in sync again using this function. // If required, we can get both in sync again using this function.
// Move in LegGeometry for modification in place. // Move in LegGeometry for modification in place.
[[nodiscard]] LegGeometry resyncGeometry(LegGeometry leg_geometry, OSRM_ATTR_WARN_UNUSED
const std::vector<RouteStep> &steps); LegGeometry resyncGeometry(LegGeometry leg_geometry, const std::vector<RouteStep> &steps);
/** /**
* Apply maneuver override relations to the selected route. * Apply maneuver override relations to the selected route.
@@ -2,6 +2,7 @@
#define OSRM_ENGINE_GUIDANCE_VERBOSITY_REDUCTION_HPP_ #define OSRM_ENGINE_GUIDANCE_VERBOSITY_REDUCTION_HPP_
#include "engine/guidance/route_step.hpp" #include "engine/guidance/route_step.hpp"
#include "util/attributes.hpp"
#include <vector> #include <vector>
@@ -12,7 +13,8 @@ namespace osrm::engine::guidance
// to announce them. All these that are not collapsed into a single turn (think segregated // to announce them. All these that are not collapsed into a single turn (think segregated
// intersection) have to be checked for the length they are active in. If they are active for a // intersection) have to be checked for the length they are active in. If they are active for a
// short distance only, we don't announce them // short distance only, we don't announce them
[[nodiscard]] std::vector<RouteStep> suppressShortNameSegments(std::vector<RouteStep> steps); OSRM_ATTR_WARN_UNUSED
std::vector<RouteStep> suppressShortNameSegments(std::vector<RouteStep> steps);
} // namespace osrm::engine::guidance } // namespace osrm::engine::guidance
@@ -6,7 +6,7 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <numbers> #include <boost/math/constants/constants.hpp>
namespace osrm::engine::map_matching namespace osrm::engine::map_matching
{ {
@@ -21,8 +21,10 @@ struct NormalDistribution
// FIXME implement log-probability version since it's faster // FIXME implement log-probability version since it's faster
double Density(const double val) const double Density(const double val) const
{ {
using namespace boost::math::constants;
const double x = val - mean; const double x = val - mean;
return 1.0 / (std::sqrt(2 * std::numbers::pi) * standard_deviation) * return 1.0 / (std::sqrt(two_pi<double>()) * standard_deviation) *
std::exp(-x * x / (standard_deviation * standard_deviation)); std::exp(-x * x / (standard_deviation * standard_deviation));
} }
@@ -4,7 +4,7 @@
#include "util/integer_range.hpp" #include "util/integer_range.hpp"
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <numbers> #include <boost/math/constants/constants.hpp>
#include <cmath> #include <cmath>
@@ -14,7 +14,7 @@
namespace osrm::engine::map_matching namespace osrm::engine::map_matching
{ {
static const double log_2_pi = std::log(2. * std::numbers::pi); static const double log_2_pi = std::log(2. * boost::math::constants::pi<double>());
static const double IMPOSSIBLE_LOG_PROB = -std::numeric_limits<double>::infinity(); static const double IMPOSSIBLE_LOG_PROB = -std::numeric_limits<double>::infinity();
static const double MINIMAL_LOG_PROB = std::numeric_limits<double>::lowest(); static const double MINIMAL_LOG_PROB = std::numeric_limits<double>::lowest();
static const std::size_t INVALID_STATE = std::numeric_limits<std::size_t>::max(); static const std::size_t INVALID_STATE = std::numeric_limits<std::size_t>::max();
@@ -2,7 +2,7 @@
#define ENGINE_MAP_MATCHING_CONFIDENCE_HPP #define ENGINE_MAP_MATCHING_CONFIDENCE_HPP
#include "engine/map_matching/bayes_classifier.hpp" #include "engine/map_matching/bayes_classifier.hpp"
#include <boost/assert.hpp>
#include <cmath> #include <cmath>
namespace osrm::engine::map_matching namespace osrm::engine::map_matching
+1 -1
View File
@@ -95,7 +95,7 @@ class BasePlugin
const std::string &message, const std::string &message,
osrm::engine::api::ResultT &result) const osrm::engine::api::ResultT &result) const
{ {
std::visit(ErrorRenderer(code, message), result); mapbox::util::apply_visitor(ErrorRenderer(code, message), result);
return Status::Error; return Status::Error;
} }
@@ -11,7 +11,6 @@
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <algorithm> #include <algorithm>
#include <boost/core/ignore_unused.hpp>
#include <iterator> #include <iterator>
#include <limits> #include <limits>
#include <tuple> #include <tuple>
@@ -270,29 +269,10 @@ retrievePackedPathFromHeap(const SearchEngineData<Algorithm>::QueryHeap &forward
return packed_path; return packed_path;
} }
template <typename Heap> template <bool DIRECTION, typename Algorithm, typename... Args>
void insertOrUpdate(Heap &heap,
const NodeID node,
const EdgeWeight weight,
const typename Heap::DataType &data)
{
const auto heapNode = heap.GetHeapNodeIfWasInserted(node);
if (!heapNode)
{
heap.Insert(node, weight, data);
}
else if (weight < heapNode->weight)
{
heapNode->data = data;
heapNode->weight = weight;
heap.DecreaseKey(*heapNode);
}
}
template <bool DIRECTION, typename Algorithm, typename Heap, typename... Args>
void relaxOutgoingEdges(const DataFacade<Algorithm> &facade, void relaxOutgoingEdges(const DataFacade<Algorithm> &facade,
Heap &forward_heap, typename SearchEngineData<Algorithm>::QueryHeap &forward_heap,
const typename Heap::HeapNode &heapNode, const typename SearchEngineData<Algorithm>::QueryHeap::HeapNode &heapNode,
const Args &...args) const Args &...args)
{ {
const auto &partition = facade.GetMultiLevelPartition(); const auto &partition = facade.GetMultiLevelPartition();
@@ -301,31 +281,14 @@ void relaxOutgoingEdges(const DataFacade<Algorithm> &facade,
const auto level = getNodeQueryLevel(partition, heapNode.node, args...); const auto level = getNodeQueryLevel(partition, heapNode.node, args...);
static constexpr auto IS_MAP_MATCHING =
std::is_same_v<typename SearchEngineData<mld::Algorithm>::MapMatchingQueryHeap, Heap>;
if (level >= 1 && !heapNode.data.from_clique_arc) if (level >= 1 && !heapNode.data.from_clique_arc)
{ {
if constexpr (DIRECTION == FORWARD_DIRECTION) if (DIRECTION == FORWARD_DIRECTION)
{ {
// Shortcuts in forward direction // Shortcuts in forward direction
const auto &cell = const auto &cell =
cells.GetCell(metric, level, partition.GetCell(level, heapNode.node)); cells.GetCell(metric, level, partition.GetCell(level, heapNode.node));
auto destination = cell.GetDestinationNodes().begin(); auto destination = cell.GetDestinationNodes().begin();
auto distance = [&cell, node = heapNode.node ]() -> auto
{
if constexpr (IS_MAP_MATCHING)
{
return cell.GetOutDistance(node).begin();
}
else
{
boost::ignore_unused(cell, node);
return 0;
}
}
();
for (auto shortcut_weight : cell.GetOutWeight(heapNode.node)) for (auto shortcut_weight : cell.GetOutWeight(heapNode.node))
{ {
BOOST_ASSERT(destination != cell.GetDestinationNodes().end()); BOOST_ASSERT(destination != cell.GetDestinationNodes().end());
@@ -335,23 +298,19 @@ void relaxOutgoingEdges(const DataFacade<Algorithm> &facade,
{ {
const EdgeWeight to_weight = heapNode.weight + shortcut_weight; const EdgeWeight to_weight = heapNode.weight + shortcut_weight;
BOOST_ASSERT(to_weight >= heapNode.weight); BOOST_ASSERT(to_weight >= heapNode.weight);
const auto toHeapNode = forward_heap.GetHeapNodeIfWasInserted(to);
if constexpr (IS_MAP_MATCHING) if (!toHeapNode)
{ {
const EdgeDistance to_distance = heapNode.data.distance + *distance; forward_heap.Insert(to, to_weight, {heapNode.node, true});
insertOrUpdate(
forward_heap, to, to_weight, {heapNode.node, true, to_distance});
} }
else else if (to_weight < toHeapNode->weight)
{ {
insertOrUpdate(forward_heap, to, to_weight, {heapNode.node, true}); toHeapNode->data = {heapNode.node, true};
toHeapNode->weight = to_weight;
forward_heap.DecreaseKey(*toHeapNode);
} }
} }
++destination; ++destination;
if constexpr (IS_MAP_MATCHING)
{
++distance;
}
} }
} }
else else
@@ -360,20 +319,6 @@ void relaxOutgoingEdges(const DataFacade<Algorithm> &facade,
const auto &cell = const auto &cell =
cells.GetCell(metric, level, partition.GetCell(level, heapNode.node)); cells.GetCell(metric, level, partition.GetCell(level, heapNode.node));
auto source = cell.GetSourceNodes().begin(); auto source = cell.GetSourceNodes().begin();
auto distance = [&cell, node = heapNode.node ]() -> auto
{
if constexpr (IS_MAP_MATCHING)
{
return cell.GetInDistance(node).begin();
}
else
{
boost::ignore_unused(cell, node);
return 0;
}
}
();
for (auto shortcut_weight : cell.GetInWeight(heapNode.node)) for (auto shortcut_weight : cell.GetInWeight(heapNode.node))
{ {
BOOST_ASSERT(source != cell.GetSourceNodes().end()); BOOST_ASSERT(source != cell.GetSourceNodes().end());
@@ -383,22 +328,19 @@ void relaxOutgoingEdges(const DataFacade<Algorithm> &facade,
{ {
const EdgeWeight to_weight = heapNode.weight + shortcut_weight; const EdgeWeight to_weight = heapNode.weight + shortcut_weight;
BOOST_ASSERT(to_weight >= heapNode.weight); BOOST_ASSERT(to_weight >= heapNode.weight);
if constexpr (IS_MAP_MATCHING) const auto toHeapNode = forward_heap.GetHeapNodeIfWasInserted(to);
if (!toHeapNode)
{ {
const EdgeDistance to_distance = heapNode.data.distance + *distance; forward_heap.Insert(to, to_weight, {heapNode.node, true});
insertOrUpdate(
forward_heap, to, to_weight, {heapNode.node, true, to_distance});
} }
else else if (to_weight < toHeapNode->weight)
{ {
insertOrUpdate(forward_heap, to, to_weight, {heapNode.node, true}); toHeapNode->data = {heapNode.node, true};
toHeapNode->weight = to_weight;
forward_heap.DecreaseKey(*toHeapNode);
} }
} }
++source; ++source;
if constexpr (IS_MAP_MATCHING)
{
++distance;
}
} }
} }
} }
@@ -425,28 +367,26 @@ void relaxOutgoingEdges(const DataFacade<Algorithm> &facade,
const EdgeWeight to_weight = const EdgeWeight to_weight =
heapNode.weight + node_weight + alias_cast<EdgeWeight>(turn_penalty); heapNode.weight + node_weight + alias_cast<EdgeWeight>(turn_penalty);
if constexpr (IS_MAP_MATCHING) const auto toHeapNode = forward_heap.GetHeapNodeIfWasInserted(to);
if (!toHeapNode)
{ {
const auto node_distance = forward_heap.Insert(to, to_weight, {heapNode.node, false});
facade.GetNodeDistance(DIRECTION == FORWARD_DIRECTION ? heapNode.node : to);
const EdgeDistance to_distance = heapNode.data.distance + node_distance;
insertOrUpdate(
forward_heap, to, to_weight, {heapNode.node, false, to_distance});
} }
else else if (to_weight < toHeapNode->weight)
{ {
insertOrUpdate(forward_heap, to, to_weight, {heapNode.node, false}); toHeapNode->data = {heapNode.node, false};
toHeapNode->weight = to_weight;
forward_heap.DecreaseKey(*toHeapNode);
} }
} }
} }
} }
} }
template <bool DIRECTION, typename Algorithm, typename Heap, typename... Args> template <bool DIRECTION, typename Algorithm, typename... Args>
void routingStep(const DataFacade<Algorithm> &facade, void routingStep(const DataFacade<Algorithm> &facade,
Heap &forward_heap, typename SearchEngineData<Algorithm>::QueryHeap &forward_heap,
Heap &reverse_heap, typename SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
NodeID &middle_node, NodeID &middle_node,
EdgeWeight &path_upper_bound, EdgeWeight &path_upper_bound,
const std::vector<NodeID> &force_step_nodes, const std::vector<NodeID> &force_step_nodes,
@@ -489,19 +429,22 @@ using UnpackedNodes = std::vector<NodeID>;
using UnpackedEdges = std::vector<EdgeID>; using UnpackedEdges = std::vector<EdgeID>;
using UnpackedPath = std::tuple<EdgeWeight, UnpackedNodes, UnpackedEdges>; using UnpackedPath = std::tuple<EdgeWeight, UnpackedNodes, UnpackedEdges>;
template <typename Algorithm, typename Heap, typename... Args> template <typename Algorithm, typename... Args>
std::optional<std::pair<NodeID, EdgeWeight>> runSearch(const DataFacade<Algorithm> &facade, UnpackedPath search(SearchEngineData<Algorithm> &engine_working_data,
Heap &forward_heap, const DataFacade<Algorithm> &facade,
Heap &reverse_heap, typename SearchEngineData<Algorithm>::QueryHeap &forward_heap,
const std::vector<NodeID> &force_step_nodes, typename SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
EdgeWeight weight_upper_bound, const std::vector<NodeID> &force_step_nodes,
const Args &...args) EdgeWeight weight_upper_bound,
const Args &...args)
{ {
if (forward_heap.Empty() || reverse_heap.Empty()) if (forward_heap.Empty() || reverse_heap.Empty())
{ {
return {}; return std::make_tuple(INVALID_EDGE_WEIGHT, std::vector<NodeID>(), std::vector<EdgeID>());
} }
const auto &partition = facade.GetMultiLevelPartition();
BOOST_ASSERT(!forward_heap.Empty() && forward_heap.MinKey() < INVALID_EDGE_WEIGHT); BOOST_ASSERT(!forward_heap.Empty() && forward_heap.MinKey() < INVALID_EDGE_WEIGHT);
BOOST_ASSERT(!reverse_heap.Empty() && reverse_heap.MinKey() < INVALID_EDGE_WEIGHT); BOOST_ASSERT(!reverse_heap.Empty() && reverse_heap.MinKey() < INVALID_EDGE_WEIGHT);
@@ -531,33 +474,10 @@ std::optional<std::pair<NodeID, EdgeWeight>> runSearch(const DataFacade<Algorith
// No path found for both target nodes? // No path found for both target nodes?
if (weight >= weight_upper_bound || SPECIAL_NODEID == middle) if (weight >= weight_upper_bound || SPECIAL_NODEID == middle)
{
return {};
}
return {{middle, weight}};
}
template <typename Algorithm, typename... Args>
UnpackedPath search(SearchEngineData<Algorithm> &engine_working_data,
const DataFacade<Algorithm> &facade,
typename SearchEngineData<Algorithm>::QueryHeap &forward_heap,
typename SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
const std::vector<NodeID> &force_step_nodes,
EdgeWeight weight_upper_bound,
const Args &...args)
{
auto searchResult = runSearch(
facade, forward_heap, reverse_heap, force_step_nodes, weight_upper_bound, args...);
if (!searchResult)
{ {
return std::make_tuple(INVALID_EDGE_WEIGHT, std::vector<NodeID>(), std::vector<EdgeID>()); return std::make_tuple(INVALID_EDGE_WEIGHT, std::vector<NodeID>(), std::vector<EdgeID>());
} }
auto [middle, weight] = *searchResult;
const auto &partition = facade.GetMultiLevelPartition();
// Get packed path as edges {from node ID, to node ID, from_clique_arc} // Get packed path as edges {from node ID, to node ID, from_clique_arc}
auto packed_path = retrievePackedPathFromHeap(forward_heap, reverse_heap, middle); auto packed_path = retrievePackedPathFromHeap(forward_heap, reverse_heap, middle);
@@ -616,31 +536,6 @@ UnpackedPath search(SearchEngineData<Algorithm> &engine_working_data,
return std::make_tuple(weight, std::move(unpacked_nodes), std::move(unpacked_edges)); return std::make_tuple(weight, std::move(unpacked_nodes), std::move(unpacked_edges));
} }
template <typename Algorithm, typename... Args>
EdgeDistance
searchDistance(SearchEngineData<Algorithm> &,
const DataFacade<Algorithm> &facade,
typename SearchEngineData<Algorithm>::MapMatchingQueryHeap &forward_heap,
typename SearchEngineData<Algorithm>::MapMatchingQueryHeap &reverse_heap,
const std::vector<NodeID> &force_step_nodes,
EdgeWeight weight_upper_bound,
const Args &...args)
{
auto searchResult = runSearch(
facade, forward_heap, reverse_heap, force_step_nodes, weight_upper_bound, args...);
if (!searchResult)
{
return INVALID_EDGE_DISTANCE;
}
auto [middle, _] = *searchResult;
auto distance = forward_heap.GetData(middle).distance + reverse_heap.GetData(middle).distance;
return distance;
}
// Alias to be compatible with the CH-based search // Alias to be compatible with the CH-based search
template <typename Algorithm, typename PhantomEndpointT> template <typename Algorithm, typename PhantomEndpointT>
inline void search(SearchEngineData<Algorithm> &engine_working_data, inline void search(SearchEngineData<Algorithm> &engine_working_data,
@@ -698,8 +593,8 @@ void unpackPath(const FacadeT &facade,
template <typename Algorithm> template <typename Algorithm>
double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data, double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
const DataFacade<Algorithm> &facade, const DataFacade<Algorithm> &facade,
typename SearchEngineData<Algorithm>::MapMatchingQueryHeap &forward_heap, typename SearchEngineData<Algorithm>::QueryHeap &forward_heap,
typename SearchEngineData<Algorithm>::MapMatchingQueryHeap &reverse_heap, typename SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
const PhantomNode &source_phantom, const PhantomNode &source_phantom,
const PhantomNode &target_phantom, const PhantomNode &target_phantom,
EdgeWeight weight_upper_bound = INVALID_EDGE_WEIGHT) EdgeWeight weight_upper_bound = INVALID_EDGE_WEIGHT)
@@ -707,49 +602,48 @@ double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
forward_heap.Clear(); forward_heap.Clear();
reverse_heap.Clear(); reverse_heap.Clear();
if (source_phantom.IsValidForwardSource())
{
forward_heap.Insert(source_phantom.forward_segment_id.id,
EdgeWeight{0} - source_phantom.GetForwardWeightPlusOffset(),
{source_phantom.forward_segment_id.id,
false,
EdgeDistance{0} - source_phantom.GetForwardDistance()});
}
if (source_phantom.IsValidReverseSource())
{
forward_heap.Insert(source_phantom.reverse_segment_id.id,
EdgeWeight{0} - source_phantom.GetReverseWeightPlusOffset(),
{source_phantom.reverse_segment_id.id,
false,
EdgeDistance{0} - source_phantom.GetReverseDistance()});
}
if (target_phantom.IsValidForwardTarget())
{
reverse_heap.Insert(
target_phantom.forward_segment_id.id,
target_phantom.GetForwardWeightPlusOffset(),
{target_phantom.forward_segment_id.id, false, target_phantom.GetForwardDistance()});
}
if (target_phantom.IsValidReverseTarget())
{
reverse_heap.Insert(
target_phantom.reverse_segment_id.id,
target_phantom.GetReverseWeightPlusOffset(),
{target_phantom.reverse_segment_id.id, false, target_phantom.GetReverseDistance()});
}
const PhantomEndpoints endpoints{source_phantom, target_phantom}; const PhantomEndpoints endpoints{source_phantom, target_phantom};
insertNodesInHeaps(forward_heap, reverse_heap, endpoints);
auto distance = searchDistance( auto [weight, unpacked_nodes, unpacked_edges] = search(
engine_working_data, facade, forward_heap, reverse_heap, {}, weight_upper_bound, endpoints); engine_working_data, facade, forward_heap, reverse_heap, {}, weight_upper_bound, endpoints);
if (distance == INVALID_EDGE_DISTANCE) if (weight == INVALID_EDGE_WEIGHT)
{ {
return std::numeric_limits<double>::max(); return std::numeric_limits<double>::max();
} }
BOOST_ASSERT(unpacked_nodes.size() >= 1);
EdgeDistance distance = {0.0};
if (source_phantom.forward_segment_id.id == unpacked_nodes.front())
{
BOOST_ASSERT(source_phantom.forward_segment_id.enabled);
distance = EdgeDistance{0} - source_phantom.GetForwardDistance();
}
else if (source_phantom.reverse_segment_id.id == unpacked_nodes.front())
{
BOOST_ASSERT(source_phantom.reverse_segment_id.enabled);
distance = EdgeDistance{0} - source_phantom.GetReverseDistance();
}
for (size_t index = 0; index < unpacked_nodes.size() - 1; ++index)
{
distance += facade.GetNodeDistance(unpacked_nodes[index]);
}
if (target_phantom.forward_segment_id.id == unpacked_nodes.back())
{
BOOST_ASSERT(target_phantom.forward_segment_id.enabled);
distance += target_phantom.GetForwardDistance();
}
else if (target_phantom.reverse_segment_id.id == unpacked_nodes.back())
{
BOOST_ASSERT(target_phantom.reverse_segment_id.enabled);
distance += target_phantom.GetReverseDistance();
}
return from_alias<double>(distance); return from_alias<double>(distance);
} }
+1 -29
View File
@@ -12,6 +12,7 @@ namespace osrm::engine
// Algorithm-dependent heaps // Algorithm-dependent heaps
// - CH algorithms use CH heaps // - CH algorithms use CH heaps
// - CoreCH algorithms use CH
// - MLD algorithms use MLD heaps // - MLD algorithms use MLD heaps
template <typename Algorithm> struct SearchEngineData template <typename Algorithm> struct SearchEngineData
@@ -46,7 +47,6 @@ template <> struct SearchEngineData<routing_algorithms::ch::Algorithm>
util::UnorderedMapStorage<NodeID, int>>; util::UnorderedMapStorage<NodeID, int>>;
using SearchEngineHeapPtr = boost::thread_specific_ptr<QueryHeap>; using SearchEngineHeapPtr = boost::thread_specific_ptr<QueryHeap>;
using ManyToManyHeapPtr = boost::thread_specific_ptr<ManyToManyQueryHeap>; using ManyToManyHeapPtr = boost::thread_specific_ptr<ManyToManyQueryHeap>;
static SearchEngineHeapPtr forward_heap_1; static SearchEngineHeapPtr forward_heap_1;
@@ -56,10 +56,6 @@ template <> struct SearchEngineData<routing_algorithms::ch::Algorithm>
static SearchEngineHeapPtr forward_heap_3; static SearchEngineHeapPtr forward_heap_3;
static SearchEngineHeapPtr reverse_heap_3; static SearchEngineHeapPtr reverse_heap_3;
static ManyToManyHeapPtr many_to_many_heap; static ManyToManyHeapPtr many_to_many_heap;
static SearchEngineHeapPtr map_matching_forward_heap_1;
static SearchEngineHeapPtr map_matching_reverse_heap_1;
void InitializeOrClearMapMatchingThreadLocalStorage(unsigned number_of_nodes);
void InitializeOrClearFirstThreadLocalStorage(unsigned number_of_nodes); void InitializeOrClearFirstThreadLocalStorage(unsigned number_of_nodes);
@@ -78,19 +74,6 @@ struct MultiLayerDijkstraHeapData
MultiLayerDijkstraHeapData(NodeID p, bool from) : parent(p), from_clique_arc(from) {} MultiLayerDijkstraHeapData(NodeID p, bool from) : parent(p), from_clique_arc(from) {}
}; };
struct MapMatchingMultiLayerDijkstraHeapData
{
NodeID parent;
bool from_clique_arc;
EdgeDistance distance = {0};
MapMatchingMultiLayerDijkstraHeapData(NodeID p) : parent(p), from_clique_arc(false) {}
MapMatchingMultiLayerDijkstraHeapData(NodeID p, bool from) : parent(p), from_clique_arc(from) {}
MapMatchingMultiLayerDijkstraHeapData(NodeID p, bool from, EdgeDistance d)
: parent(p), from_clique_arc(from), distance(d)
{
}
};
struct ManyToManyMultiLayerDijkstraHeapData : MultiLayerDijkstraHeapData struct ManyToManyMultiLayerDijkstraHeapData : MultiLayerDijkstraHeapData
{ {
EdgeDuration duration; EdgeDuration duration;
@@ -121,27 +104,16 @@ template <> struct SearchEngineData<routing_algorithms::mld::Algorithm>
EdgeWeight, EdgeWeight,
ManyToManyMultiLayerDijkstraHeapData, ManyToManyMultiLayerDijkstraHeapData,
util::TwoLevelStorage<NodeID, int>>; util::TwoLevelStorage<NodeID, int>>;
using MapMatchingQueryHeap = util::QueryHeap<NodeID,
NodeID,
EdgeWeight,
MapMatchingMultiLayerDijkstraHeapData,
util::TwoLevelStorage<NodeID, int>>;
using SearchEngineHeapPtr = boost::thread_specific_ptr<QueryHeap>; using SearchEngineHeapPtr = boost::thread_specific_ptr<QueryHeap>;
using ManyToManyHeapPtr = boost::thread_specific_ptr<ManyToManyQueryHeap>; using ManyToManyHeapPtr = boost::thread_specific_ptr<ManyToManyQueryHeap>;
using MapMatchingHeapPtr = boost::thread_specific_ptr<MapMatchingQueryHeap>;
static SearchEngineHeapPtr forward_heap_1; static SearchEngineHeapPtr forward_heap_1;
static SearchEngineHeapPtr reverse_heap_1; static SearchEngineHeapPtr reverse_heap_1;
static MapMatchingHeapPtr map_matching_forward_heap_1;
static MapMatchingHeapPtr map_matching_reverse_heap_1;
static ManyToManyHeapPtr many_to_many_heap; static ManyToManyHeapPtr many_to_many_heap;
void InitializeOrClearFirstThreadLocalStorage(unsigned number_of_nodes, void InitializeOrClearFirstThreadLocalStorage(unsigned number_of_nodes,
unsigned number_of_boundary_nodes); unsigned number_of_boundary_nodes);
void InitializeOrClearMapMatchingThreadLocalStorage(unsigned number_of_nodes,
unsigned number_of_boundary_nodes);
void InitializeOrClearManyToManyThreadLocalStorage(unsigned number_of_nodes, void InitializeOrClearManyToManyThreadLocalStorage(unsigned number_of_nodes,
unsigned number_of_boundary_nodes); unsigned number_of_boundary_nodes);
+22 -1
View File
@@ -3,9 +3,11 @@
#include "extractor/class_data.hpp" #include "extractor/class_data.hpp"
#include "extractor/turn_lane_types.hpp" #include "extractor/turn_lane_types.hpp"
#include "util/std_hash.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include <boost/functional/hash.hpp>
#include <boost/optional/optional_fwd.hpp>
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
@@ -16,6 +18,25 @@ class Way;
class Relation; class Relation;
} // namespace osmium } // namespace osmium
namespace std
{
template <> struct hash<std::tuple<std::string, std::string, std::string, std::string, std::string>>
{
std::size_t operator()(
const std::tuple<std::string, std::string, std::string, std::string, std::string> &mk)
const noexcept
{
std::size_t seed = 0;
boost::hash_combine(seed, std::get<0>(mk));
boost::hash_combine(seed, std::get<1>(mk));
boost::hash_combine(seed, std::get<2>(mk));
boost::hash_combine(seed, std::get<3>(mk));
boost::hash_combine(seed, std::get<4>(mk));
return seed;
}
};
} // namespace std
namespace osrm::extractor namespace osrm::extractor
{ {
@@ -7,8 +7,8 @@
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <mapbox/variant.hpp>
#include <utility> #include <utility>
#include <variant>
namespace osrm::extractor namespace osrm::extractor
{ {
@@ -1,15 +1,16 @@
#ifndef OSRM_EXTRACTOR_INTERSECTION_COORDINATE_EXTRACTOR_HPP_ #ifndef OSRM_EXTRACTOR_INTERSECTION_COORDINATE_EXTRACTOR_HPP_
#define OSRM_EXTRACTOR_INTERSECTION_COORDINATE_EXTRACTOR_HPP_ #define OSRM_EXTRACTOR_INTERSECTION_COORDINATE_EXTRACTOR_HPP_
#include <utility>
#include <vector>
#include "extractor/compressed_edge_container.hpp" #include "extractor/compressed_edge_container.hpp"
#include "extractor/query_node.hpp" #include "extractor/query_node.hpp"
#include "util/attributes.hpp"
#include "util/coordinate.hpp" #include "util/coordinate.hpp"
#include "util/node_based_graph.hpp" #include "util/node_based_graph.hpp"
#include <utility>
#include <vector>
namespace osrm::extractor::intersection namespace osrm::extractor::intersection
{ {
@@ -26,16 +27,17 @@ class CoordinateExtractor
* Note: The segment between intersection and turn coordinate can be zero, if the OSM modelling * Note: The segment between intersection and turn coordinate can be zero, if the OSM modelling
* is unfortunate. See https://github.com/Project-OSRM/osrm-backend/issues/3470 * is unfortunate. See https://github.com/Project-OSRM/osrm-backend/issues/3470
*/ */
[[nodiscard]] util::Coordinate OSRM_ATTR_WARN_UNUSED
GetCoordinateAlongRoad(const NodeID intersection_node, util::Coordinate GetCoordinateAlongRoad(const NodeID intersection_node,
const EdgeID turn_edge, const EdgeID turn_edge,
const bool traversed_in_reverse, const bool traversed_in_reverse,
const NodeID to_node, const NodeID to_node,
const std::uint8_t number_of_in_lanes) const; const std::uint8_t number_of_in_lanes) const;
// Given a set of precomputed coordinates, select the representative coordinate along the road // Given a set of precomputed coordinates, select the representative coordinate along the road
// that best describes the turn // that best describes the turn
[[nodiscard]] util::Coordinate OSRM_ATTR_WARN_UNUSED
util::Coordinate
ExtractRepresentativeCoordinate(const NodeID intersection_node, ExtractRepresentativeCoordinate(const NodeID intersection_node,
const EdgeID turn_edge, const EdgeID turn_edge,
const bool traversed_in_reverse, const bool traversed_in_reverse,
@@ -45,7 +47,7 @@ class CoordinateExtractor
// instead of finding only a single coordinate, we can also list all coordinates along a // instead of finding only a single coordinate, we can also list all coordinates along a
// road. // road.
[[nodiscard]] std::vector<util::Coordinate> OSRM_ATTR_WARN_UNUSED std::vector<util::Coordinate>
GetCoordinatesAlongRoad(const NodeID intersection_node, GetCoordinatesAlongRoad(const NodeID intersection_node,
const EdgeID turn_edge, const EdgeID turn_edge,
const bool traversed_in_reverse, const bool traversed_in_reverse,
@@ -53,18 +55,20 @@ class CoordinateExtractor
// wrapper in case of normal forward edges (traversed_in_reverse = false, to_node = // wrapper in case of normal forward edges (traversed_in_reverse = false, to_node =
// node_based_graph.GetTarget(turn_edge) // node_based_graph.GetTarget(turn_edge)
[[nodiscard]] std::vector<util::Coordinate> OSRM_ATTR_WARN_UNUSED
GetForwardCoordinatesAlongRoad(const NodeID from, const EdgeID turn_edge) const; std::vector<util::Coordinate> GetForwardCoordinatesAlongRoad(const NodeID from,
const EdgeID turn_edge) const;
// a less precise way to compute coordinates along a route. Due to the heavy interaction of // a less precise way to compute coordinates along a route. Due to the heavy interaction of
// graph traversal and turn instructions, we often don't care for high precision. We only want // graph traversal and turn instructions, we often don't care for high precision. We only want
// to check for available connections in order, or find (with room for error) the straightmost // to check for available connections in order, or find (with room for error) the straightmost
// turn. This function will offer a bit more error potential but allow for much higher // turn. This function will offer a bit more error potential but allow for much higher
// performance // performance
[[nodiscard]] util::Coordinate GetCoordinateCloseToTurn(const NodeID from_node, OSRM_ATTR_WARN_UNUSED
const EdgeID turn_edge, util::Coordinate GetCoordinateCloseToTurn(const NodeID from_node,
const bool traversed_in_reverse, const EdgeID turn_edge,
const NodeID to_node) const; const bool traversed_in_reverse,
const NodeID to_node) const;
/* When extracting the coordinates, we first extract all coordinates. We don't care about most /* When extracting the coordinates, we first extract all coordinates. We don't care about most
* of them, though. * of them, though.
@@ -86,19 +90,22 @@ class CoordinateExtractor
* The optional length cache needs to store the accumulated distance up to the respective * The optional length cache needs to store the accumulated distance up to the respective
* coordinate index [0,d(0,1),...] * coordinate index [0,d(0,1),...]
*/ */
[[nodiscard]] std::vector<util::Coordinate> OSRM_ATTR_WARN_UNUSED
std::vector<util::Coordinate>
TrimCoordinatesToLength(std::vector<util::Coordinate> coordinates, TrimCoordinatesToLength(std::vector<util::Coordinate> coordinates,
const double desired_length, const double desired_length,
const std::vector<double> &length_cache = {}) const; const std::vector<double> &length_cache = {}) const;
[[nodiscard]] std::vector<double> OSRM_ATTR_WARN_UNUSED
PrepareLengthCache(const std::vector<util::Coordinate> &coordinates, const double limit) const; std::vector<double> PrepareLengthCache(const std::vector<util::Coordinate> &coordinates,
const double limit) const;
/* when looking at a set of coordinates, this function allows trimming the vector to a smaller, /* when looking at a set of coordinates, this function allows trimming the vector to a smaller,
* only containing coordinates up to a given distance along the path. The last coordinate might * only containing coordinates up to a given distance along the path. The last coordinate might
* be interpolated * be interpolated
*/ */
[[nodiscard]] std::vector<util::Coordinate> OSRM_ATTR_WARN_UNUSED
std::vector<util::Coordinate>
TrimCoordinatesByLengthFront(std::vector<util::Coordinate> coordinates, TrimCoordinatesByLengthFront(std::vector<util::Coordinate> coordinates,
const double desired_length) const; const double desired_length) const;
@@ -123,9 +130,10 @@ class CoordinateExtractor
* *
* for fixpoint `b`, vector_base `d` and vector_head `e` * for fixpoint `b`, vector_base `d` and vector_head `e`
*/ */
[[nodiscard]] util::Coordinate GetCorrectedCoordinate(const util::Coordinate fixpoint, OSRM_ATTR_WARN_UNUSED
const util::Coordinate vector_base, util::Coordinate GetCorrectedCoordinate(const util::Coordinate fixpoint,
const util::Coordinate vector_head) const; const util::Coordinate vector_base,
const util::Coordinate vector_head) const;
/* generate a uniform vector of coordinates in same range distances /* generate a uniform vector of coordinates in same range distances
* *
@@ -135,7 +143,8 @@ class CoordinateExtractor
* Into: * Into:
* x -- x -- x -- x -- x - x * x -- x -- x -- x -- x - x
*/ */
[[nodiscard]] std::vector<util::Coordinate> OSRM_ATTR_WARN_UNUSED
std::vector<util::Coordinate>
SampleCoordinates(const std::vector<util::Coordinate> &coordinates, SampleCoordinates(const std::vector<util::Coordinate> &coordinates,
const double length, const double length,
const double rate) const; const double rate) const;
+6 -7
View File
@@ -8,12 +8,10 @@
#include "turn_path.hpp" #include "turn_path.hpp"
#include "util/integer_range.hpp" #include "util/integer_range.hpp"
#include "util/log.hpp" #include "util/log.hpp"
#include "util/std_hash.hpp"
#include "util/vector_view.hpp" #include "util/vector_view.hpp"
#include <variant>
#include <algorithm> #include <algorithm>
#include <boost/functional/hash.hpp>
#include <mapbox/variant.hpp>
namespace osrm::extractor namespace osrm::extractor
{ {
@@ -149,6 +147,7 @@ struct UnresolvedManeuverOverride
namespace std namespace std
{ {
template <> struct hash<osrm::extractor::NodeBasedTurn> template <> struct hash<osrm::extractor::NodeBasedTurn>
{ {
using argument_type = osrm::extractor::NodeBasedTurn; using argument_type = osrm::extractor::NodeBasedTurn;
using result_type = std::size_t; using result_type = std::size_t;
@@ -156,9 +155,9 @@ template <> struct hash<osrm::extractor::NodeBasedTurn>
{ {
std::size_t seed = 0; std::size_t seed = 0;
hash_combine(seed, s.from); boost::hash_combine(seed, s.from);
hash_combine(seed, s.via); boost::hash_combine(seed, s.via);
hash_combine(seed, s.to); boost::hash_combine(seed, s.to);
return seed; return seed;
} }
+3 -1
View File
@@ -1,10 +1,12 @@
#ifndef RESTRICTION_HPP #ifndef RESTRICTION_HPP
#define RESTRICTION_HPP #define RESTRICTION_HPP
#include "turn_path.hpp"
#include "util/coordinate.hpp" #include "util/coordinate.hpp"
#include "util/opening_hours.hpp" #include "util/opening_hours.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include "mapbox/variant.hpp"
#include "turn_path.hpp"
#include <limits> #include <limits>
namespace osrm::extractor namespace osrm::extractor
+1
View File
@@ -215,6 +215,7 @@ inline void read(storage::tar::FileReader &reader,
const std::string &name, const std::string &name,
detail::NameTableImpl<Ownership> &name_table) detail::NameTableImpl<Ownership> &name_table)
{ {
std::string buffer;
util::serialization::read(reader, name, name_table.indexed_data); util::serialization::read(reader, name, name_table.indexed_data);
} }
} // namespace osrm::extractor::serialization } // namespace osrm::extractor::serialization
+6 -6
View File
@@ -1,11 +1,10 @@
#ifndef OSRM_EXTRACTOR_TRAFFIC_SIGNALS_HPP #ifndef OSRM_EXTRACTOR_TRAFFIC_SIGNALS_HPP
#define OSRM_EXTRACTOR_TRAFFIC_SIGNALS_HPP #define OSRM_EXTRACTOR_TRAFFIC_SIGNALS_HPP
#include "util/std_hash.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include <boost/functional/hash.hpp>
#include <unordered_set> #include <unordered_set>
#include <utility>
namespace osrm::extractor namespace osrm::extractor
{ {
@@ -13,22 +12,23 @@ namespace osrm::extractor
struct TrafficSignals struct TrafficSignals
{ {
std::unordered_set<NodeID> bidirectional_nodes; std::unordered_set<NodeID> bidirectional_nodes;
std::unordered_set<std::pair<NodeID, NodeID>> unidirectional_segments; std::unordered_set<std::pair<NodeID, NodeID>, boost::hash<std::pair<NodeID, NodeID>>>
unidirectional_segments;
inline bool HasSignal(NodeID from, NodeID to) const inline bool HasSignal(NodeID from, NodeID to) const
{ {
return bidirectional_nodes.contains(to) || unidirectional_segments.contains({from, to}); return bidirectional_nodes.count(to) > 0 || unidirectional_segments.count({from, to}) > 0;
} }
void Compress(NodeID from, NodeID via, NodeID to) void Compress(NodeID from, NodeID via, NodeID to)
{ {
bidirectional_nodes.erase(via); bidirectional_nodes.erase(via);
if (unidirectional_segments.contains({via, to})) if (unidirectional_segments.count({via, to}))
{ {
unidirectional_segments.erase({via, to}); unidirectional_segments.erase({via, to});
unidirectional_segments.insert({from, to}); unidirectional_segments.insert({from, to});
} }
if (unidirectional_segments.contains({via, from})) if (unidirectional_segments.count({via, from}))
{ {
unidirectional_segments.erase({via, from}); unidirectional_segments.erase({via, from});
unidirectional_segments.insert({to, from}); unidirectional_segments.insert({to, from});
+15 -2
View File
@@ -3,9 +3,10 @@
#include "util/concurrent_id_map.hpp" #include "util/concurrent_id_map.hpp"
#include "util/integer_range.hpp" #include "util/integer_range.hpp"
#include "util/std_hash.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include <boost/functional/hash.hpp>
#include <bitset> #include <bitset>
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
@@ -53,7 +54,19 @@ const constexpr Mask merge_to_right = 1u << 10u;
using TurnLaneDescription = std::vector<TurnLaneType::Mask>; using TurnLaneDescription = std::vector<TurnLaneType::Mask>;
using LaneDescriptionMap = util::ConcurrentIDMap<TurnLaneDescription, LaneDescriptionID>; // hash function for TurnLaneDescription
struct TurnLaneDescription_hash
{
std::size_t operator()(const TurnLaneDescription &lane_description) const
{
std::size_t seed = 0;
boost::hash_range(seed, lane_description.begin(), lane_description.end());
return seed;
}
};
using LaneDescriptionMap =
util::ConcurrentIDMap<TurnLaneDescription, LaneDescriptionID, TurnLaneDescription_hash>;
using TurnLanesIndexedArray = using TurnLanesIndexedArray =
std::tuple<std::vector<std::uint32_t>, std::vector<TurnLaneType::Mask>>; std::tuple<std::vector<std::uint32_t>, std::vector<TurnLaneType::Mask>>;
+39 -39
View File
@@ -4,7 +4,7 @@
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include <algorithm> #include <algorithm>
#include <variant> #include <mapbox/variant.hpp>
#include <vector> #include <vector>
namespace osrm::extractor namespace osrm::extractor
@@ -61,50 +61,50 @@ struct InputViaWayPath
struct InputTurnPath struct InputTurnPath
{ {
std::variant<InputViaNodePath, InputViaWayPath> node_or_way; mapbox::util::variant<InputViaNodePath, InputViaWayPath> node_or_way;
TurnPathType Type() const TurnPathType Type() const
{ {
BOOST_ASSERT(node_or_way.index() < TurnPathType::NUM_TURN_PATH_TYPES); BOOST_ASSERT(node_or_way.which() < TurnPathType::NUM_TURN_PATH_TYPES);
return static_cast<TurnPathType>(node_or_way.index()); return static_cast<TurnPathType>(node_or_way.which());
} }
OSMWayID From() const OSMWayID From() const
{ {
return node_or_way.index() == TurnPathType::VIA_NODE_TURN_PATH return node_or_way.which() == TurnPathType::VIA_NODE_TURN_PATH
? std::get<InputViaNodePath>(node_or_way).from ? mapbox::util::get<InputViaNodePath>(node_or_way).from
: std::get<InputViaWayPath>(node_or_way).from; : mapbox::util::get<InputViaWayPath>(node_or_way).from;
} }
OSMWayID To() const OSMWayID To() const
{ {
return node_or_way.index() == TurnPathType::VIA_NODE_TURN_PATH return node_or_way.which() == TurnPathType::VIA_NODE_TURN_PATH
? std::get<InputViaNodePath>(node_or_way).to ? mapbox::util::get<InputViaNodePath>(node_or_way).to
: std::get<InputViaWayPath>(node_or_way).to; : mapbox::util::get<InputViaWayPath>(node_or_way).to;
} }
InputViaWayPath &AsViaWayPath() InputViaWayPath &AsViaWayPath()
{ {
BOOST_ASSERT(node_or_way.index() == TurnPathType::VIA_WAY_TURN_PATH); BOOST_ASSERT(node_or_way.which() == TurnPathType::VIA_WAY_TURN_PATH);
return std::get<InputViaWayPath>(node_or_way); return mapbox::util::get<InputViaWayPath>(node_or_way);
} }
const InputViaWayPath &AsViaWayPath() const const InputViaWayPath &AsViaWayPath() const
{ {
BOOST_ASSERT(node_or_way.index() == TurnPathType::VIA_WAY_TURN_PATH); BOOST_ASSERT(node_or_way.which() == TurnPathType::VIA_WAY_TURN_PATH);
return std::get<InputViaWayPath>(node_or_way); return mapbox::util::get<InputViaWayPath>(node_or_way);
} }
InputViaNodePath &AsViaNodePath() InputViaNodePath &AsViaNodePath()
{ {
BOOST_ASSERT(node_or_way.index() == TurnPathType::VIA_NODE_TURN_PATH); BOOST_ASSERT(node_or_way.which() == TurnPathType::VIA_NODE_TURN_PATH);
return std::get<InputViaNodePath>(node_or_way); return mapbox::util::get<InputViaNodePath>(node_or_way);
} }
const InputViaNodePath &AsViaNodePath() const const InputViaNodePath &AsViaNodePath() const
{ {
BOOST_ASSERT(node_or_way.index() == TurnPathType::VIA_NODE_TURN_PATH); BOOST_ASSERT(node_or_way.which() == TurnPathType::VIA_NODE_TURN_PATH);
return std::get<InputViaNodePath>(node_or_way); return mapbox::util::get<InputViaNodePath>(node_or_way);
} }
}; };
@@ -175,63 +175,63 @@ struct ViaWayPath
// between node/way paths // between node/way paths
struct TurnPath struct TurnPath
{ {
std::variant<ViaNodePath, ViaWayPath> node_or_way; mapbox::util::variant<ViaNodePath, ViaWayPath> node_or_way;
NodeID To() const NodeID To() const
{ {
return node_or_way.index() == TurnPathType::VIA_NODE_TURN_PATH return node_or_way.which() == TurnPathType::VIA_NODE_TURN_PATH
? std::get<ViaNodePath>(node_or_way).to ? mapbox::util::get<ViaNodePath>(node_or_way).to
: std::get<ViaWayPath>(node_or_way).to; : mapbox::util::get<ViaWayPath>(node_or_way).to;
} }
NodeID From() const NodeID From() const
{ {
return node_or_way.index() == TurnPathType::VIA_NODE_TURN_PATH return node_or_way.which() == TurnPathType::VIA_NODE_TURN_PATH
? std::get<ViaNodePath>(node_or_way).from ? mapbox::util::get<ViaNodePath>(node_or_way).from
: std::get<ViaWayPath>(node_or_way).from; : mapbox::util::get<ViaWayPath>(node_or_way).from;
} }
NodeID FirstVia() const NodeID FirstVia() const
{ {
if (node_or_way.index() == TurnPathType::VIA_NODE_TURN_PATH) if (node_or_way.which() == TurnPathType::VIA_NODE_TURN_PATH)
{ {
return std::get<ViaNodePath>(node_or_way).via; return mapbox::util::get<ViaNodePath>(node_or_way).via;
} }
else else
{ {
BOOST_ASSERT(!std::get<ViaWayPath>(node_or_way).via.empty()); BOOST_ASSERT(!mapbox::util::get<ViaWayPath>(node_or_way).via.empty());
return std::get<ViaWayPath>(node_or_way).via[0]; return mapbox::util::get<ViaWayPath>(node_or_way).via[0];
} }
} }
ViaWayPath &AsViaWayPath() ViaWayPath &AsViaWayPath()
{ {
BOOST_ASSERT(node_or_way.index() == TurnPathType::VIA_WAY_TURN_PATH); BOOST_ASSERT(node_or_way.which() == TurnPathType::VIA_WAY_TURN_PATH);
return std::get<ViaWayPath>(node_or_way); return mapbox::util::get<ViaWayPath>(node_or_way);
} }
const ViaWayPath &AsViaWayPath() const const ViaWayPath &AsViaWayPath() const
{ {
BOOST_ASSERT(node_or_way.index() == TurnPathType::VIA_WAY_TURN_PATH); BOOST_ASSERT(node_or_way.which() == TurnPathType::VIA_WAY_TURN_PATH);
return std::get<ViaWayPath>(node_or_way); return mapbox::util::get<ViaWayPath>(node_or_way);
} }
ViaNodePath &AsViaNodePath() ViaNodePath &AsViaNodePath()
{ {
BOOST_ASSERT(node_or_way.index() == TurnPathType::VIA_NODE_TURN_PATH); BOOST_ASSERT(node_or_way.which() == TurnPathType::VIA_NODE_TURN_PATH);
return std::get<ViaNodePath>(node_or_way); return mapbox::util::get<ViaNodePath>(node_or_way);
} }
const ViaNodePath &AsViaNodePath() const const ViaNodePath &AsViaNodePath() const
{ {
BOOST_ASSERT(node_or_way.index() == TurnPathType::VIA_NODE_TURN_PATH); BOOST_ASSERT(node_or_way.which() == TurnPathType::VIA_NODE_TURN_PATH);
return std::get<ViaNodePath>(node_or_way); return mapbox::util::get<ViaNodePath>(node_or_way);
} }
TurnPathType Type() const TurnPathType Type() const
{ {
BOOST_ASSERT(node_or_way.index() < TurnPathType::NUM_TURN_PATH_TYPES); BOOST_ASSERT(node_or_way.which() < TurnPathType::NUM_TURN_PATH_TYPES);
return static_cast<TurnPathType>(node_or_way.index()); return static_cast<TurnPathType>(node_or_way.which());
} }
bool operator==(const TurnPath &other) const bool operator==(const TurnPath &other) const
+10 -5
View File
@@ -7,6 +7,7 @@
#include "guidance/intersection_handler.hpp" #include "guidance/intersection_handler.hpp"
#include "guidance/is_through_street.hpp" #include "guidance/is_through_street.hpp"
#include "util/attributes.hpp"
#include "util/node_based_graph.hpp" #include "util/node_based_graph.hpp"
#include <vector> #include <vector>
@@ -41,14 +42,18 @@ class MotorwayHandler final : public IntersectionHandler
Intersection intersection) const override final; Intersection intersection) const override final;
private: private:
[[nodiscard]] Intersection handleSliproads(const NodeID intersection_node_id, OSRM_ATTR_WARN_UNUSED
Intersection intersection) const; Intersection handleSliproads(const NodeID intersection_node_id,
Intersection intersection) const;
[[nodiscard]] Intersection fromMotorway(const EdgeID via_edge, Intersection intersection) const; OSRM_ATTR_WARN_UNUSED
Intersection fromMotorway(const EdgeID via_edge, Intersection intersection) const;
[[nodiscard]] Intersection fromRamp(const EdgeID via_edge, Intersection intersection) const; OSRM_ATTR_WARN_UNUSED
Intersection fromRamp(const EdgeID via_edge, Intersection intersection) const;
[[nodiscard]] Intersection fallback(Intersection intersection) const; OSRM_ATTR_WARN_UNUSED
Intersection fallback(Intersection intersection) const;
}; };
} // namespace osrm::guidance } // namespace osrm::guidance
+6 -3
View File
@@ -7,6 +7,8 @@
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/tokenizer.hpp> #include <boost/tokenizer.hpp>
#include "util/attributes.hpp"
namespace osrm::extractor::guidance namespace osrm::extractor::guidance
{ {
@@ -19,7 +21,8 @@ namespace osrm::extractor::guidance
// will be corrected to left|throught, since the final lane is not drivable. // will be corrected to left|throught, since the final lane is not drivable.
// This is in contrast to a situation with lanes:psv:forward=0 (or not set) where left|through| // This is in contrast to a situation with lanes:psv:forward=0 (or not set) where left|through|
// represents left|through|through // represents left|through|through
[[nodiscard]] inline std::string OSRM_ATTR_WARN_UNUSED
inline std::string
trimLaneString(std::string lane_string, std::int32_t count_left, std::int32_t count_right) trimLaneString(std::string lane_string, std::int32_t count_left, std::int32_t count_right)
{ {
if (count_left) if (count_left)
@@ -65,8 +68,8 @@ trimLaneString(std::string lane_string, std::int32_t count_left, std::int32_t co
// turn:lanes=left|through|through|right // turn:lanes=left|through|through|right
// vehicle:lanes=yes|yes|no|yes // vehicle:lanes=yes|yes|no|yes
// bicycle:lanes=yes|no|designated|yes // bicycle:lanes=yes|no|designated|yes
[[nodiscard]] inline std::string applyAccessTokens(std::string lane_string, OSRM_ATTR_WARN_UNUSED
const std::string &access_tokens) inline std::string applyAccessTokens(std::string lane_string, const std::string &access_tokens)
{ {
using tokenizer = boost::tokenizer<boost::char_separator<char>>; using tokenizer = boost::tokenizer<boost::char_separator<char>>;
boost::char_separator<char> sep("|", "", boost::keep_empty_tokens); boost::char_separator<char> sep("|", "", boost::keep_empty_tokens);
+6 -3
View File
@@ -17,6 +17,7 @@
#include "guidance/turn_classification.hpp" #include "guidance/turn_classification.hpp"
#include "guidance/turn_handler.hpp" #include "guidance/turn_handler.hpp"
#include "util/attributes.hpp"
#include "util/node_based_graph.hpp" #include "util/node_based_graph.hpp"
#include <cstdint> #include <cstdint>
@@ -46,11 +47,13 @@ class TurnAnalysis
/* Full Analysis Process for a single node/edge combination. Use with caution, as the process is /* Full Analysis Process for a single node/edge combination. Use with caution, as the process is
* relatively expensive */ * relatively expensive */
[[nodiscard]] Intersection operator()(const NodeID node_prior_to_intersection, OSRM_ATTR_WARN_UNUSED
const EdgeID entering_via_edge) const; Intersection operator()(const NodeID node_prior_to_intersection,
const EdgeID entering_via_edge) const;
// Select turn types based on the intersection shape // Select turn types based on the intersection shape
[[nodiscard]] Intersection OSRM_ATTR_WARN_UNUSED
Intersection
AssignTurnTypes(const NodeID from_node, AssignTurnTypes(const NodeID from_node,
const EdgeID via_eid, const EdgeID via_eid,
const extractor::intersection::IntersectionView &intersection) const; const extractor::intersection::IntersectionView &intersection) const;
+17 -13
View File
@@ -8,6 +8,7 @@
#include "guidance/intersection_handler.hpp" #include "guidance/intersection_handler.hpp"
#include "guidance/is_through_street.hpp" #include "guidance/is_through_street.hpp"
#include "util/attributes.hpp"
#include "util/node_based_graph.hpp" #include "util/node_based_graph.hpp"
#include <cstddef> #include <cstddef>
@@ -75,19 +76,20 @@ class TurnHandler final : public IntersectionHandler
bool isCompatibleByRoadClass(const Intersection &intersection, const Fork fork) const; bool isCompatibleByRoadClass(const Intersection &intersection, const Fork fork) const;
// Dead end. // Dead end.
[[nodiscard]] Intersection handleOneWayTurn(Intersection intersection) const; OSRM_ATTR_WARN_UNUSED
Intersection handleOneWayTurn(Intersection intersection) const;
// Mode Changes, new names... // Mode Changes, new names...
[[nodiscard]] Intersection handleTwoWayTurn(const EdgeID via_edge, OSRM_ATTR_WARN_UNUSED
Intersection intersection) const; Intersection handleTwoWayTurn(const EdgeID via_edge, Intersection intersection) const;
// Forks, T intersections and similar // Forks, T intersections and similar
[[nodiscard]] Intersection handleThreeWayTurn(const EdgeID via_edge, OSRM_ATTR_WARN_UNUSED
Intersection intersection) const; Intersection handleThreeWayTurn(const EdgeID via_edge, Intersection intersection) const;
// Handling of turns larger then degree three // Handling of turns larger then degree three
[[nodiscard]] Intersection handleComplexTurn(const EdgeID via_edge, OSRM_ATTR_WARN_UNUSED
Intersection intersection) const; Intersection handleComplexTurn(const EdgeID via_edge, Intersection intersection) const;
void void
handleDistinctConflict(const EdgeID via_edge, ConnectedRoad &left, ConnectedRoad &right) const; handleDistinctConflict(const EdgeID via_edge, ConnectedRoad &left, ConnectedRoad &right) const;
@@ -95,13 +97,15 @@ class TurnHandler final : public IntersectionHandler
// Classification // Classification
std::optional<Fork> findFork(const EdgeID via_edge, Intersection &intersection) const; std::optional<Fork> findFork(const EdgeID via_edge, Intersection &intersection) const;
[[nodiscard]] Intersection assignLeftTurns(const EdgeID via_edge, OSRM_ATTR_WARN_UNUSED
Intersection intersection, Intersection assignLeftTurns(const EdgeID via_edge,
const std::size_t starting_at) const; Intersection intersection,
const std::size_t starting_at) const;
[[nodiscard]] Intersection assignRightTurns(const EdgeID via_edge, OSRM_ATTR_WARN_UNUSED
Intersection intersection, Intersection assignRightTurns(const EdgeID via_edge,
const std::size_t up_to) const; Intersection intersection,
const std::size_t up_to) const;
}; };
} // namespace osrm::guidance } // namespace osrm::guidance
+3 -1
View File
@@ -2,6 +2,7 @@
#define OSRM_GUIDANCE_TURN_INSTRUCTION_HPP_ #define OSRM_GUIDANCE_TURN_INSTRUCTION_HPP_
#include "guidance/roundabout_type.hpp" #include "guidance/roundabout_type.hpp"
#include "util/attributes.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include <algorithm> #include <algorithm>
@@ -242,7 +243,8 @@ inline guidance::DirectionModifier::Enum getTurnDirection(const double angle)
} }
// swaps left <-> right modifier types // swaps left <-> right modifier types
[[nodiscard]] inline guidance::DirectionModifier::Enum OSRM_ATTR_WARN_UNUSED
inline guidance::DirectionModifier::Enum
mirrorDirectionModifier(const guidance::DirectionModifier::Enum modifier) mirrorDirectionModifier(const guidance::DirectionModifier::Enum modifier)
{ {
const constexpr guidance::DirectionModifier::Enum results[] = { const constexpr guidance::DirectionModifier::Enum results[] = {
+4 -2
View File
@@ -3,12 +3,14 @@
#include "guidance/intersection.hpp" #include "guidance/intersection.hpp"
#include "guidance/turn_lane_data.hpp" #include "guidance/turn_lane_data.hpp"
#include "util/attributes.hpp"
namespace osrm::guidance::lanes namespace osrm::guidance::lanes
{ {
[[nodiscard]] LaneDataVector handleNoneValueAtSimpleTurn(LaneDataVector lane_data, OSRM_ATTR_WARN_UNUSED
const Intersection &intersection); LaneDataVector handleNoneValueAtSimpleTurn(LaneDataVector lane_data,
const Intersection &intersection);
} // namespace osrm::guidance::lanes } // namespace osrm::guidance::lanes
+3 -2
View File
@@ -2,6 +2,7 @@
#define OSRM_GUIDANCE_TURN_LANE_DATA_HPP_ #define OSRM_GUIDANCE_TURN_LANE_DATA_HPP_
#include "extractor/turn_lane_types.hpp" #include "extractor/turn_lane_types.hpp"
#include "util/attributes.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include <vector> #include <vector>
@@ -22,8 +23,8 @@ struct TurnLaneData
using LaneDataVector = std::vector<TurnLaneData>; using LaneDataVector = std::vector<TurnLaneData>;
// convertes a string given in the OSM format into a TurnLaneData vector // convertes a string given in the OSM format into a TurnLaneData vector
[[nodiscard]] LaneDataVector OSRM_ATTR_WARN_UNUSED
laneDataFromDescription(const extractor::TurnLaneDescription &turn_lane_description); LaneDataVector laneDataFromDescription(const extractor::TurnLaneDescription &turn_lane_description);
// Locate A Tag in a lane data vector (if multiple tags are set, the first one found is returned) // Locate A Tag in a lane data vector (if multiple tags are set, the first one found is returned)
LaneDataVector::const_iterator findTag(const extractor::TurnLaneType::Mask tag, LaneDataVector::const_iterator findTag(const extractor::TurnLaneType::Mask tag,
+15 -13
View File
@@ -9,6 +9,7 @@
#include "guidance/turn_analysis.hpp" #include "guidance/turn_analysis.hpp"
#include "guidance/turn_lane_data.hpp" #include "guidance/turn_lane_data.hpp"
#include "util/attributes.hpp"
#include "util/guidance/turn_lanes.hpp" #include "util/guidance/turn_lanes.hpp"
#include "util/node_based_graph.hpp" #include "util/node_based_graph.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
@@ -67,8 +68,8 @@ class TurnLaneHandler
~TurnLaneHandler(); ~TurnLaneHandler();
[[nodiscard]] Intersection OSRM_ATTR_WARN_UNUSED
assignTurnLanes(const NodeID at, const EdgeID via_edge, Intersection intersection); Intersection assignTurnLanes(const NodeID at, const EdgeID via_edge, Intersection intersection);
private: private:
mutable std::atomic<std::size_t> count_handled; mutable std::atomic<std::size_t> count_handled;
@@ -107,23 +108,24 @@ class TurnLaneHandler
const Intersection &intersection) const; const Intersection &intersection) const;
// in case of a simple intersection, assign the lane entries // in case of a simple intersection, assign the lane entries
[[nodiscard]] Intersection simpleMatchTuplesToTurns(Intersection intersection, OSRM_ATTR_WARN_UNUSED
const LaneDataVector &lane_data, Intersection simpleMatchTuplesToTurns(Intersection intersection,
const LaneDescriptionID lane_string_id); const LaneDataVector &lane_data,
const LaneDescriptionID lane_string_id);
// partition lane data into lane data relevant at current turn and at next turn // partition lane data into lane data relevant at current turn and at next turn
[[nodiscard]] std::pair<TurnLaneHandler::LaneDataVector, TurnLaneHandler::LaneDataVector> OSRM_ATTR_WARN_UNUSED
partitionLaneData(const NodeID at, std::pair<TurnLaneHandler::LaneDataVector, TurnLaneHandler::LaneDataVector> partitionLaneData(
LaneDataVector turn_lane_data, const NodeID at, LaneDataVector turn_lane_data, const Intersection &intersection) const;
const Intersection &intersection) const;
// Sliproad turns have a separated lane to the right/left of other depicted lanes. These lanes // Sliproad turns have a separated lane to the right/left of other depicted lanes. These lanes
// are not necessarily separated clearly from the rest of the way. As a result, we combine both // are not necessarily separated clearly from the rest of the way. As a result, we combine both
// lane entries for our output, while performing the matching with the separated lanes only. // lane entries for our output, while performing the matching with the separated lanes only.
[[nodiscard]] Intersection handleSliproadTurn(Intersection intersection, OSRM_ATTR_WARN_UNUSED
const LaneDescriptionID lane_description_id, Intersection handleSliproadTurn(Intersection intersection,
LaneDataVector lane_data, const LaneDescriptionID lane_description_id,
const Intersection &previous_intersection); LaneDataVector lane_data,
const Intersection &previous_intersection);
// get the lane data for an intersection // get the lane data for an intersection
void extractLaneData(const EdgeID via_edge, void extractLaneData(const EdgeID via_edge,
+7 -6
View File
@@ -5,6 +5,7 @@
#include "guidance/turn_instruction.hpp" #include "guidance/turn_instruction.hpp"
#include "guidance/turn_lane_data.hpp" #include "guidance/turn_lane_data.hpp"
#include "util/attributes.hpp"
#include "util/guidance/turn_lanes.hpp" #include "util/guidance/turn_lanes.hpp"
#include "util/node_based_graph.hpp" #include "util/node_based_graph.hpp"
@@ -33,12 +34,12 @@ findBestMatchForReverse(const extractor::TurnLaneType::Mask leftmost_tag,
bool canMatchTrivially(const Intersection &intersection, const LaneDataVector &lane_data); bool canMatchTrivially(const Intersection &intersection, const LaneDataVector &lane_data);
// perform a trivial match on the turn lanes // perform a trivial match on the turn lanes
[[nodiscard]] Intersection OSRM_ATTR_WARN_UNUSED
triviallyMatchLanesToTurns(Intersection intersection, Intersection triviallyMatchLanesToTurns(Intersection intersection,
const LaneDataVector &lane_data, const LaneDataVector &lane_data,
const util::NodeBasedDynamicGraph &node_based_graph, const util::NodeBasedDynamicGraph &node_based_graph,
const LaneDescriptionID lane_string_id, const LaneDescriptionID lane_string_id,
util::guidance::LaneDataIdMap &lane_data_to_id); util::guidance::LaneDataIdMap &lane_data_to_id);
} // namespace osrm::guidance::lanes } // namespace osrm::guidance::lanes
+2 -2
View File
@@ -29,7 +29,7 @@ struct V8Renderer
for (const auto &keyValue : object.values) for (const auto &keyValue : object.values)
{ {
Napi::Value child; Napi::Value child;
std::visit(V8Renderer(env, child), keyValue.second); mapbox::util::apply_visitor(V8Renderer(env, child), keyValue.second);
obj.Set(keyValue.first, child); obj.Set(keyValue.first, child);
} }
out = obj; out = obj;
@@ -41,7 +41,7 @@ struct V8Renderer
for (auto i = 0u; i < array.values.size(); ++i) for (auto i = 0u; i < array.values.size(); ++i)
{ {
Napi::Value child; Napi::Value child;
std::visit(V8Renderer(env, child), array.values[i]); mapbox::util::apply_visitor(V8Renderer(env, child), array.values[i]);
a.Set(i, child); a.Set(i, child);
} }
out = a; out = a;
+13 -8
View File
@@ -24,11 +24,11 @@
#include <boost/optional.hpp> #include <boost/optional.hpp>
#include <algorithm> #include <algorithm>
#include <iostream>
#include <iterator> #include <iterator>
#include <sstream> #include <sstream>
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
#include <variant>
#include <vector> #include <vector>
#include <exception> #include <exception>
@@ -51,7 +51,7 @@ struct PluginParameters
bool renderToBuffer = false; bool renderToBuffer = false;
}; };
using ObjectOrString = typename std::variant<osrm::json::Object, std::string>; using ObjectOrString = typename mapbox::util::variant<osrm::json::Object, std::string>;
template <typename ResultT> inline Napi::Value render(const Napi::Env &env, const ResultT &result); template <typename ResultT> inline Napi::Value render(const Napi::Env &env, const ResultT &result);
@@ -62,18 +62,18 @@ template <> Napi::Value inline render(const Napi::Env &env, const std::string &r
template <> Napi::Value inline render(const Napi::Env &env, const ObjectOrString &result) template <> Napi::Value inline render(const Napi::Env &env, const ObjectOrString &result)
{ {
if (std::holds_alternative<osrm::json::Object>(result)) if (result.is<osrm::json::Object>())
{ {
// Convert osrm::json object tree into matching v8 object tree // Convert osrm::json object tree into matching v8 object tree
Napi::Value value; Napi::Value value;
renderToV8(env, value, std::get<osrm::json::Object>(result)); renderToV8(env, value, result.get<osrm::json::Object>());
return value; return value;
} }
else else
{ {
// Return the string object as a node Buffer // Return the string object as a node Buffer
return Napi::Buffer<char>::Copy( return Napi::Buffer<char>::Copy(
env, std::get<std::string>(result).data(), std::get<std::string>(result).size()); env, result.get<std::string>().data(), result.get<std::string>().size());
} }
} }
@@ -96,7 +96,7 @@ inline void ParseResult(const osrm::Status &result_status, osrm::json::Object &r
if (result_status == osrm::Status::Error) if (result_status == osrm::Status::Error)
{ {
throw std::logic_error(std::get<osrm::json::String>(code_iter->second).value.c_str()); throw std::logic_error(code_iter->second.get<osrm::json::String>().value.c_str());
} }
result.values.erase(code_iter); result.values.erase(code_iter);
@@ -296,19 +296,24 @@ inline engine_config_ptr argumentsToEngineConfig(const Napi::CallbackInfo &args)
{ {
engine_config->algorithm = osrm::EngineConfig::Algorithm::CH; engine_config->algorithm = osrm::EngineConfig::Algorithm::CH;
} }
else if (algorithm_str == "CoreCH")
{
engine_config->algorithm = osrm::EngineConfig::Algorithm::CH;
}
else if (algorithm_str == "MLD") else if (algorithm_str == "MLD")
{ {
engine_config->algorithm = osrm::EngineConfig::Algorithm::MLD; engine_config->algorithm = osrm::EngineConfig::Algorithm::MLD;
} }
else else
{ {
ThrowError(args.Env(), "algorithm option must be one of 'CH', or 'MLD'."); ThrowError(args.Env(), "algorithm option must be one of 'CH', 'CoreCH', or 'MLD'.");
return engine_config_ptr(); return engine_config_ptr();
} }
} }
else if (!algorithm.IsUndefined()) else if (!algorithm.IsUndefined())
{ {
ThrowError(args.Env(), "algorithm option must be a string and one of 'CH', or 'MLD'."); ThrowError(args.Env(),
"algorithm option must be a string and one of 'CH', 'CoreCH', or 'MLD'.");
return engine_config_ptr(); return engine_config_ptr();
} }
+1 -1
View File
@@ -12,7 +12,7 @@ struct header
// explicitly use default copy c'tor as adding move c'tor // explicitly use default copy c'tor as adding move c'tor
header &operator=(const header &other) = default; header &operator=(const header &other) = default;
header(std::string name, std::string value) : name(std::move(name)), value(std::move(value)) {} header(std::string name, std::string value) : name(std::move(name)), value(std::move(value)) {}
header(header &&other) noexcept : name(std::move(other.name)), value(std::move(other.value)) {} header(header &&other) : name(std::move(other.name)), value(std::move(other.value)) {}
void clear() void clear()
{ {
+1 -1
View File
@@ -5,7 +5,7 @@
#include "osrm/osrm.hpp" #include "osrm/osrm.hpp"
#include "util/coordinate.hpp" #include "util/coordinate.hpp"
#include <variant> #include <mapbox/variant.hpp>
#include <string> #include <string>
#include <vector> #include <vector>
-1
View File
@@ -18,7 +18,6 @@
#include <cerrno> #include <cerrno>
#include <cstring> #include <cstring>
#include <iostream>
#include <tuple> #include <tuple>
#include <type_traits> #include <type_traits>
+1 -1
View File
@@ -61,7 +61,7 @@ class SharedMemory
{ {
shm = boost::interprocess::xsi_shared_memory(boost::interprocess::open_only, key); shm = boost::interprocess::xsi_shared_memory(boost::interprocess::open_only, key);
util::Log(logDEBUG) << "opening " << shm.get_shmid() << " from id " << (int)id; util::Log(logDEBUG) << "opening " << (int)shm.get_shmid() << " from id " << (int)id;
region = boost::interprocess::mapped_region(shm, boost::interprocess::read_only); region = boost::interprocess::mapped_region(shm, boost::interprocess::read_only);
} }
+2 -2
View File
@@ -28,9 +28,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef OSRM_UTIL_ALIAS_HPP #ifndef OSRM_UTIL_ALIAS_HPP
#define OSRM_UTIL_ALIAS_HPP #define OSRM_UTIL_ALIAS_HPP
#include <cstddef> #include <boost/numeric/conversion/cast.hpp>
#include <functional> #include <functional>
#include <ostream> #include <iostream>
#include <type_traits> #include <type_traits>
namespace osrm namespace osrm
+13
View File
@@ -0,0 +1,13 @@
#ifndef OSRM_ATTRIBUTES_HPP_
#define OSRM_ATTRIBUTES_HPP_
// OSRM_ATTR_WARN_UNUSED - caller has to use function's return value
// https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
#if defined(__GNUC__) && (__GNUC__ >= 4)
#define OSRM_ATTR_WARN_UNUSED __attribute__((warn_unused_result))
#else
#define OSRM_ATTR_WARN_UNUSED
#endif
#endif
+1 -2
View File
@@ -4,7 +4,6 @@
#include <cmath> #include <cmath>
#include <cstdint> #include <cstdint>
#include <limits> #include <limits>
#include <numbers>
#include <tuple> #include <tuple>
#include <utility> #include <utility>
@@ -38,7 +37,7 @@ class CheapRuler
static constexpr double FE = 1.0 / 298.257223563; // flattening static constexpr double FE = 1.0 / 298.257223563; // flattening
static constexpr double E2 = FE * (2 - FE); static constexpr double E2 = FE * (2 - FE);
static constexpr double RAD = std::numbers::pi / 180.0; static constexpr double RAD = M_PI / 180.0;
public: public:
explicit CheapRuler(double latitude) explicit CheapRuler(double latitude)
+2 -2
View File
@@ -26,7 +26,7 @@ struct ConcurrentIDMap
mutable UpgradableMutex mutex; mutable UpgradableMutex mutex;
ConcurrentIDMap() = default; ConcurrentIDMap() = default;
ConcurrentIDMap(ConcurrentIDMap &&other) noexcept ConcurrentIDMap(ConcurrentIDMap &&other)
{ {
if (this != &other) if (this != &other)
{ {
@@ -36,7 +36,7 @@ struct ConcurrentIDMap
data = std::move(other.data); data = std::move(other.data);
} }
} }
ConcurrentIDMap &operator=(ConcurrentIDMap &&other) noexcept ConcurrentIDMap &operator=(ConcurrentIDMap &&other)
{ {
if (this != &other) if (this != &other)
{ {
+11 -3
View File
@@ -3,7 +3,7 @@
#include "util/coordinate.hpp" #include "util/coordinate.hpp"
#include <numbers> #include <boost/math/constants/constants.hpp>
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
@@ -23,9 +23,17 @@ const constexpr double RAD_TO_DEGREE = 1. / DEGREE_TO_RAD;
// The IUGG value for the equatorial radius is 6378.137 km (3963.19 miles) // The IUGG value for the equatorial radius is 6378.137 km (3963.19 miles)
const constexpr long double EARTH_RADIUS = 6372797.560856; const constexpr long double EARTH_RADIUS = 6372797.560856;
inline double degToRad(const double degree) { return degree * (std::numbers::pi / 180.0); } inline double degToRad(const double degree)
{
using namespace boost::math::constants;
return degree * (pi<double>() / 180.0);
}
inline double radToDeg(const double radian) { return radian * (180.0 * std::numbers::inv_pi); } inline double radToDeg(const double radian)
{
using namespace boost::math::constants;
return radian * (180.0 * (1. / pi<double>()));
}
} // namespace detail } // namespace detail
const constexpr static double METERS_PER_DEGREE_LAT = 110567.0; const constexpr static double METERS_PER_DEGREE_LAT = 110567.0;
+6 -7
View File
@@ -166,7 +166,7 @@ class DeallocatingVectorIterator
template <typename ElementT> class DeallocatingVector; template <typename ElementT> class DeallocatingVector;
template <typename T> void swap(DeallocatingVector<T> &lhs, DeallocatingVector<T> &rhs) noexcept; template <typename T> void swap(DeallocatingVector<T> &lhs, DeallocatingVector<T> &rhs);
template <typename ElementT> class DeallocatingVector template <typename ElementT> class DeallocatingVector
{ {
@@ -204,8 +204,8 @@ template <typename ElementT> class DeallocatingVector
} }
// moving is fine // moving is fine
DeallocatingVector(DeallocatingVector &&other) noexcept { swap(other); } DeallocatingVector(DeallocatingVector &&other) { swap(other); }
DeallocatingVector &operator=(DeallocatingVector &&other) noexcept DeallocatingVector &operator=(DeallocatingVector &&other)
{ {
swap(other); swap(other);
return *this; return *this;
@@ -221,10 +221,9 @@ template <typename ElementT> class DeallocatingVector
~DeallocatingVector() { clear(); } ~DeallocatingVector() { clear(); }
friend void swap<>(DeallocatingVector<ElementT> &lhs, friend void swap<>(DeallocatingVector<ElementT> &lhs, DeallocatingVector<ElementT> &rhs);
DeallocatingVector<ElementT> &rhs) noexcept;
void swap(DeallocatingVector<ElementT> &other) noexcept void swap(DeallocatingVector<ElementT> &other)
{ {
std::swap(current_size, other.current_size); std::swap(current_size, other.current_size);
bucket_list.swap(other.bucket_list); bucket_list.swap(other.bucket_list);
@@ -343,7 +342,7 @@ template <typename ElementT> class DeallocatingVector
} }
}; };
template <typename T> void swap(DeallocatingVector<T> &lhs, DeallocatingVector<T> &rhs) noexcept template <typename T> void swap(DeallocatingVector<T> &lhs, DeallocatingVector<T> &rhs)
{ {
lhs.swap(rhs); lhs.swap(rhs);
} }
+1 -1
View File
@@ -12,7 +12,7 @@
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include <iomanip> #include <iomanip>
#include <ostream> #include <iostream>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <vector> #include <vector>
+2 -2
View File
@@ -154,7 +154,7 @@ template <typename EdgeDataT> class DynamicGraph
return *this; return *this;
} }
DynamicGraph(DynamicGraph &&other) noexcept DynamicGraph(DynamicGraph &&other)
{ {
number_of_nodes = other.number_of_nodes; number_of_nodes = other.number_of_nodes;
// atomics can't be moved this is why we need an own constructor // atomics can't be moved this is why we need an own constructor
@@ -164,7 +164,7 @@ template <typename EdgeDataT> class DynamicGraph
edge_list = std::move(other.edge_list); edge_list = std::move(other.edge_list);
} }
DynamicGraph &operator=(DynamicGraph &&other) noexcept DynamicGraph &operator=(DynamicGraph &&other)
{ {
number_of_nodes = other.number_of_nodes; number_of_nodes = other.number_of_nodes;
// atomics can't be moved this is why we need an own constructor // atomics can't be moved this is why we need an own constructor
+1
View File
@@ -30,6 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <array> #include <array>
#include <exception> #include <exception>
#include <iostream>
#include <string> #include <string>
#include <utility> #include <utility>
+3 -5
View File
@@ -1,8 +1,6 @@
#ifndef EXCEPTION_UTILS_HPP #ifndef SOURCE_MACROS_HPP
#define EXCEPTION_UTILS_HPP #define SOURCE_MACROS_HPP
#include <cstring> #include <cstring>
#include <string>
// Helper macros, don't use these ones // Helper macros, don't use these ones
// STRIP the OSRM_PROJECT_DIR from the front of a filename. Expected to come // STRIP the OSRM_PROJECT_DIR from the front of a filename. Expected to come
@@ -14,4 +12,4 @@
// This is the macro to use // This is the macro to use
#define SOURCE_REF (OSRM_SOURCE_FILE_ + ":" + std::to_string(__LINE__)) #define SOURCE_REF (OSRM_SOURCE_FILE_ + ":" + std::to_string(__LINE__))
#endif // EXCEPTION_UTILS_HPP #endif // SOURCE_MACROS_HPP
+1 -1
View File
@@ -51,7 +51,7 @@ class GeojsonLogger
if (!first) if (!first)
ofs << ",\n\t\t"; ofs << ",\n\t\t";
util::json::render(ofs, std::get<util::json::Object>(object)); util::json::render(ofs, object.get<util::json::Object>());
first = false; first = false;
} }
+1 -1
View File
@@ -51,4 +51,4 @@ struct CoordinateVectorToMultiPoint
} // namespace osrm::util } // namespace osrm::util
#endif /* OSRM_GEOJSON_DEBUG_POLICIES */ #endif /* OSRM_GEOJSON_DEBUG_POLICIES */
@@ -55,12 +55,12 @@ inline util::json::Object makeStyle(const GeojsonStyleSize size_type,
struct CoordinateToJsonArray struct CoordinateToJsonArray
{ {
util::json::Value operator()(const util::Coordinate coordinate) util::json::Array operator()(const util::Coordinate coordinate)
{ {
util::json::Array json_coordinate; util::json::Array json_coordinate;
json_coordinate.values.push_back(static_cast<double>(toFloating(coordinate.lon))); json_coordinate.values.push_back(static_cast<double>(toFloating(coordinate.lon)));
json_coordinate.values.push_back(static_cast<double>(toFloating(coordinate.lat))); json_coordinate.values.push_back(static_cast<double>(toFloating(coordinate.lat)));
return util::json::Value{json_coordinate}; return json_coordinate;
} }
}; };
@@ -73,7 +73,7 @@ struct NodeIdToCoordinate
const std::vector<util::Coordinate> &node_coordinates; const std::vector<util::Coordinate> &node_coordinates;
util::json::Value operator()(const NodeID nid) util::json::Array operator()(const NodeID nid)
{ {
auto coordinate = node_coordinates[nid]; auto coordinate = node_coordinates[nid];
CoordinateToJsonArray converter; CoordinateToJsonArray converter;
@@ -108,4 +108,4 @@ inline util::json::Array makeJsonArray(const std::vector<util::Coordinate> &inpu
} }
} // namespace osrm::util } // namespace osrm::util
#endif /* OSRM_GEOJSON_DEBUG_POLICY_TOOLKIT_HPP */ #endif /* OSRM_GEOJSON_DEBUG_POLICY_TOOLKIT_HPP */
+5 -7
View File
@@ -1,14 +1,15 @@
#ifndef OSRM_UTIL_GUIDANCE_BEARING_CLASS_HPP_ #ifndef OSRM_UTIL_GUIDANCE_BEARING_CLASS_HPP_
#define OSRM_UTIL_GUIDANCE_BEARING_CLASS_HPP_ #define OSRM_UTIL_GUIDANCE_BEARING_CLASS_HPP_
#include "util/std_hash.hpp"
#include "util/typedefs.hpp"
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
#include <functional> #include <functional>
#include <vector> #include <vector>
#include <boost/functional/hash.hpp>
#include "util/typedefs.hpp"
namespace osrm::util::guidance namespace osrm::util::guidance
{ {
class BearingClass; class BearingClass;
@@ -61,10 +62,7 @@ namespace std
inline size_t hash<::osrm::util::guidance::BearingClass>::operator()( inline size_t hash<::osrm::util::guidance::BearingClass>::operator()(
const ::osrm::util::guidance::BearingClass &bearing_class) const const ::osrm::util::guidance::BearingClass &bearing_class) const
{ {
std::size_t value = 0; return boost::hash_value(bearing_class.available_bearings);
hash_range(
value, bearing_class.available_bearings.cbegin(), bearing_class.available_bearings.cend());
return value;
} }
} // namespace std } // namespace std
+6 -1
View File
@@ -6,6 +6,7 @@
#include "extractor/name_table.hpp" #include "extractor/name_table.hpp"
#include "extractor/suffix_table.hpp" #include "extractor/suffix_table.hpp"
#include "util/attributes.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include <algorithm> #include <algorithm>
@@ -14,6 +15,9 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/predicate.hpp>
namespace osrm::util::guidance namespace osrm::util::guidance
{ {
// Name Change Logic // Name Change Logic
@@ -124,7 +128,8 @@ inline bool requiresNameAnnounced(const StringView &from_name,
// check similarity of names // check similarity of names
const auto names_are_empty = from_name.empty() && to_name.empty(); const auto names_are_empty = from_name.empty() && to_name.empty();
const auto name_is_contained = from_name.starts_with(to_name) || to_name.starts_with(from_name); const auto name_is_contained =
boost::starts_with(from_name, to_name) || boost::starts_with(to_name, from_name);
const auto checkForPrefixOrSuffixChange = [](const std::string_view first, const auto checkForPrefixOrSuffixChange = [](const std::string_view first,
const std::string_view second, const std::string_view second,
+35 -31
View File
@@ -1,22 +1,36 @@
#ifndef OSRM_UTIL_GUIDANCE_TURN_LANES_HPP #ifndef OSRM_UTIL_GUIDANCE_TURN_LANES_HPP
#define OSRM_UTIL_GUIDANCE_TURN_LANES_HPP #define OSRM_UTIL_GUIDANCE_TURN_LANES_HPP
#include "util/concurrent_id_map.hpp"
#include "util/std_hash.hpp"
#include "util/typedefs.hpp"
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
#include <functional> #include <functional>
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include "util/concurrent_id_map.hpp"
#include "util/typedefs.hpp"
#include <boost/functional/hash.hpp>
namespace osrm::util::guidance namespace osrm::util::guidance
{ {
class LaneTuple; class LaneTuple;
class LaneTupleIdPair; class LaneTupleIdPair;
} // namespace osrm::util::guidance } // namespace osrm::util::guidance
namespace std
{
template <> struct hash<::osrm::util::guidance::LaneTuple>
{
inline std::size_t operator()(const ::osrm::util::guidance::LaneTuple &bearing_class) const;
};
template <> struct hash<::osrm::util::guidance::LaneTupleIdPair>
{
inline std::size_t
operator()(const ::osrm::util::guidance::LaneTupleIdPair &bearing_class) const;
};
} // namespace std
namespace osrm::util::guidance namespace osrm::util::guidance
{ {
@@ -47,6 +61,14 @@ class LaneTuple
LaneID lanes_in_turn; LaneID lanes_in_turn;
LaneID first_lane_from_the_right; // is INVALID_LANEID when no lanes present LaneID first_lane_from_the_right; // is INVALID_LANEID when no lanes present
friend std::size_t hash_value(const LaneTuple &tup)
{
std::size_t seed{0};
boost::hash_combine(seed, tup.lanes_in_turn);
boost::hash_combine(seed, tup.first_lane_from_the_right);
return seed;
}
}; };
class LaneTupleIdPair class LaneTupleIdPair
@@ -56,36 +78,18 @@ class LaneTupleIdPair
LaneDescriptionID second; LaneDescriptionID second;
bool operator==(const LaneTupleIdPair &other) const; bool operator==(const LaneTupleIdPair &other) const;
friend std::size_t hash_value(const LaneTupleIdPair &pair)
{
std::size_t seed{0};
boost::hash_combine(seed, pair.first);
boost::hash_combine(seed, pair.second);
return seed;
}
}; };
using LaneDataIdMap = ConcurrentIDMap<LaneTupleIdPair, LaneDataID>; using LaneDataIdMap = ConcurrentIDMap<LaneTupleIdPair, LaneDataID, boost::hash<LaneTupleIdPair>>;
} // namespace osrm::util::guidance } // namespace osrm::util::guidance
namespace std
{
template <> struct hash<::osrm::util::guidance::LaneTuple>
{
inline std::size_t operator()(const ::osrm::util::guidance::LaneTuple &lane_tuple) const
{
std::size_t seed{0};
hash_combine(seed, lane_tuple.lanes_in_turn);
hash_combine(seed, lane_tuple.first_lane_from_the_right);
return seed;
}
};
template <> struct hash<::osrm::util::guidance::LaneTupleIdPair>
{
inline std::size_t
operator()(const ::osrm::util::guidance::LaneTupleIdPair &lane_tuple_id_pair) const
{
std::size_t seed{0};
hash_combine(seed, lane_tuple_id_pair.first);
hash_combine(seed, lane_tuple_id_pair.second);
return seed;
}
};
} // namespace std
#endif /* OSRM_UTIL_GUIDANCE_TURN_LANES_HPP */ #endif /* OSRM_UTIL_GUIDANCE_TURN_LANES_HPP */
+9 -2
View File
@@ -31,10 +31,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef JSON_CONTAINER_HPP #ifndef JSON_CONTAINER_HPP
#define JSON_CONTAINER_HPP #define JSON_CONTAINER_HPP
#include <mapbox/variant.hpp>
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
#include <utility> #include <utility>
#include <variant>
#include <vector> #include <vector>
namespace osrm::util::json namespace osrm::util::json
@@ -95,7 +96,13 @@ struct Null
* *
* Dispatch on its type by either by using apply_visitor or its get function. * Dispatch on its type by either by using apply_visitor or its get function.
*/ */
using Value = std::variant<String, Number, Object, Array, True, False, Null>; using Value = mapbox::util::variant<String,
Number,
mapbox::util::recursive_wrapper<Object>,
mapbox::util::recursive_wrapper<Array>,
True,
False,
Null>;
/** /**
* Typed Object. * Typed Object.
+12 -10
View File
@@ -81,10 +81,10 @@ struct Comparator
const auto &rhs_child = rhs.values.find(key)->second; const auto &rhs_child = rhs.values.find(key)->second;
const auto &lhs_child = lhs.values.find(key)->second; const auto &lhs_child = lhs.values.find(key)->second;
auto is_same = auto is_same = mapbox::util::apply_visitor(
std::visit(Comparator(reason, lhs_path + "." + key, rhs_path + "." + key), Comparator(reason, lhs_path + "." + key, rhs_path + "." + key),
lhs_child, lhs_child,
rhs_child); rhs_child);
if (!is_same) if (!is_same)
{ {
return false; return false;
@@ -104,11 +104,12 @@ struct Comparator
for (auto i = 0UL; i < lhs.values.size(); ++i) for (auto i = 0UL; i < lhs.values.size(); ++i)
{ {
auto is_same = std::visit(Comparator(reason, auto is_same =
lhs_path + "[" + std::to_string(i) + "]", mapbox::util::apply_visitor(Comparator(reason,
rhs_path + "[" + std::to_string(i) + "]"), lhs_path + "[" + std::to_string(i) + "]",
lhs.values[i], rhs_path + "[" + std::to_string(i) + "]"),
rhs.values[i]); lhs.values[i],
rhs.values[i]);
if (!is_same) if (!is_same)
{ {
return false; return false;
@@ -150,7 +151,8 @@ struct Comparator
inline bool compare(const Value &reference, const Value &result, std::string &reason) inline bool compare(const Value &reference, const Value &result, std::string &reason)
{ {
return std::visit(Comparator(reason, "reference", "result"), reference, result); return mapbox::util::apply_visitor(
Comparator(reason, "reference", "result"), reference, result);
} }
} // namespace osrm::util::json } // namespace osrm::util::json
+2 -2
View File
@@ -67,7 +67,7 @@ template <typename Out> struct Renderer
write('\"'); write('\"');
write(it->first); write(it->first);
write<>("\":"); write<>("\":");
std::visit(Renderer(out), it->second); mapbox::util::apply_visitor(Renderer(out), it->second);
if (++it != end) if (++it != end)
{ {
write(','); write(',');
@@ -81,7 +81,7 @@ template <typename Out> struct Renderer
write('['); write('[');
for (auto it = array.values.cbegin(), end = array.values.cend(); it != end;) for (auto it = array.values.cbegin(), end = array.values.cend(); it != end;)
{ {
std::visit(Renderer(out), *it); mapbox::util::apply_visitor(Renderer(out), *it);
if (++it != end) if (++it != end)
{ {
write(','); write(',');
+1
View File
@@ -10,6 +10,7 @@ extern "C"
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <iostream>
#include <string> #include <string>
namespace osrm::util namespace osrm::util
+49
View File
@@ -0,0 +1,49 @@
#ifndef MATRIX_GRAPH_WRAPPER_H
#define MATRIX_GRAPH_WRAPPER_H
#include <cstddef>
#include <iterator>
#include <vector>
#include "util/typedefs.hpp"
namespace osrm::util
{
// This Wrapper provides all methods that are needed for util::TarjanSCC, when the graph is
// given in a matrix representation (e.g. as output from a distance table call)
template <typename T> class MatrixGraphWrapper
{
public:
MatrixGraphWrapper(std::vector<T> table, const std::size_t number_of_nodes)
: table_(std::move(table)), number_of_nodes_(number_of_nodes)
{
}
std::size_t GetNumberOfNodes() const { return number_of_nodes_; }
std::vector<T> GetAdjacentEdgeRange(const NodeID node) const
{
std::vector<T> edges;
// find all valid adjacent edges and move to vector `edges`
for (std::size_t i = 0; i < number_of_nodes_; ++i)
{
if (*(std::begin(table_) + node * number_of_nodes_ + i) != INVALID_EDGE_WEIGHT)
{
edges.push_back(i);
}
}
return edges;
}
EdgeWeight GetTarget(const EdgeWeight edge) const { return edge; }
private:
const std::vector<T> table_;
const std::size_t number_of_nodes_;
};
} // namespace osrm::util
#endif // MATRIX_GRAPH_WRAPPER_H
+1
View File
@@ -9,6 +9,7 @@
#include <tbb/parallel_sort.h> #include <tbb/parallel_sort.h>
#include <iostream>
#include <memory> #include <memory>
#include <utility> #include <utility>
+35 -14
View File
@@ -153,7 +153,8 @@ template <typename T, std::size_t Bits, storage::Ownership Ownership> class Pack
// number of words per block // number of words per block
static constexpr std::size_t BLOCK_WORDS = (Bits * BLOCK_ELEMENTS) / WORD_BITS; static constexpr std::size_t BLOCK_WORDS = (Bits * BLOCK_ELEMENTS) / WORD_BITS;
static constexpr std::array<WordT, BLOCK_ELEMENTS> initialize_lower_mask() // C++14 does not allow operator[] to be constexpr, this is fixed in C++17.
static /* constexpr */ std::array<WordT, BLOCK_ELEMENTS> initialize_lower_mask()
{ {
std::array<WordT, BLOCK_ELEMENTS> lower_mask; std::array<WordT, BLOCK_ELEMENTS> lower_mask;
@@ -169,7 +170,7 @@ template <typename T, std::size_t Bits, storage::Ownership Ownership> class Pack
return lower_mask; return lower_mask;
} }
static constexpr std::array<WordT, BLOCK_ELEMENTS> initialize_upper_mask() static /* constexpr */ std::array<WordT, BLOCK_ELEMENTS> initialize_upper_mask()
{ {
std::array<WordT, BLOCK_ELEMENTS> upper_mask; std::array<WordT, BLOCK_ELEMENTS> upper_mask;
@@ -193,7 +194,7 @@ template <typename T, std::size_t Bits, storage::Ownership Ownership> class Pack
return upper_mask; return upper_mask;
} }
static constexpr std::array<std::uint8_t, BLOCK_ELEMENTS> initialize_lower_offset() static /* constexpr */ std::array<std::uint8_t, BLOCK_ELEMENTS> initialize_lower_offset()
{ {
std::array<std::uint8_t, WORD_BITS> lower_offset; std::array<std::uint8_t, WORD_BITS> lower_offset;
@@ -208,7 +209,7 @@ template <typename T, std::size_t Bits, storage::Ownership Ownership> class Pack
return lower_offset; return lower_offset;
} }
static constexpr std::array<std::uint8_t, BLOCK_ELEMENTS> initialize_upper_offset() static /* constexpr */ std::array<std::uint8_t, BLOCK_ELEMENTS> initialize_upper_offset()
{ {
std::array<std::uint8_t, BLOCK_ELEMENTS> upper_offset; std::array<std::uint8_t, BLOCK_ELEMENTS> upper_offset;
@@ -231,7 +232,7 @@ template <typename T, std::size_t Bits, storage::Ownership Ownership> class Pack
return upper_offset; return upper_offset;
} }
static constexpr std::array<std::uint8_t, BLOCK_ELEMENTS> initialize_word_offset() static /* constexpr */ std::array<std::uint8_t, BLOCK_ELEMENTS> initialize_word_offset()
{ {
std::array<std::uint8_t, BLOCK_ELEMENTS> word_offset; std::array<std::uint8_t, BLOCK_ELEMENTS> word_offset;
@@ -245,15 +246,28 @@ template <typename T, std::size_t Bits, storage::Ownership Ownership> class Pack
return word_offset; return word_offset;
} }
// For now we need to call these on object creation
void initialize()
{
lower_mask = initialize_lower_mask();
upper_mask = initialize_upper_mask();
lower_offset = initialize_lower_offset();
upper_offset = initialize_upper_offset();
word_offset = initialize_word_offset();
}
// mask for the lower/upper word of a record // mask for the lower/upper word of a record
static constexpr std::array<WordT, BLOCK_ELEMENTS> lower_mask = initialize_lower_mask(); // TODO: With C++17 these could be constexpr
static constexpr std::array<WordT, BLOCK_ELEMENTS> upper_mask = initialize_upper_mask(); /* static constexpr */ std::array<WordT, BLOCK_ELEMENTS>
static constexpr std::array<std::uint8_t, BLOCK_ELEMENTS> lower_offset = lower_mask /* = initialize_lower_mask()*/;
initialize_lower_offset(); /* static constexpr */ std::array<WordT, BLOCK_ELEMENTS>
static constexpr std::array<std::uint8_t, BLOCK_ELEMENTS> upper_offset = upper_mask /* = initialize_upper_mask()*/;
initialize_upper_offset(); /* static constexpr */ std::array<std::uint8_t, BLOCK_ELEMENTS>
lower_offset /* = initialize_lower_offset()*/;
/* static constexpr */ std::array<std::uint8_t, BLOCK_ELEMENTS>
upper_offset /* = initialize_upper_offset()*/;
// in which word of the block is the element // in which word of the block is the element
static constexpr std::array<std::uint8_t, BLOCK_ELEMENTS> word_offset = /* static constexpr */ std::array<std::uint8_t, BLOCK_ELEMENTS> word_offset =
initialize_word_offset(); initialize_word_offset();
struct InternalIndex struct InternalIndex
@@ -364,21 +378,27 @@ template <typename T, std::size_t Bits, storage::Ownership Ownership> class Pack
PackedVector(std::initializer_list<T> list) PackedVector(std::initializer_list<T> list)
{ {
initialize();
reserve(list.size()); reserve(list.size());
for (const auto value : list) for (const auto value : list)
push_back(value); push_back(value);
} }
PackedVector(){}; PackedVector() { initialize(); };
PackedVector(const PackedVector &) = default; PackedVector(const PackedVector &) = default;
PackedVector(PackedVector &&) = default; PackedVector(PackedVector &&) = default;
PackedVector &operator=(const PackedVector &) = default; PackedVector &operator=(const PackedVector &) = default;
PackedVector &operator=(PackedVector &&) = default; PackedVector &operator=(PackedVector &&) = default;
PackedVector(std::size_t size) { resize(size); } PackedVector(std::size_t size)
{
initialize();
resize(size);
}
PackedVector(std::size_t size, T initial_value) PackedVector(std::size_t size, T initial_value)
{ {
initialize();
resize(size); resize(size);
fill(initial_value); fill(initial_value);
} }
@@ -386,6 +406,7 @@ template <typename T, std::size_t Bits, storage::Ownership Ownership> class Pack
PackedVector(util::ViewOrVector<WordT, Ownership> vec_, std::size_t num_elements) PackedVector(util::ViewOrVector<WordT, Ownership> vec_, std::size_t num_elements)
: vec(std::move(vec_)), num_elements(num_elements) : vec(std::move(vec_)), num_elements(num_elements)
{ {
initialize();
} }
// forces the efficient read-only lookup // forces the efficient read-only lookup
+2 -2
View File
@@ -10,9 +10,9 @@ namespace osrm::util
namespace permutation_detail namespace permutation_detail
{ {
template <typename T> static inline void swap(T &a, T &b) noexcept { std::swap(a, b); } template <typename T> static inline void swap(T &a, T &b) { std::swap(a, b); }
static inline void swap(std::vector<bool>::reference a, std::vector<bool>::reference b) noexcept static inline void swap(std::vector<bool>::reference a, std::vector<bool>::reference b)
{ {
std::vector<bool>::swap(a, b); std::vector<bool>::swap(a, b);
} }
+8 -21
View File
@@ -193,20 +193,7 @@ template <typename NodeID,
class QueryHeap class QueryHeap
{ {
private: private:
struct HeapData using HeapData = std::pair<Weight, Key>;
{
Weight weight;
Key index;
bool operator>(const HeapData &other) const
{
if (weight == other.weight)
{
return index > other.index;
}
return weight > other.weight;
}
};
using HeapContainer = boost::heap::d_ary_heap<HeapData, using HeapContainer = boost::heap::d_ary_heap<HeapData,
boost::heap::arity<4>, boost::heap::arity<4>,
boost::heap::mutable_<true>, boost::heap::mutable_<true>,
@@ -245,7 +232,7 @@ class QueryHeap
{ {
BOOST_ASSERT(node < std::numeric_limits<NodeID>::max()); BOOST_ASSERT(node < std::numeric_limits<NodeID>::max());
const auto index = static_cast<Key>(inserted_nodes.size()); const auto index = static_cast<Key>(inserted_nodes.size());
const auto handle = heap.emplace(HeapData{weight, index}); const auto handle = heap.push(std::make_pair(weight, index));
inserted_nodes.emplace_back(HeapNode{handle, node, weight, data}); inserted_nodes.emplace_back(HeapNode{handle, node, weight, data});
node_index[node] = index; node_index[node] = index;
} }
@@ -328,19 +315,19 @@ class QueryHeap
NodeID Min() const NodeID Min() const
{ {
BOOST_ASSERT(!heap.empty()); BOOST_ASSERT(!heap.empty());
return inserted_nodes[heap.top().index].node; return inserted_nodes[heap.top().second].node;
} }
Weight MinKey() const Weight MinKey() const
{ {
BOOST_ASSERT(!heap.empty()); BOOST_ASSERT(!heap.empty());
return heap.top().weight; return heap.top().first;
} }
NodeID DeleteMin() NodeID DeleteMin()
{ {
BOOST_ASSERT(!heap.empty()); BOOST_ASSERT(!heap.empty());
const Key removedIndex = heap.top().index; const Key removedIndex = heap.top().second;
heap.pop(); heap.pop();
inserted_nodes[removedIndex].handle = heap.s_handle_from_iterator(heap.end()); inserted_nodes[removedIndex].handle = heap.s_handle_from_iterator(heap.end());
return inserted_nodes[removedIndex].node; return inserted_nodes[removedIndex].node;
@@ -349,7 +336,7 @@ class QueryHeap
HeapNode &DeleteMinGetHeapNode() HeapNode &DeleteMinGetHeapNode()
{ {
BOOST_ASSERT(!heap.empty()); BOOST_ASSERT(!heap.empty());
const Key removedIndex = heap.top().index; const Key removedIndex = heap.top().second;
heap.pop(); heap.pop();
inserted_nodes[removedIndex].handle = heap.s_handle_from_iterator(heap.end()); inserted_nodes[removedIndex].handle = heap.s_handle_from_iterator(heap.end());
return inserted_nodes[removedIndex]; return inserted_nodes[removedIndex];
@@ -370,13 +357,13 @@ class QueryHeap
const auto index = node_index.peek_index(node); const auto index = node_index.peek_index(node);
auto &reference = inserted_nodes[index]; auto &reference = inserted_nodes[index];
reference.weight = weight; reference.weight = weight;
heap.increase(reference.handle, HeapData{weight, static_cast<Key>(index)}); heap.increase(reference.handle, std::make_pair(weight, index));
} }
void DecreaseKey(const HeapNode &heapNode) void DecreaseKey(const HeapNode &heapNode)
{ {
BOOST_ASSERT(!WasRemoved(heapNode.node)); BOOST_ASSERT(!WasRemoved(heapNode.node));
heap.increase(heapNode.handle, HeapData{heapNode.weight, (*heapNode.handle).index}); heap.increase(heapNode.handle, std::make_pair(heapNode.weight, (*heapNode.handle).second));
} }
private: private:
+3 -3
View File
@@ -1,7 +1,6 @@
#ifndef OSRM_STATIC_ASSERT_HPP #ifndef OSRM_STATIC_ASSERT_HPP
#define OSRM_STATIC_ASSERT_HPP #define OSRM_STATIC_ASSERT_HPP
#include <iterator>
#include <type_traits> #include <type_traits>
namespace osrm::util namespace osrm::util
@@ -9,13 +8,14 @@ namespace osrm::util
template <typename It, typename Value> inline void static_assert_iter_value() template <typename It, typename Value> inline void static_assert_iter_value()
{ {
static_assert(std::is_same_v<std::iter_value_t<It>, Value>, ""); using IterValueType = typename std::iterator_traits<It>::value_type;
static_assert(std::is_same<IterValueType, Value>::value, "");
} }
template <typename It, typename Category> inline void static_assert_iter_category() template <typename It, typename Category> inline void static_assert_iter_category()
{ {
using IterCategoryType = typename std::iterator_traits<It>::iterator_category; using IterCategoryType = typename std::iterator_traits<It>::iterator_category;
static_assert(std::is_base_of_v<Category, IterCategoryType>, ""); static_assert(std::is_base_of<Category, IterCategoryType>::value, "");
} }
} // namespace osrm::util } // namespace osrm::util
+1 -39
View File
@@ -1,11 +1,7 @@
#ifndef STD_HASH_HPP #ifndef STD_HASH_HPP
#define STD_HASH_HPP #define STD_HASH_HPP
#include <cstddef>
#include <functional> #include <functional>
#include <tuple>
#include <utility>
#include <vector>
// this is largely inspired by boost's hash combine as can be found in // this is largely inspired by boost's hash combine as can be found in
// "The C++ Standard Library" 2nd Edition. Nicolai M. Josuttis. 2012. // "The C++ Standard Library" 2nd Edition. Nicolai M. Josuttis. 2012.
@@ -15,14 +11,6 @@ template <typename T> void hash_combine(std::size_t &seed, const T &val)
seed ^= std::hash<T>()(val) + 0x9e3779b9 + (seed << 6) + (seed >> 2); seed ^= std::hash<T>()(val) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
} }
template <typename It> void hash_range(std::size_t &seed, It first, const It last)
{
for (; first != last; ++first)
{
hash_combine(seed, *first);
}
}
template <typename T> void hash_val(std::size_t &seed, const T &val) { hash_combine(seed, val); } template <typename T> void hash_val(std::size_t &seed, const T &val) { hash_combine(seed, val); }
template <typename T, typename... Types> template <typename T, typename... Types>
@@ -41,39 +29,13 @@ template <typename... Types> std::size_t hash_val(const Types &...args)
namespace std namespace std
{ {
template <typename... T> struct hash<std::tuple<T...>>
{
template <std::size_t... I>
static auto apply_tuple(const std::tuple<T...> &t, std::index_sequence<I...>)
{
std::size_t seed = 0;
return ((seed = hash_val(std::get<I>(t), seed)), ...);
}
auto operator()(const std::tuple<T...> &t) const
{
return apply_tuple(t, std::make_index_sequence<sizeof...(T)>());
}
};
template <typename T1, typename T2> struct hash<std::pair<T1, T2>> template <typename T1, typename T2> struct hash<std::pair<T1, T2>>
{ {
std::size_t operator()(const std::pair<T1, T2> &pair) const size_t operator()(const std::pair<T1, T2> &pair) const
{ {
return hash_val(pair.first, pair.second); return hash_val(pair.first, pair.second);
} }
}; };
template <typename T> struct hash<std::vector<T>>
{
auto operator()(const std::vector<T> &lane_description) const
{
std::size_t seed = 0;
hash_range(seed, lane_description.begin(), lane_description.end());
return seed;
}
};
} // namespace std } // namespace std
#endif // STD_HASH_HPP #endif // STD_HASH_HPP
+59 -17
View File
@@ -1,9 +1,8 @@
#ifndef STRING_UTIL_HPP #ifndef STRING_UTIL_HPP
#define STRING_UTIL_HPP #define STRING_UTIL_HPP
#include <array>
#include <cctype> #include <cctype>
#include <cstddef>
#include <random> #include <random>
#include <string> #include <string>
#include <vector> #include <vector>
@@ -11,30 +10,73 @@
namespace osrm::util namespace osrm::util
{ {
// implements Lemire's table-based escape needs check // precision: position after decimal point
// cf. https://lemire.me/blog/2024/05/31/quickly-checking-whether-a-string-needs-escaping/ // length: maximum number of digits including comma and decimals
inline static constexpr std::array<uint8_t, 256> json_quotable_character = []() constexpr // work with negative values to prevent overflowing when taking -value
template <int length, int precision> char *printInt(char *buffer, int value)
{ {
std::array<uint8_t, 256> result{}; static_assert(length > 0, "length must be positive");
for (auto i = 0; i < 32; i++) static_assert(precision > 0, "precision must be positive");
const bool minus = [&value]
{ {
result[i] = 1; if (value >= 0)
} {
for (auto i : {'"', '\\'}) value = -value;
return false;
}
return true;
}();
buffer += length - 1;
for (int i = 0; i < precision; ++i)
{ {
result[i] = 1; *buffer = '0' - (value % 10);
value /= 10;
--buffer;
} }
return result; *buffer = '.';
}(); --buffer;
for (int i = precision + 1; i < length; ++i)
{
*buffer = '0' - (value % 10);
value /= 10;
if (value == 0)
{
break;
}
--buffer;
}
if (minus)
{
--buffer;
*buffer = '-';
}
return buffer;
}
inline bool RequiresJSONStringEscaping(const std::string &string) inline bool RequiresJSONStringEscaping(const std::string &string)
{ {
uint8_t needs = 0; for (const char letter : string)
for (uint8_t c : string)
{ {
needs |= json_quotable_character[c]; switch (letter)
{
case '\\':
case '"':
case '/':
case '\b':
case '\f':
case '\n':
case '\r':
case '\t':
return true;
default:
continue;
}
} }
return needs; return false;
} }
inline void EscapeJSONString(const std::string &input, std::string &output) inline void EscapeJSONString(const std::string &input, std::string &output)
+16 -11
View File
@@ -6,7 +6,7 @@
#include <limits> #include <limits>
#include <numbers> #include <boost/math/constants/constants.hpp>
namespace osrm::util namespace osrm::util
{ {
@@ -356,21 +356,26 @@ constexpr unsigned short atan_table[4096] = {
0xffe0, 0xffea, 0xfff4, 0xffff}; 0xffe0, 0xffea, 0xfff4, 0xffff};
// max value is pi/4 // max value is pi/4
const constexpr double SCALING_FACTOR = 4. * std::numbers::inv_pi * 0xFFFF; #ifdef _MSC_VER // TODO: remove as soon as boost allows C++14 features with Visual Studio
const constexpr double SCALING_FACTOR = 4. / M_PI * 0xFFFF;
#else
const constexpr double SCALING_FACTOR = 4. / boost::math::constants::pi<double>() * 0xFFFF;
#endif
inline double atan2_lookup(double y, double x) inline double atan2_lookup(double y, double x)
{ {
static constexpr auto half_pi = std::numbers::pi * 0.5;
using namespace boost::math::constants;
if (std::abs(x) < std::numeric_limits<double>::epsilon()) if (std::abs(x) < std::numeric_limits<double>::epsilon())
{ {
if (y >= 0.) if (y >= 0.)
{ {
return half_pi; return half_pi<double>();
} }
else else
{ {
return -half_pi; return -half_pi<double>();
} }
} }
@@ -401,25 +406,25 @@ inline double atan2_lookup(double y, double x)
case 0: case 0:
break; break;
case 1: case 1:
angle = std::numbers::pi - angle; angle = pi<double>() - angle;
break; break;
case 2: case 2:
angle = -angle; angle = -angle;
break; break;
case 3: case 3:
angle = -std::numbers::pi + angle; angle = -pi<double>() + angle;
break; break;
case 4: case 4:
angle = half_pi - angle; angle = half_pi<double>() - angle;
break; break;
case 5: case 5:
angle = half_pi + angle; angle = half_pi<double>() + angle;
break; break;
case 6: case 6:
angle = -half_pi + angle; angle = -half_pi<double>() + angle;
break; break;
case 7: case 7:
angle = -half_pi - angle; angle = -half_pi<double>() - angle;
break; break;
} }
return angle; return angle;
+4 -4
View File
@@ -3,7 +3,7 @@
#include "util/coordinate.hpp" #include "util/coordinate.hpp"
#include <numbers> #include <boost/math/constants/constants.hpp>
namespace osrm::util::web_mercator namespace osrm::util::web_mercator
{ {
@@ -14,7 +14,7 @@ const constexpr double RAD_TO_DEGREE = 1. / DEGREE_TO_RAD;
// radius used by WGS84 // radius used by WGS84
const constexpr double EARTH_RADIUS_WGS84 = 6378137.0; const constexpr double EARTH_RADIUS_WGS84 = 6378137.0;
// earth circumference devided by 2 // earth circumference devided by 2
const constexpr double MAXEXTENT = EARTH_RADIUS_WGS84 * std::numbers::pi; const constexpr double MAXEXTENT = EARTH_RADIUS_WGS84 * boost::math::constants::pi<double>();
// ^ math functions are not constexpr since they have side-effects (setting errno) :( // ^ math functions are not constexpr since they have side-effects (setting errno) :(
const constexpr double EPSG3857_MAX_LATITUDE = 85.051128779806592378; // 90(4*atan(exp(pi))/pi-1) const constexpr double EPSG3857_MAX_LATITUDE = 85.051128779806592378; // 90(4*atan(exp(pi))/pi-1)
const constexpr double MAX_LONGITUDE = 180.0; const constexpr double MAX_LONGITUDE = 180.0;
@@ -103,8 +103,8 @@ inline void pixelToDegree(const double shift, double &x, double &y)
const double b = shift / 2.0; const double b = shift / 2.0;
x = (x - b) / shift * 360.0; x = (x - b) / shift * 360.0;
// FIXME needs to be simplified // FIXME needs to be simplified
const double g = (y - b) / -(shift * 0.5 * std::numbers::inv_pi) / detail::DEGREE_TO_RAD; const double g = (y - b) / -(shift / (2 * M_PI)) / detail::DEGREE_TO_RAD;
static_assert(detail::DEGREE_TO_RAD * 0.5 * std::numbers::inv_pi - 1 / 360. < 0.0001, ""); static_assert(detail::DEGREE_TO_RAD / (2 * M_PI) - 1 / 360. < 0.0001, "");
y = static_cast<double>(yToLat(g)); y = static_cast<double>(yToLat(g));
} }
-90
View File
@@ -1,90 +0,0 @@
import requests
import xml.etree.ElementTree as ET
import csv
import sys
import argparse
def get_osm_gps_traces(bboxes):
url = 'https://api.openstreetmap.org/api/0.6/trackpoints'
traces = []
lon_step = 0.25
lat_step = 0.25
for bbox in bboxes:
min_lon, min_lat, max_lon, max_lat = map(float, bbox.split(','))
current_min_lon = min_lon
while current_min_lon < max_lon:
current_max_lon = min(current_min_lon + lon_step, max_lon)
current_min_lat = min_lat
while current_min_lat < max_lat:
current_max_lat = min(current_min_lat + lat_step, max_lat)
bbox_str = f'{current_min_lon},{current_min_lat},{current_max_lon},{current_max_lat}'
print(f"Requesting bbox: {bbox_str}", file=sys.stderr)
params = {
'bbox': bbox_str,
'page': 0
}
headers = {
'Accept': 'application/xml'
}
response = requests.get(url, params=params, headers=headers)
if response.status_code == 200:
traces.append(response.content)
else:
print(f"Error fetching data for bbox {bbox_str}: {response.status_code} {response.text}", file=sys.stderr)
current_min_lat += lat_step
current_min_lon += lon_step
return traces
def parse_gpx_data(gpx_data):
try:
root = ET.fromstring(gpx_data)
except ET.ParseError as e:
print(f"Error parsing GPX data: {e}", file=sys.stderr)
return []
namespace = {'gpx': 'http://www.topografix.com/GPX/1/0'}
tracks = []
for trk in root.findall('.//gpx:trk', namespace):
track_data = []
for trkseg in trk.findall('.//gpx:trkseg', namespace):
for trkpt in trkseg.findall('gpx:trkpt', namespace):
lat = trkpt.get('lat')
lon = trkpt.get('lon')
time = trkpt.find('time').text if trkpt.find('time') is not None else ''
track_data.append([lat, lon, time])
tracks.append(track_data)
return tracks
def save_to_csv(data, file):
writer = csv.writer(file)
writer.writerow(['TrackID', 'Latitude', 'Longitude', 'Time'])
writer.writerows(data)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Fetch and output OSM GPS traces for given bounding boxes.')
parser.add_argument('bboxes', nargs='+', help='Bounding boxes in the format min_lon,min_lat,max_lon,max_lat')
args = parser.parse_args()
gpx_data_traces = get_osm_gps_traces(args.bboxes)
print(f"Collected {len(gpx_data_traces)} trace segments", file=sys.stderr)
all_data = []
track_id = 0
for gpx_data in gpx_data_traces:
for track in parse_gpx_data(gpx_data):
for point in track:
all_data.append([track_id] + point)
track_id += 1
# Output all data to stdout
save_to_csv(all_data, sys.stdout)
-102
View File
@@ -1,102 +0,0 @@
import requests
import sys
import random
from collections import defaultdict
import os
import csv
import numpy as np
import time
import argparse
class BenchmarkRunner:
def __init__(self):
self.coordinates = []
self.tracks = defaultdict(list)
gps_traces_file_path = os.path.expanduser('~/gps_traces.csv')
with open(gps_traces_file_path, 'r') as file:
reader = csv.DictReader(file)
for row in reader:
coord = (float(row['Latitude']), float(row['Longitude']))
self.coordinates.append(coord)
self.tracks[row['TrackID']].append(coord)
self.track_ids = list(self.tracks.keys())
def run(self, benchmark_name, host, num_requests, warmup_requests=50):
for _ in range(warmup_requests):
url = self.make_url(host, benchmark_name)
_ = requests.get(url)
times = []
for _ in range(num_requests):
url = self.make_url(host, benchmark_name)
start_time = time.time()
response = requests.get(url)
end_time = time.time()
if response.status_code != 200:
if benchmark_name == 'match':
code = response.json()['code']
if code == 'NoSegment' or code == 'NoMatch':
continue
raise Exception(f"Error: {response.status_code} {response.text}")
times.append((end_time - start_time) * 1000) # convert to ms
return times
def make_url(self, host, benchmark_name):
if benchmark_name == 'route':
start = random.choice(self.coordinates)
end = random.choice(self.coordinates)
start_coord = f"{start[1]:.6f},{start[0]:.6f}"
end_coord = f"{end[1]:.6f},{end[0]:.6f}"
return f"{host}/route/v1/driving/{start_coord};{end_coord}?overview=full&steps=true"
elif benchmark_name == 'table':
num_coords = random.randint(3, 100)
selected_coords = random.sample(self.coordinates, num_coords)
coords_str = ";".join([f"{coord[1]:.6f},{coord[0]:.6f}" for coord in selected_coords])
return f"{host}/table/v1/driving/{coords_str}"
elif benchmark_name == 'match':
num_coords = random.randint(50, 100)
track_id = random.choice(self.track_ids)
track_coords = self.tracks[track_id][:num_coords]
coords_str = ";".join([f"{coord[1]:.6f},{coord[0]:.6f}" for coord in track_coords])
radiues_str = ";".join([f"{random.randint(5, 20)}" for _ in range(len(track_coords))])
return f"{host}/match/v1/driving/{coords_str}?steps=true&radiuses={radiues_str}"
elif benchmark_name == 'nearest':
coord = random.choice(self.coordinates)
coord_str = f"{coord[1]:.6f},{coord[0]:.6f}"
return f"{host}/nearest/v1/driving/{coord_str}"
elif benchmark_name == 'trip':
num_coords = random.randint(2, 10)
selected_coords = random.sample(self.coordinates, num_coords)
coords_str = ";".join([f"{coord[1]:.6f},{coord[0]:.6f}" for coord in selected_coords])
return f"{host}/trip/v1/driving/{coords_str}?steps=true"
else:
raise Exception(f"Unknown benchmark: {benchmark_name}")
def main():
parser = argparse.ArgumentParser(description='Run GPS benchmark tests.')
parser.add_argument('--host', type=str, required=True, help='Host URL')
parser.add_argument('--method', type=str, required=True, choices=['route', 'table', 'match', 'nearest', 'trip'], help='Benchmark method')
parser.add_argument('--num_requests', type=int, required=True, help='Number of requests to perform')
args = parser.parse_args()
random.seed(42)
runner = BenchmarkRunner()
times = runner.run(args.method, args.host, args.num_requests)
print(f'Total: {np.sum(times)}ms')
print(f"Min time: {np.min(times)}ms")
print(f"Mean time: {np.mean(times)}ms")
print(f"Median time: {np.median(times)}ms")
print(f"95th percentile: {np.percentile(times, 95)}ms")
print(f"99th percentile: {np.percentile(times, 99)}ms")
print(f"Max time: {np.max(times)}ms")
if __name__ == '__main__':
main()
+3 -12
View File
@@ -16,10 +16,8 @@ def create_markdown_table(results):
rows = [] rows = []
for result in results: for result in results:
name = result['name'] name = result['name']
base = result['base'] or '' base = result['base'].replace('\n', '<br/>')
base = base.replace('\n', '<br/>') pr = result['pr'].replace('\n', '<br/>')
pr = result['pr'] or ''
pr = pr.replace('\n', '<br/>')
row = f"| {name} | {base} | {pr} |" row = f"| {name} | {base} | {pr} |"
rows.append(row) rows.append(row)
return f"{header}\n" + "\n".join(rows) return f"{header}\n" + "\n".join(rows)
@@ -77,14 +75,7 @@ def main():
pr_body = pr_details.get('body', '') or '' pr_body = pr_details.get('body', '') or ''
markdown_table = create_markdown_table(benchmark_results) markdown_table = create_markdown_table(benchmark_results)
new_benchmark_section = f""" new_benchmark_section = f"<!-- BENCHMARK_RESULTS_START -->\n## Benchmark Results\n{markdown_table}\n<!-- BENCHMARK_RESULTS_END -->"
<!-- BENCHMARK_RESULTS_START -->
<details><summary><h2>Benchmark Results</h2></summary>
{markdown_table}
</details>
<!-- BENCHMARK_RESULTS_END -->
"""
if re.search(r'<!-- BENCHMARK_RESULTS_START -->.*<!-- BENCHMARK_RESULTS_END -->', pr_body, re.DOTALL): if re.search(r'<!-- BENCHMARK_RESULTS_START -->.*<!-- BENCHMARK_RESULTS_END -->', pr_body, re.DOTALL):
updated_body = re.sub( updated_body = re.sub(
+2 -50
View File
@@ -1,24 +1,11 @@
#!/bin/bash #!/bin/bash
set -eou pipefail set -eou pipefail
function measure_peak_ram_and_time {
COMMAND=$1
OUTPUT_FILE=$2
OUTPUT=$(/usr/bin/time -f "%e %M" $COMMAND 2>&1 | tail -n 1)
TIME=$(echo $OUTPUT | awk '{print $1}')
PEAK_RAM_KB=$(echo $OUTPUT | awk '{print $2}')
PEAK_RAM_MB=$(echo "scale=2; $PEAK_RAM_KB / 1024" | bc)
echo "Time: ${TIME}s Peak RAM: ${PEAK_RAM_MB}MB" > $OUTPUT_FILE
}
function run_benchmarks_for_folder { function run_benchmarks_for_folder {
echo "Running benchmarks for $1" echo "Running benchmarks for $1"
FOLDER=$1 FOLDER=$1
RESULTS_FOLDER=$2 RESULTS_FOLDER=$2
SCRIPTS_FOLDER=$3
mkdir -p $RESULTS_FOLDER mkdir -p $RESULTS_FOLDER
@@ -26,47 +13,12 @@ function run_benchmarks_for_folder {
./$BENCHMARKS_FOLDER/match-bench "./$FOLDER/test/data/mld/monaco.osrm" mld > "$RESULTS_FOLDER/match_mld.bench" ./$BENCHMARKS_FOLDER/match-bench "./$FOLDER/test/data/mld/monaco.osrm" mld > "$RESULTS_FOLDER/match_mld.bench"
./$BENCHMARKS_FOLDER/match-bench "./$FOLDER/test/data/ch/monaco.osrm" ch > "$RESULTS_FOLDER/match_ch.bench" ./$BENCHMARKS_FOLDER/match-bench "./$FOLDER/test/data/ch/monaco.osrm" ch > "$RESULTS_FOLDER/match_ch.bench"
./$BENCHMARKS_FOLDER/route-bench "./$FOLDER/test/data/mld/monaco.osrm" mld > "$RESULTS_FOLDER/route_mld.bench"
./$BENCHMARKS_FOLDER/route-bench "./$FOLDER/test/data/ch/monaco.osrm" ch > "$RESULTS_FOLDER/route_ch.bench"
./$BENCHMARKS_FOLDER/alias-bench > "$RESULTS_FOLDER/alias.bench" ./$BENCHMARKS_FOLDER/alias-bench > "$RESULTS_FOLDER/alias.bench"
./$BENCHMARKS_FOLDER/json-render-bench "./$FOLDER/src/benchmarks/portugal_to_korea.json" > "$RESULTS_FOLDER/json-render.bench" ./$BENCHMARKS_FOLDER/json-render-bench "./$FOLDER/src/benchmarks/portugal_to_korea.json" > "$RESULTS_FOLDER/json-render.bench"
./$BENCHMARKS_FOLDER/packedvector-bench > "$RESULTS_FOLDER/packedvector.bench" ./$BENCHMARKS_FOLDER/packedvector-bench > "$RESULTS_FOLDER/packedvector.bench"
./$BENCHMARKS_FOLDER/rtree-bench "./$FOLDER/test/data/monaco.osrm.ramIndex" "./$FOLDER/test/data/monaco.osrm.fileIndex" "./$FOLDER/test/data/monaco.osrm.nbg_nodes" > "$RESULTS_FOLDER/rtree.bench" ./$BENCHMARKS_FOLDER/rtree-bench "./$FOLDER/test/data/monaco.osrm.ramIndex" "./$FOLDER/test/data/monaco.osrm.fileIndex" "./$FOLDER/test/data/monaco.osrm.nbg_nodes" > "$RESULTS_FOLDER/rtree.bench"
BINARIES_FOLDER="$FOLDER/build"
cp ~/data.osm.pbf $FOLDER
measure_peak_ram_and_time "$BINARIES_FOLDER/osrm-extract -p $FOLDER/profiles/car.lua $FOLDER/data.osm.pbf" "$RESULTS_FOLDER/osrm_extract.bench"
measure_peak_ram_and_time "$BINARIES_FOLDER/osrm-partition $FOLDER/data.osrm" "$RESULTS_FOLDER/osrm_partition.bench"
measure_peak_ram_and_time "$BINARIES_FOLDER/osrm-customize $FOLDER/data.osrm" "$RESULTS_FOLDER/osrm_customize.bench"
measure_peak_ram_and_time "$BINARIES_FOLDER/osrm-contract $FOLDER/data.osrm" "$RESULTS_FOLDER/osrm_contract.bench"
for BENCH in nearest table trip route match; do
./$BENCHMARKS_FOLDER/bench "$FOLDER/data.osrm" mld ~/gps_traces.csv ${BENCH} > "$RESULTS_FOLDER/random_${BENCH}_mld.bench" || true
./$BENCHMARKS_FOLDER/bench "$FOLDER/data.osrm" ch ~/gps_traces.csv ${BENCH} > "$RESULTS_FOLDER/random_${BENCH}_ch.bench" || true
done
for ALGORITHM in ch mld; do
$BINARIES_FOLDER/osrm-routed --algorithm $ALGORITHM $FOLDER/data.osrm &
OSRM_ROUTED_PID=$!
# wait for osrm-routed to start
if ! curl --retry-delay 3 --retry 10 --retry-all-errors "http://127.0.0.1:5000/route/v1/driving/13.388860,52.517037;13.385983,52.496891?steps=true"; then
echo "osrm-routed failed to start for algorithm $ALGORITHM"
kill -9 $OSRM_ROUTED_PID
continue
fi
for METHOD in route nearest trip table match; do
python3 $SCRIPTS_FOLDER/scripts/ci/e2e_benchmark.py --host http://localhost:5000 --method $METHOD --num_requests 1000 > $RESULTS_FOLDER/e2e_${METHOD}_${ALGORITHM}.bench
done
kill -9 $OSRM_ROUTED_PID
done
} }
run_benchmarks_for_folder $1 "${1}_results" $2 run_benchmarks_for_folder $1 "${1}_results"
run_benchmarks_for_folder $2 "${2}_results" $2 run_benchmarks_for_folder $2 "${2}_results"
+95
View File
@@ -0,0 +1,95 @@
@ECHO OFF
SETLOCAL
SET EL=0
ECHO NUMBER_OF_PROCESSORS^: %NUMBER_OF_PROCESSORS%
SET PROJECT_DIR=%CD%
SET CONFIGURATION=Release
mkdir build
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
cd build
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
cmake -DENABLE_CONAN=ON -DENABLE_NODE_BINDINGS=ON -DCMAKE_BUILD_TYPE=%CONFIGURATION% -G "Visual Studio 17 2022" ..
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
msbuild OSRM.sln ^
/p:Configuration=%CONFIGURATION% ^
/p:Platform=x64 ^
/t:rebuild ^
/p:BuildInParallel=true ^
/m:%NUMBER_OF_PROCESSORS% ^
/toolsversion:Current ^
/clp:Verbosity=quiet ^
/nologo
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
CD %PROJECT_DIR%\build
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
ECHO running extractor-tests.exe ...
unit_tests\%CONFIGURATION%\extractor-tests.exe
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
ECHO running contractor-tests.exe ...
unit_tests\%CONFIGURATION%\contractor-tests.exe
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
ECHO running engine-tests.exe ...
unit_tests\%CONFIGURATION%\engine-tests.exe
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
ECHO running util-tests.exe ...
unit_tests\%CONFIGURATION%\util-tests.exe
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
ECHO running server-tests.exe ...
unit_tests\%CONFIGURATION%\server-tests.exe
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
ECHO running partitioner-tests.exe ...
unit_tests\%CONFIGURATION%\partitioner-tests.exe
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
ECHO running customizer-tests.exe ...
unit_tests\%CONFIGURATION%\customizer-tests.exe
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
SET test_region=monaco
SET test_region_ch=ch\monaco
SET test_region_corech=corech\monaco
SET test_region_mld=mld\monaco
SET test_osm=%test_region%.osm.pbf
COPY %PROJECT_DIR%\test\data\%test_region%.osm.pbf %test_osm%
%CONFIGURATION%\osrm-extract.exe -p %PROJECT_DIR%\profiles\car.lua %test_osm%
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
MKDIR ch
XCOPY %test_region%.osrm.* ch\
XCOPY %test_region%.osrm ch\
MKDIR corech
XCOPY %test_region%.osrm.* corech\
XCOPY %test_region%.osrm corech\
MKDIR mld
XCOPY %test_region%.osrm.* mld\
XCOPY %test_region%.osrm mld\
%CONFIGURATION%\osrm-contract.exe %test_region_ch%.osrm
%CONFIGURATION%\osrm-contract.exe --core 0.8 %test_region_corech%.osrm
%CONFIGURATION%\osrm-partition.exe %test_region_mld%.osrm
%CONFIGURATION%\osrm-customize.exe %test_region_mld%.osrm
XCOPY /Y ch\*.* ..\test\data\ch\
XCOPY /Y corech\*.* ..\test\data\corech\
XCOPY /Y mld\*.* ..\test\data\mld\
unit_tests\%CONFIGURATION%\library-tests.exe
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
:ERROR
ECHO ~~~~~~~~~~~~~~~~~~~~~~ ERROR %~f0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ECHO ERRORLEVEL^: %ERRORLEVEL%
SET EL=%ERRORLEVEL%
:DONE
ECHO ~~~~~~~~~~~~~~~~~~~~~~ DONE %~f0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
EXIT /b %EL%
+7 -4
View File
@@ -12,11 +12,14 @@ set -o nounset
OSMIUM_PATH="osmcode/libosmium" OSMIUM_PATH="osmcode/libosmium"
OSMIUM_TAG=v2.14.0 OSMIUM_TAG=v2.14.0
VARIANT_PATH="mapbox/variant"
VARIANT_TAG=v1.1.3
SOL_PATH="ThePhD/sol2" SOL_PATH="ThePhD/sol2"
SOL_TAG=v3.3.0 SOL_TAG=v2.17.5
RAPIDJSON_PATH="Tencent/rapidjson" RAPIDJSON_PATH="Tencent/rapidjson"
RAPIDJSON_TAG=f9d53419e912910fd8fa57d5705fa41425428c35 RAPIDJSON_TAG=v1.1.0
MICROTAR_PATH="rxi/microtar" MICROTAR_PATH="rxi/microtar"
MICROTAR_TAG=v0.1.0 MICROTAR_TAG=v0.1.0
@@ -31,7 +34,7 @@ FMT_PATH="fmtlib/fmt"
FMT_TAG=v10.2.1 FMT_TAG=v10.2.1
function update_subtree () { function update_subtree () {
name=$(echo "$1" | tr '[:lower:]' '[:upper:]') name=${1^^}
path=$(tmpvar=${name}_PATH && echo ${!tmpvar}) path=$(tmpvar=${name}_PATH && echo ${!tmpvar})
tag=$(tmpvar=${name}_TAG && echo ${!tmpvar}) tag=$(tmpvar=${name}_TAG && echo ${!tmpvar})
dir=$(basename $path) dir=$(basename $path)
@@ -53,6 +56,6 @@ function update_subtree () {
} }
## Update dependencies ## Update dependencies
for dep in osmium sol rapidjson microtar protozero vtzero fmt; do for dep in osmium variant sol rapidjson microtar protozero vtzero fmt; do
update_subtree $dep update_subtree $dep
done done
+1 -29
View File
@@ -18,7 +18,6 @@ target_link_libraries(rtree-bench
${TBB_LIBRARIES} ${TBB_LIBRARIES}
${MAYBE_SHAPEFILE}) ${MAYBE_SHAPEFILE})
add_executable(match-bench add_executable(match-bench
EXCLUDE_FROM_ALL EXCLUDE_FROM_ALL
${MatchBenchmarkSources} ${MatchBenchmarkSources}
@@ -31,31 +30,6 @@ target_link_libraries(match-bench
${TBB_LIBRARIES} ${TBB_LIBRARIES}
${MAYBE_SHAPEFILE}) ${MAYBE_SHAPEFILE})
add_executable(route-bench
EXCLUDE_FROM_ALL
route.cpp
$<TARGET_OBJECTS:UTIL>)
target_link_libraries(route-bench
osrm
${BOOST_BASE_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
${TBB_LIBRARIES}
${MAYBE_SHAPEFILE})
add_executable(bench
EXCLUDE_FROM_ALL
bench.cpp
$<TARGET_OBJECTS:UTIL>)
target_link_libraries(bench
osrm
${BOOST_BASE_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
${TBB_LIBRARIES}
${MAYBE_SHAPEFILE})
add_executable(json-render-bench add_executable(json-render-bench
EXCLUDE_FROM_ALL EXCLUDE_FROM_ALL
json_render.cpp json_render.cpp
@@ -98,7 +72,5 @@ add_custom_target(benchmarks
rtree-bench rtree-bench
packedvector-bench packedvector-bench
match-bench match-bench
route-bench
bench
json-render-bench json-render-bench
alias-bench) alias-bench)
-1
View File
@@ -5,7 +5,6 @@
#include <algorithm> #include <algorithm>
#include <iomanip> #include <iomanip>
#include <iostream>
#include <numeric> #include <numeric>
#include <random> #include <random>
#include <string> #include <string>
-573
View File
@@ -1,573 +0,0 @@
#include "osrm/match_parameters.hpp"
#include "osrm/nearest_parameters.hpp"
#include "osrm/table_parameters.hpp"
#include "osrm/trip_parameters.hpp"
#include "engine/engine_config.hpp"
#include "util/coordinate.hpp"
#include "util/timing_util.hpp"
#include "osrm/route_parameters.hpp"
#include "osrm/coordinate.hpp"
#include "osrm/engine_config.hpp"
#include "osrm/json_container.hpp"
#include "osrm/osrm.hpp"
#include "osrm/status.hpp"
#include <boost/assert.hpp>
#include <boost/optional/optional.hpp>
#include <cstdlib>
#include <exception>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <optional>
#include <ostream>
#include <random>
#include <stdexcept>
#include <string>
#include <unordered_map>
#include <vector>
using namespace osrm;
namespace
{
class GPSTraces
{
private:
std::set<int> trackIDs;
std::unordered_map<int /* track id */, std::vector<osrm::util::Coordinate>> traces;
std::vector<osrm::util::Coordinate> coordinates;
mutable std::mt19937 gen;
public:
GPSTraces(int seed) : gen(std::random_device{}()) { gen.seed(seed); }
bool readCSV(const std::string &filename)
{
std::ifstream file(filename);
if (!file.is_open())
{
std::cerr << "Error opening file: " << filename << std::endl;
return false;
}
std::string line;
std::getline(file, line);
while (std::getline(file, line))
{
std::istringstream ss(line);
std::string token;
int trackID;
double latitude, longitude;
std::string time;
std::getline(ss, token, ',');
trackID = std::stoi(token);
std::getline(ss, token, ',');
latitude = std::stod(token);
std::getline(ss, token, ',');
longitude = std::stod(token);
// handle empty fields
if (std::getline(ss, token, ','))
{
time = token;
}
trackIDs.insert(trackID);
traces[trackID].emplace_back(osrm::util::Coordinate{
osrm::util::FloatLongitude{longitude}, osrm::util::FloatLatitude{latitude}});
coordinates.emplace_back(osrm::util::Coordinate{osrm::util::FloatLongitude{longitude},
osrm::util::FloatLatitude{latitude}});
}
file.close();
return true;
}
const osrm::util::Coordinate &getRandomCoordinate() const
{
std::uniform_int_distribution<> dis(0, coordinates.size() - 1);
return coordinates[dis(gen)];
}
const std::vector<osrm::util::Coordinate> &getRandomTrace() const
{
std::uniform_int_distribution<> dis(0, trackIDs.size() - 1);
auto it = trackIDs.begin();
std::advance(it, dis(gen));
return traces.at(*it);
}
};
class Statistics
{
public:
void push(double timeMs)
{
times.push_back(timeMs);
sorted = false;
}
double mean() { return sum() / times.size(); }
double sum()
{
double sum = 0;
for (auto time : times)
{
sum += time;
}
return sum;
}
double min() { return *std::min_element(times.begin(), times.end()); }
double max() { return *std::max_element(times.begin(), times.end()); }
double percentile(double p)
{
const auto &times = getTimes();
return times[static_cast<size_t>(p * times.size())];
}
private:
std::vector<double> getTimes()
{
if (!sorted)
{
std::sort(times.begin(), times.end());
sorted = true;
}
return times;
}
std::vector<double> times;
bool sorted = false;
};
std::ostream &operator<<(std::ostream &os, Statistics &statistics)
{
os << std::fixed << std::setprecision(2);
os << "total: " << statistics.sum() << "ms" << std::endl;
os << "avg: " << statistics.mean() << "ms" << std::endl;
os << "min: " << statistics.min() << "ms" << std::endl;
os << "max: " << statistics.max() << "ms" << std::endl;
os << "p99: " << statistics.percentile(0.99) << "ms" << std::endl;
return os;
}
void runRouteBenchmark(const OSRM &osrm, const GPSTraces &gpsTraces)
{
struct Benchmark
{
std::string name;
size_t coordinates;
RouteParameters::OverviewType overview;
bool steps = false;
std::optional<size_t> alternatives = std::nullopt;
std::optional<double> radius = std::nullopt;
};
auto run_benchmark = [&](const Benchmark &benchmark)
{
Statistics statistics;
auto NUM = 10000;
for (int i = 0; i < NUM; ++i)
{
RouteParameters params;
params.overview = benchmark.overview;
params.steps = benchmark.steps;
for (size_t i = 0; i < benchmark.coordinates; ++i)
{
params.coordinates.push_back(gpsTraces.getRandomCoordinate());
}
if (benchmark.alternatives)
{
params.alternatives = *benchmark.alternatives;
}
if (benchmark.radius)
{
params.radiuses = std::vector<boost::optional<double>>(
params.coordinates.size(), boost::make_optional(*benchmark.radius));
}
engine::api::ResultT result = json::Object();
TIMER_START(routes);
const auto rc = osrm.Route(params, result);
TIMER_STOP(routes);
statistics.push(TIMER_MSEC(routes));
auto &json_result = std::get<json::Object>(result);
if (rc != Status::Ok || json_result.values.find("routes") == json_result.values.end())
{
auto code = std::get<json::String>(json_result.values["code"]).value;
if (code != "NoSegment" && code != "NoRoute")
{
throw std::runtime_error{"Couldn't route: " + code};
}
}
}
std::cout << benchmark.name << std::endl;
std::cout << statistics << std::endl;
};
std::vector<Benchmark> benchmarks = {
{"10000 routes, 3 coordinates, no alternatives, overview=full, steps=true",
3,
RouteParameters::OverviewType::Full,
true,
std::nullopt},
{"10000 routes, 2 coordinates, no alternatives, overview=full, steps=true",
2,
RouteParameters::OverviewType::Full,
true,
std::nullopt},
{"10000 routes, 2 coordinates, 3 alternatives, overview=full, steps=true",
2,
RouteParameters::OverviewType::Full,
true,
3},
{"10000 routes, 3 coordinates, no alternatives, overview=false, steps=false",
3,
RouteParameters::OverviewType::False,
false,
std::nullopt},
{"10000 routes, 2 coordinates, no alternatives, overview=false, steps=false",
2,
RouteParameters::OverviewType::False,
false,
std::nullopt},
{"10000 routes, 2 coordinates, 3 alternatives, overview=false, steps=false",
2,
RouteParameters::OverviewType::False,
false,
3},
{"10000 routes, 3 coordinates, no alternatives, overview=false, steps=false, radius=750",
3,
RouteParameters::OverviewType::False,
false,
std::nullopt,
750},
{"10000 routes, 2 coordinates, no alternatives, overview=false, steps=false, radius=750",
2,
RouteParameters::OverviewType::False,
false,
std::nullopt,
750},
{"10000 routes, 2 coordinates, 3 alternatives, overview=false, steps=false, radius=750",
2,
RouteParameters::OverviewType::False,
false,
3,
750}
};
for (const auto &benchmark : benchmarks)
{
run_benchmark(benchmark);
}
}
void runMatchBenchmark(const OSRM &osrm, const GPSTraces &gpsTraces)
{
struct Benchmark
{
std::string name;
std::optional<size_t> radius = std::nullopt;
};
auto run_benchmark = [&](const Benchmark &benchmark)
{
Statistics statistics;
auto NUM = 1000;
for (int i = 0; i < NUM; ++i)
{
engine::api::ResultT result = json::Object();
engine::api::MatchParameters params;
params.coordinates = gpsTraces.getRandomTrace();
params.radiuses = {};
if (benchmark.radius)
{
for (size_t index = 0; index < params.coordinates.size(); ++index)
{
params.radiuses.emplace_back(*benchmark.radius);
}
}
TIMER_START(match);
const auto rc = osrm.Match(params, result);
TIMER_STOP(match);
statistics.push(TIMER_MSEC(match));
auto &json_result = std::get<json::Object>(result);
if (rc != Status::Ok ||
json_result.values.find("matchings") == json_result.values.end())
{
auto code = std::get<json::String>(json_result.values["code"]).value;
if (code != "NoSegment" && code != "NoMatch")
{
throw std::runtime_error{"Couldn't route: " + code};
}
}
}
std::cout << benchmark.name << std::endl;
std::cout << statistics << std::endl;
};
std::vector<Benchmark> benchmarks = {{"1000 matches, default radius"},
{"1000 matches, radius=10", 10},
{"1000 matches, radius=20", 20}};
for (const auto &benchmark : benchmarks)
{
run_benchmark(benchmark);
}
}
void runNearestBenchmark(const OSRM &osrm, const GPSTraces &gpsTraces)
{
struct Benchmark
{
std::string name;
std::optional<size_t> number_of_results = std::nullopt;
};
auto run_benchmark = [&](const Benchmark &benchmark)
{
Statistics statistics;
auto NUM = 10000;
for (int i = 0; i < NUM; ++i)
{
engine::api::ResultT result = json::Object();
NearestParameters params;
params.coordinates.push_back(gpsTraces.getRandomCoordinate());
if (benchmark.number_of_results)
{
params.number_of_results = *benchmark.number_of_results;
}
TIMER_START(nearest);
const auto rc = osrm.Nearest(params, result);
TIMER_STOP(nearest);
statistics.push(TIMER_MSEC(nearest));
auto &json_result = std::get<json::Object>(result);
if (rc != Status::Ok ||
json_result.values.find("waypoints") == json_result.values.end())
{
auto code = std::get<json::String>(json_result.values["code"]).value;
if (code != "NoSegment")
{
throw std::runtime_error{"Couldn't find nearest point"};
}
}
}
std::cout << benchmark.name << std::endl;
std::cout << statistics << std::endl;
};
std::vector<Benchmark> benchmarks = {{"10000 nearest, number_of_results=1", 1},
{"10000 nearest, number_of_results=5", 5},
{"10000 nearest, number_of_results=10", 10}};
for (const auto &benchmark : benchmarks)
{
run_benchmark(benchmark);
}
}
void runTripBenchmark(const OSRM &osrm, const GPSTraces &gpsTraces)
{
struct Benchmark
{
std::string name;
size_t coordinates;
};
auto run_benchmark = [&](const Benchmark &benchmark)
{
Statistics statistics;
auto NUM = 1000;
for (int i = 0; i < NUM; ++i)
{
engine::api::ResultT result = json::Object();
TripParameters params;
params.roundtrip = true;
for (size_t i = 0; i < benchmark.coordinates; ++i)
{
params.coordinates.push_back(gpsTraces.getRandomCoordinate());
}
TIMER_START(trip);
const auto rc = osrm.Trip(params, result);
TIMER_STOP(trip);
statistics.push(TIMER_MSEC(trip));
auto &json_result = std::get<json::Object>(result);
if (rc != Status::Ok || json_result.values.find("trips") == json_result.values.end())
{
auto code = std::get<json::String>(json_result.values["code"]).value;
if (code != "NoSegment")
{
throw std::runtime_error{"Couldn't find trip"};
}
}
}
std::cout << benchmark.name << std::endl;
std::cout << statistics << std::endl;
};
std::vector<Benchmark> benchmarks = {
{"1000 trips, 3 coordinates", 3},
{"1000 trips, 4 coordinates", 4},
{"1000 trips, 5 coordinates", 5},
};
for (const auto &benchmark : benchmarks)
{
run_benchmark(benchmark);
}
}
void runTableBenchmark(const OSRM &osrm, const GPSTraces &gpsTraces)
{
struct Benchmark
{
std::string name;
size_t coordinates;
};
auto run_benchmark = [&](const Benchmark &benchmark)
{
Statistics statistics;
auto NUM = 250;
for (int i = 0; i < NUM; ++i)
{
engine::api::ResultT result = json::Object();
TableParameters params;
for (size_t i = 0; i < benchmark.coordinates; ++i)
{
params.coordinates.push_back(gpsTraces.getRandomCoordinate());
}
TIMER_START(table);
const auto rc = osrm.Table(params, result);
TIMER_STOP(table);
statistics.push(TIMER_MSEC(table));
auto &json_result = std::get<json::Object>(result);
if (rc != Status::Ok ||
json_result.values.find("durations") == json_result.values.end())
{
auto code = std::get<json::String>(json_result.values["code"]).value;
if (code != "NoSegment")
{
throw std::runtime_error{"Couldn't compute table"};
}
}
}
std::cout << benchmark.name << std::endl;
std::cout << statistics << std::endl;
};
std::vector<Benchmark> benchmarks = {{"250 tables, 3 coordinates", 3},
{"250 tables, 25 coordinates", 25},
{"250 tables, 50 coordinates", 50},
{"250 tables, 100 coordinates", 100}};
for (const auto &benchmark : benchmarks)
{
run_benchmark(benchmark);
}
}
} // namespace
int main(int argc, const char *argv[])
try
{
if (argc < 5)
{
std::cerr
<< "Usage: " << argv[0]
<< " data.osrm <mld|ch> <path to GPS traces.csv> <route|match|trip|table|nearest>\n";
return EXIT_FAILURE;
}
// Configure based on a .osrm base path, and no datasets in shared mem from osrm-datastore
EngineConfig config;
config.storage_config = {argv[1]};
config.algorithm =
std::string{argv[2]} == "mld" ? EngineConfig::Algorithm::MLD : EngineConfig::Algorithm::CH;
config.use_shared_memory = false;
// Routing machine with several services (such as Route, Table, Nearest, Trip, Match)
OSRM osrm{config};
GPSTraces gpsTraces{42};
gpsTraces.readCSV(argv[3]);
const auto benchmarkToRun = std::string{argv[4]};
if (benchmarkToRun == "route")
{
runRouteBenchmark(osrm, gpsTraces);
}
else if (benchmarkToRun == "match")
{
runMatchBenchmark(osrm, gpsTraces);
}
else if (benchmarkToRun == "nearest")
{
runNearestBenchmark(osrm, gpsTraces);
}
else if (benchmarkToRun == "trip")
{
runTripBenchmark(osrm, gpsTraces);
}
else if (benchmarkToRun == "table")
{
runTableBenchmark(osrm, gpsTraces);
}
else
{
std::cerr << "Unknown benchmark: " << benchmarkToRun << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
catch (const std::exception &e)
{
std::cerr << "Error: " << e.what() << std::endl;
return EXIT_FAILURE;
}
+1 -1
View File
@@ -86,7 +86,7 @@ json::Object load(const char *filename)
json::Value result; json::Value result;
convert(document, result); convert(document, result);
return std::get<json::Object>(result); return result.get<json::Object>();
} }
} // namespace } // namespace
+2 -2
View File
@@ -232,9 +232,9 @@ try
{ {
engine::api::ResultT result = json::Object(); engine::api::ResultT result = json::Object();
const auto rc = osrm.Match(params, result); const auto rc = osrm.Match(params, result);
auto &json_result = std::get<json::Object>(result); auto &json_result = result.get<json::Object>();
if (rc != Status::Ok || if (rc != Status::Ok ||
std::get<json::Array>(json_result.values.at("matchings")).values.size() != 1) json_result.values.at("matchings").get<json::Array>().values.size() != 1)
{ {
throw std::runtime_error{"Couldn't match"}; throw std::runtime_error{"Couldn't match"};
} }
-1
View File
@@ -5,7 +5,6 @@
#include <algorithm> #include <algorithm>
#include <iomanip> #include <iomanip>
#include <iostream>
#include <numeric> #include <numeric>
#include <random> #include <random>
#include <string> #include <string>
-166
View File
@@ -1,166 +0,0 @@
#include "engine/engine_config.hpp"
#include "util/coordinate.hpp"
#include "util/timing_util.hpp"
#include "osrm/route_parameters.hpp"
#include "osrm/coordinate.hpp"
#include "osrm/engine_config.hpp"
#include "osrm/json_container.hpp"
#include "osrm/osrm.hpp"
#include "osrm/status.hpp"
#include <boost/assert.hpp>
#include <boost/optional/optional.hpp>
#include <cstdlib>
#include <exception>
#include <iostream>
#include <optional>
#include <stdexcept>
#include <string>
#include <vector>
int main(int argc, const char *argv[])
try
{
if (argc < 2)
{
std::cerr << "Usage: " << argv[0] << " data.osrm\n";
return EXIT_FAILURE;
}
using namespace osrm;
// Configure based on a .osrm base path, and no datasets in shared mem from osrm-datastore
EngineConfig config;
config.storage_config = {argv[1]};
config.algorithm = (argc > 2 && std::string{argv[2]} == "mld") ? EngineConfig::Algorithm::MLD
: EngineConfig::Algorithm::CH;
config.use_shared_memory = false;
// Routing machine with several services (such as Route, Table, Nearest, Trip, Match)
OSRM osrm{config};
struct Benchmark
{
std::string name;
std::vector<util::Coordinate> coordinates;
RouteParameters::OverviewType overview;
bool steps = false;
std::optional<size_t> alternatives = std::nullopt;
std::optional<double> radius = std::nullopt;
};
auto run_benchmark = [&](const Benchmark &benchmark)
{
RouteParameters params;
params.overview = benchmark.overview;
params.steps = benchmark.steps;
params.coordinates = benchmark.coordinates;
if (benchmark.alternatives)
{
params.alternatives = *benchmark.alternatives;
}
if (benchmark.radius)
{
params.radiuses = std::vector<boost::optional<double>>(
params.coordinates.size(), boost::make_optional(*benchmark.radius));
}
TIMER_START(routes);
auto NUM = 1000;
for (int i = 0; i < NUM; ++i)
{
engine::api::ResultT result = json::Object();
const auto rc = osrm.Route(params, result);
auto &json_result = std::get<json::Object>(result);
if (rc != Status::Ok || json_result.values.find("routes") == json_result.values.end())
{
throw std::runtime_error{"Couldn't route"};
}
}
TIMER_STOP(routes);
std::cout << benchmark.name << std::endl;
std::cout << TIMER_MSEC(routes) << "ms" << std::endl;
std::cout << TIMER_MSEC(routes) / NUM << "ms/req" << std::endl;
};
std::vector<Benchmark> benchmarks = {
{"1000 routes, 3 coordinates, no alternatives, overview=full, steps=true",
{{FloatLongitude{7.437602352715465}, FloatLatitude{43.75030522209604}},
{FloatLongitude{7.421844922513342}, FloatLatitude{43.73690777888953}},
{FloatLongitude{7.412303912230966}, FloatLatitude{43.72851046529198}}},
RouteParameters::OverviewType::Full,
true,
std::nullopt},
{"1000 routes, 2 coordinates, no alternatives, overview=full, steps=true",
{{FloatLongitude{7.437602352715465}, FloatLatitude{43.75030522209604}},
{FloatLongitude{7.412303912230966}, FloatLatitude{43.72851046529198}}},
RouteParameters::OverviewType::Full,
true,
std::nullopt},
{"1000 routes, 2 coordinates, 3 alternatives, overview=full, steps=true",
{{FloatLongitude{7.437602352715465}, FloatLatitude{43.75030522209604}},
{FloatLongitude{7.412303912230966}, FloatLatitude{43.72851046529198}}},
RouteParameters::OverviewType::Full,
true,
3},
{"1000 routes, 3 coordinates, no alternatives, overview=false, steps=false",
{{FloatLongitude{7.437602352715465}, FloatLatitude{43.75030522209604}},
{FloatLongitude{7.421844922513342}, FloatLatitude{43.73690777888953}},
{FloatLongitude{7.412303912230966}, FloatLatitude{43.72851046529198}}},
RouteParameters::OverviewType::False,
false,
std::nullopt},
{"1000 routes, 2 coordinates, no alternatives, overview=false, steps=false",
{{FloatLongitude{7.437602352715465}, FloatLatitude{43.75030522209604}},
{FloatLongitude{7.412303912230966}, FloatLatitude{43.72851046529198}}},
RouteParameters::OverviewType::False,
false,
std::nullopt},
{"1000 routes, 2 coordinates, 3 alternatives, overview=false, steps=false",
{{FloatLongitude{7.437602352715465}, FloatLatitude{43.75030522209604}},
{FloatLongitude{7.412303912230966}, FloatLatitude{43.72851046529198}}},
RouteParameters::OverviewType::False,
false,
3},
{"1000 routes, 3 coordinates, no alternatives, overview=false, steps=false, radius=750",
{{FloatLongitude{7.437602352715465}, FloatLatitude{43.75030522209604}},
{FloatLongitude{7.421844922513342}, FloatLatitude{43.73690777888953}},
{FloatLongitude{7.412303912230966}, FloatLatitude{43.72851046529198}}},
RouteParameters::OverviewType::False,
false,
std::nullopt,
750},
{"1000 routes, 2 coordinates, no alternatives, overview=false, steps=false, radius=750",
{{FloatLongitude{7.437602352715465}, FloatLatitude{43.75030522209604}},
{FloatLongitude{7.412303912230966}, FloatLatitude{43.72851046529198}}},
RouteParameters::OverviewType::False,
false,
std::nullopt,
750},
{"1000 routes, 2 coordinates, 3 alternatives, overview=false, steps=false, radius=750",
{{FloatLongitude{7.437602352715465}, FloatLatitude{43.75030522209604}},
{FloatLongitude{7.412303912230966}, FloatLatitude{43.72851046529198}}},
RouteParameters::OverviewType::False,
false,
3,
750}
};
for (const auto &benchmark : benchmarks)
{
run_benchmark(benchmark);
}
return EXIT_SUCCESS;
}
catch (const std::exception &e)
{
std::cerr << "Error: " << e.what() << std::endl;
return EXIT_FAILURE;
}
+1
View File
@@ -1,6 +1,7 @@
#include "contractor/contractor.hpp" #include "contractor/contractor.hpp"
#include "contractor/contract_excludable_graph.hpp" #include "contractor/contract_excludable_graph.hpp"
#include "contractor/contracted_edge_container.hpp" #include "contractor/contracted_edge_container.hpp"
#include "contractor/crc32_processor.hpp"
#include "contractor/files.hpp" #include "contractor/files.hpp"
#include "contractor/graph_contractor.hpp" #include "contractor/graph_contractor.hpp"
#include "contractor/graph_contractor_adaptors.hpp" #include "contractor/graph_contractor_adaptors.hpp"

Some files were not shown because too many files have changed in this diff Show More