Compare commits

...

286 Commits

Author SHA1 Message Date
Dennis Luxen 1d3932e8c5 fix an off-by-one issue in the output JSON 2014-06-27 16:18:38 +02:00
Dennis Luxen 3f85b30d4a remove some unneeded includes 2014-06-27 10:38:28 +02:00
Dennis Luxen e4c398aa23 make std::hash specialization for std::pair<> fully generic 2014-06-27 09:50:57 +02:00
Dennis Luxen f9417555d0 remove superflous include 2014-06-27 09:50:26 +02:00
Dennis Luxen 5d3123b97f reformat code using clang-format 2014-06-26 13:50:29 +02:00
dmbreaker 25080aaf1d Non-explicit constructor and hash-functions. 2014-06-26 13:50:29 +02:00
dmbreaker 05ac4b5ab6 Fixes to fulfill remarks. 2014-06-26 13:50:29 +02:00
dmbreaker 07e13e2499 Replaced std::pair with classes.
Looks like fixed wrong restriction type in CheckForEmanatingIsOnlyTurn (now RestrictionTarget instead if RestrictionSource).
2014-06-26 13:50:29 +02:00
dmbreaker 2d9645b9b0 Added structures for RestrictionTarget and RestrictionSource. 2014-06-26 13:50:29 +02:00
Dennis Luxen 65ccbedab2 Merge pull request #1103 from dmbreaker/feature/graph_comments
Added some graphical explanations for variables.
2014-06-26 12:16:44 +02:00
Dennis Luxen 631567864b Merge pull request #1098 from TheMarex/rangetable-covertity
Fix coverity warning in RangeTable
2014-06-26 12:15:35 +02:00
Dennis Luxen 39d479128c add better comment to document the source of the hash_combine work 2014-06-26 12:14:47 +02:00
Dennis Luxen 4c0b315c07 Merge pull request #1094 from gberaudo/fixes
Several fixes: remove dead code, fix Int->String conversion for INT_MIN, remove duplicated coordinate from encoded polyline.
2014-06-26 11:54:45 +02:00
dmbreaker 264e83a1f3 Added comments with graphical representation of variables. 2014-06-26 12:31:45 +04:00
Dennis Luxen 2b2ed50721 add a hash combine implementation that has some minor performance guarantees 2014-06-25 18:50:46 +02:00
Dennis Luxen 31fbf99109 fail hard when building tools and not all prequisites are met 2014-06-25 10:53:51 +02:00
Dennis Luxen 63381ad221 fix compilation on GCC 4.8.2, type of priority_queue<> is not properly deduced 2014-06-24 18:31:34 +02:00
Guillaume Beraudo 6ee2d1103e Remove duplicated point in polyline encoded data
First point was outputted twice.
Add test case.
2014-06-24 17:25:36 +02:00
Guillaume Beraudo bee18dba54 Display warning when routing without street names.
Indeed, street names are optional for routing.
2014-06-24 17:18:52 +02:00
Guillaume Beraudo 481e445e8a Fix printInt when value=INT_MIN (was overflowing) 2014-06-24 17:18:52 +02:00
Guillaume Beraudo 129f7b7441 Remove unused polyline method 2014-06-24 17:18:52 +02:00
Guillaume Beraudo d6bc3c5175 Remove unused test method 2014-06-24 17:18:52 +02:00
Dennis Luxen de7c56c6bc remove remaining NULL pointers by nullptrs 2014-06-24 16:50:00 +02:00
Dennis Luxen 0c59ecfa14 remove dead code, produce empty route when origin and destination are the same 2014-06-24 16:09:25 +02:00
Patrick Niklaus f67241a3cb Fix coverity warning in RangeTable 2014-06-24 13:26:27 +02:00
Dennis Luxen 3b2893944c remove non-existing dependency 2014-06-24 12:45:16 +02:00
Dennis Luxen dd7d6df4c6 streamline PBF parsing code 2014-06-24 12:25:19 +02:00
Dennis Luxen efbda436f3 properly cast from int to bool 2014-06-24 11:46:32 +02:00
Dane Springmeyer 2064934939 link -lrt to osrm-prepare 2014-06-23 16:02:58 -07:00
Dennis Luxen b36cf7c450 remove debug output 2014-06-23 17:34:20 +02:00
Dennis Luxen a24dd3dee2 use incremental NN query for Nearest plugin 2014-06-23 17:33:55 +02:00
Dennis Luxen 7b22f08869 remove dead code 2014-06-23 17:32:52 +02:00
Dennis Luxen 840929754a remove debug output 2014-06-23 17:32:24 +02:00
Dennis Luxen 51fd332806 add incremental query to Facades 2014-06-23 16:56:01 +02:00
Dennis Luxen 4d7e0f6b79 use incremental NN query for distance table generation 2014-06-23 16:55:38 +02:00
Dennis Luxen b74a573ec5 add typedef for an array of phantom node vectors 2014-06-23 16:54:57 +02:00
Dennis Luxen 5faf88afdb implement incremental NN query for R-tree 2014-06-23 16:54:31 +02:00
Dennis Luxen 5e1110930e use proper floating point literal instead of implicit cast from int 2014-06-23 14:42:37 +02:00
Dennis Luxen f11adf5f80 fix signed/unsigned comparison 2014-06-23 14:35:09 +02:00
Dennis Luxen 40a71e09a6 use an explicit downcast to initialize variable 2014-06-23 13:22:46 +02:00
Dennis Luxen 1231847a3c replace hashmap with a dummy vector based implementation as the number of tags per object is tiny 2014-06-23 13:22:14 +02:00
Dennis Luxen b06a73e893 replace hashmap with a dummy vector based implementation as the number of tags per object is tiny 2014-06-23 13:21:56 +02:00
Dennis Luxen f99f194927 use proper interface of HashTable, use prefix increment 2014-06-23 12:13:01 +02:00
Dennis Luxen eac7d07ef6 rename variables to cut OCLint warnings 2014-06-23 12:11:56 +02:00
Dennis Luxen 60d70a9f4c fix leak on shutdown 2014-06-20 17:32:20 +02:00
Dennis Luxen c944783590 don't downcast from std:.size_t to unsigned 2014-06-20 17:32:03 +02:00
Dennis Luxen 8104a8aea1 reformat to cut long line 2014-06-20 16:49:33 +02:00
Dennis Luxen a4db678895 reformat to cut long line 2014-06-20 16:48:34 +02:00
Dennis Luxen da33d02461 reformat to cut long line 2014-06-20 16:47:09 +02:00
Dennis Luxen 9b4071006e reformat to cut long line 2014-06-20 16:39:58 +02:00
Dennis Luxen b3cdd5b3bf reformat to cut long line 2014-06-20 16:36:15 +02:00
Dennis Luxen 93e53ec612 fix comparison to accept 0 distance results in distance table 2014-06-19 19:52:15 +02:00
Dennis Luxen ea8319e2b9 add more asserts to test for data corruption during MBR merging in StaticRTree 2014-06-19 17:52:59 +02:00
Dennis Luxen 2fae253c62 use std::size_t consistently and avoid possible loss of data 2014-06-19 11:14:28 +02:00
Dennis Luxen e204b257ad add proper size_t->unsigned cast 2014-06-19 10:40:24 +02:00
Dennis Luxen dd83d8ed61 make size of table compact 2014-06-19 10:40:04 +02:00
Dennis Luxen 61f3d85af1 add even more cast sanity 2014-06-18 11:49:01 +02:00
Dennis Luxen 804e515847 stream line code a bit in Reply 2014-06-18 11:25:56 +02:00
Dennis Luxen 35977b6c7f add explicit cast 2014-06-18 11:24:50 +02:00
Dennis Luxen 23f1d3d83b add explicit cast 2014-06-18 11:20:24 +02:00
Dennis Luxen b8ea935424 cast bearing to unsigned 2014-06-18 11:17:51 +02:00
Dennis Luxen 7c0866f626 stream line code a bit in Reply 2014-06-18 11:17:23 +02:00
Dennis Luxen 0f2062b739 round bearing value to integers 2014-06-18 11:00:13 +02:00
Dennis Luxen e91454eeee use auto keyword to deduce types automatically 2014-06-18 10:59:43 +02:00
Dennis Luxen 58134200df use float consistently in DescriptionFactory 2014-06-18 10:44:46 +02:00
Dennis Luxen f6bab21928 use double consistently in JSONDescriptor 2014-06-18 10:44:09 +02:00
Dennis Luxen 011910811b use float consistently in Contractor 2014-06-18 10:43:26 +02:00
Dennis Luxen bbc0ba147a reformat Descriptors/JSONDescriptor.h 2014-06-18 10:15:38 +02:00
Dennis Luxen 922a4331db reformat source file datastore.cpp 2014-06-18 09:42:45 +02:00
Dennis Luxen 8f7f1e2683 reformat source file Server/RequestHandler.cpp 2014-06-18 09:40:53 +02:00
Dennis Luxen 1980cc007f cast parameters before c'ting Coordinate 2014-06-17 19:10:26 +02:00
Dennis Luxen 39611f7477 couple more explicit casts 2014-06-17 18:52:01 +02:00
Dennis Luxen e3d659576f cast std::size_t and unsigned in a proper way 2014-06-17 16:01:06 +02:00
Dennis Luxen 46d4670b74 cast float to unsigned in a proper way 2014-06-17 16:00:42 +02:00
Dennis Luxen 15ca6d5ca9 use explicit casts where feasible 2014-06-17 15:57:03 +02:00
Dennis Luxen 58f23cda4a use explicit casts where feasible 2014-06-17 15:51:43 +02:00
Dennis Luxen a58d8420a2 add some formatting whitespace 2014-06-17 15:48:47 +02:00
Dennis Luxen 96f834fb81 use explicit casts 2014-06-17 15:47:59 +02:00
Dennis Luxen 86617eccb1 use explicit casts 2014-06-17 15:47:40 +02:00
Dennis Luxen f2936d1c2d add disabled HipChat notifications to Windows build 2014-06-17 15:47:16 +02:00
Dennis Luxen 0fc8e04ab5 use proper data types to avoid uncessary casts 2014-06-17 15:30:28 +02:00
Dennis Luxen a65e2d3115 downcast size_t to unsigned 2014-06-17 13:19:59 +02:00
Dennis Luxen ca6e25b11c make many more conversions explicit 2014-06-17 13:18:55 +02:00
Dennis Luxen 3ec6a6f5bc remove ignored parameter 2014-06-17 13:09:58 +02:00
Dennis Luxen c12fae47e7 allow results at high latitudes to be a bit more imprecise 2014-06-17 13:00:13 +02:00
Dennis Luxen 604d2c698b replace fp divisions by multiplications 2014-06-17 12:50:29 +02:00
Dennis Luxen 5d14016366 add static_casts to avoid unnecessary conversion from double to float 2014-06-17 12:37:55 +02:00
Dennis Luxen b112becbba use explicit casts to mitigate MSVC warnings 2014-06-17 12:15:40 +02:00
Dennis Luxen e68a09fb3c fix windows deploy on develop branch, partially fixes #1085 2014-06-16 15:13:19 +02:00
Dennis Luxen 30e9b4513a Merge branch 'alex85k-develop' into develop 2014-06-16 13:43:26 +02:00
alex85k 671b14dac0 pack only develop version to zip on AppVeyor 2014-06-16 16:02:14 +06:00
Porjo 82e99988e8 Change content-type header for JSON data 2014-06-16 09:29:34 +02:00
Dennis Luxen 313a7ed7fa Merge pull request #1076 from alex85k/patch-mingw
Add Mingw support (tune libraries and disable cpuid with #ifdef)
2014-06-15 21:55:18 +02:00
Dennis Luxen cf3365574e Merge branch 'TheMarex-thread-control' into develop 2014-06-15 12:35:26 +02:00
Dennis Luxen 0e1f6f50ea Merge branch 'thread-control' of https://github.com/TheMarex/Project-OSRM into TheMarex-thread-control 2014-06-15 12:35:15 +02:00
Dennis Luxen 5b6518d4a9 Merge branch 'TheMarex-diffencoding' into develop 2014-06-15 12:10:18 +02:00
Patrick Niklaus c009dce591 Another VC2013 fix 2014-06-15 11:42:59 +02:00
Patrick Niklaus 40e2d7932b Fix VC2013 issues 2014-06-15 11:29:36 +02:00
Patrick Niklaus e29b7a6eae Fix some minor style issues 2014-06-15 11:04:10 +02:00
Patrick Niklaus a3e9cbc000 Allow user to force thread number
This allows the user to do (potentially) stupid things, but warns him.
The default is TBBs default, so probably the right thing.
To enforce thread numbers in extractor it must be passed to the child
threads.
2014-06-14 17:02:43 +02:00
Patrick Niklaus aedcc2ff40 Add array inlcude 2014-06-12 22:01:23 +02:00
Patrick Niklaus 4c17aeb180 Removed SSE code in RangeTable to rely on compiler optimazation 2014-06-12 22:01:23 +02:00
Patrick Niklaus ef60ae652c Fix edge cases in RangeTable 2014-06-12 22:01:23 +02:00
Patrick Niklaus 1d62ed028e Fix off-by-one since back() gives last value inside [begin,end) 2014-06-12 22:01:23 +02:00
Patrick Niklaus 50bf7694c2 Constify some parts of RangeTable 2014-06-12 22:01:22 +02:00
Patrick Niklaus 807f1d7c1c Initial support for SharedDataFacade
SharedDataLayout was refactored to include canary values at the
boundaries of each memory block. This makes it easy to detect overruns
and block-size mismatches between osrm-datastore and the
SharedDataFacade.
2014-06-12 22:01:22 +02:00
Patrick Niklaus 7a7d0c09d9 Integrate RangeTable into server 2014-06-12 22:00:03 +02:00
Patrick Niklaus f90ce77da4 Use differential encoding for name offsets
Each name is represented as an integer range in a vector of chars.
Instead of storing the absolute offset inside this array, we can store
only the offset to the previous entry (the string size). By doing this we reduce
the number of bytes need to store an offset from 4 to 1 bytes (if we
set a maximum string length of 255).
This is however slower, since the absolute offset must be computed on
each querry by summing up all previous lengths. To limit the
performance inpact we only do this for blocks of a certain size (16).
2014-06-12 22:00:03 +02:00
Dennis Luxen d27ac27bc7 remove one fwd decl, add more comments to Connection 2014-06-12 13:46:07 +02:00
Dennis Luxen 44c6a64bf4 make c'tor of NodeInfo explicit 2014-06-11 18:26:34 +02:00
Dennis Luxen 2d6eae9391 make conversion explicit 2014-06-11 18:15:36 +02:00
Dennis Luxen ba440550a6 make conversion explicit 2014-06-11 18:15:31 +02:00
Dennis Luxen 8e24fee9da explicitly cast from int to bool 2014-06-11 17:44:50 +02:00
alex85k 1148652101 Add Mingw support (tune libraries and disable cpuid with #ifdef) 2014-06-11 20:58:53 +06:00
Dennis Luxen ed01eeaeb3 reformat SharedMemoryFactory according to code guidelines 2014-06-11 15:22:51 +02:00
Dennis Luxen 096f187d6f remove empty line 2014-06-11 15:19:11 +02:00
Dennis Luxen fa35eb1959 adapt for merge, add deployment details 2014-06-11 15:17:51 +02:00
Dennis Luxen 8d89d30c74 Merge branch 'alex85k-win-038' into develop 2014-06-11 15:15:05 +02:00
alex85k f1bde40939 add appveyor.yml template 2014-06-11 18:38:03 +06:00
alex85k 4e7ccaa298 use std::memcpy instead of std::copy (avoid checked iterators assertions) 2014-06-11 18:38:02 +06:00
alex85k d0284991ed patch Ruby files for successful testing on Windows 2014-06-11 18:38:01 +06:00
alex85k c4998990e5 disable io-benchmark on Windows 2014-06-11 18:38:01 +06:00
alex85k 42d3ee9b94 workaround for std::packaged_task<void()> problem on MSVC 2014-06-11 18:38:00 +06:00
alex85k be5c3e41e1 Replace sizeof asserts with warning on Windows 2014-06-11 18:37:26 +06:00
alex85k 3282d410c4 Add basic shared memory support for Windows OS 2014-06-11 18:15:17 +06:00
Alexei Kasatkin 75303c95f8 Avoid constexpr by #ifdef (not supported in MSVC18) 2014-06-11 18:15:16 +06:00
Alexei Kasatkin 0209272831 fix includes and definitions (avoid unistd.h, isatty, fix min,max, round and M_PI) 2014-06-11 18:15:15 +06:00
Alexei Kasatkin 0e16c4ed97 Add more Boost libraries on Windows, fix TBB debug linking, stop building
on old Microsoft compilers
2014-06-11 18:15:14 +06:00
Dennis Luxen e49720f34a add include 2014-06-11 13:44:10 +02:00
Dennis Luxen 8aee371d81 further include untangling, chops 5sec compile time 2014-06-11 12:25:57 +02:00
Dennis Luxen 71c4f81b59 avoid signed/unsigned comparison 2014-06-10 18:08:58 +02:00
Dennis Luxen 3127fafc88 Merge branch 'patch-6' of https://github.com/alex85k/Project-OSRM into develop 2014-06-10 17:40:56 +02:00
Dennis Luxen 4e6bdf28cc fixes #1041, some only_ turn restrictions are inverted under certain conditions 2014-06-10 17:26:22 +02:00
Dennis Luxen 621a5a86a0 fixes #1041, some only_ turn restrictions are inverted under certain conditions 2014-06-10 17:26:05 +02:00
Dennis Luxen d80c8cbd2f add another turn restriction test 2014-06-10 17:23:24 +02:00
Dennis Luxen 686f1aeeb2 reformat some code 2014-06-10 17:23:07 +02:00
alex85k e27a69bab7 Use one more .string().c_str() call 2014-06-10 20:34:21 +06:00
Dennis Luxen 4ee2e1d049 fix long line 2014-06-10 10:49:45 +02:00
Dennis Luxen 2102648102 fix short variable name 2014-06-10 10:48:43 +02:00
Dennis Luxen 8611e40172 Merge branch 'TheMarex-fix-cucumber' into develop 2014-06-09 18:41:37 +02:00
Dennis Luxen 7d5b88fff8 Merge branch 'fix-cucumber' of https://github.com/TheMarex/Project-OSRM into TheMarex-fix-cucumber 2014-06-09 18:41:18 +02:00
Dennis Luxen cfd9aa31a9 add algorithm include 2014-06-09 18:32:07 +02:00
Dennis Luxen 62aea4c321 refactored function names 2014-06-09 18:10:46 +02:00
Dennis Luxen f75fcb3041 refactor RequestHandler to remove code duplication, nested blocks and object copies 2014-06-09 18:06:23 +02:00
Dennis Luxen 971c557d85 explicitly initialize Header member 2014-06-09 17:58:17 +02:00
Dennis Luxen ea05aa225e rename some function names in Reply 2014-06-09 17:57:35 +02:00
Dennis Luxen 56cdabff6a add move c'tor to Header 2014-06-09 17:57:03 +02:00
Dennis Luxen 15f62e680a use inplace construction for Headers instead of explicit objects and copying 2014-06-09 17:55:16 +02:00
Dennis Luxen 0af4e16c21 use inplace construction for Headers instead of explicit objects and copying 2014-06-09 17:54:46 +02:00
Dennis Luxen c7b90bac1a add explicit unsigned->string conversion 2014-06-09 17:50:50 +02:00
Patrick Niklaus 4b81331d53 Don't reset response, so log_fail won't crash cucumber 2014-06-09 14:33:30 +02:00
Dennis Luxen 47ab0cbf62 reduce some code duplication 2014-06-09 12:11:44 +02:00
Dennis Luxen f5b079b8e7 add more comments to reduce NCSS number 2014-06-09 11:58:23 +02:00
Emil Tin 21c4691d40 cuke: make File.tail utility more robust 2014-06-08 12:06:34 +02:00
Dennis Luxen 3726706608 remove another superflous include 2014-06-06 19:19:45 +02:00
Dennis Luxen 28a53aa147 remove superflous include 2014-06-06 19:18:44 +02:00
Dennis Luxen 2ad572490c const as const can 2014-06-06 18:06:05 +02:00
Dennis Luxen 0ed9caf969 fix a couple of implicit signed/unsigned conversions 2014-06-06 18:05:07 +02:00
Dennis Luxen 63ee376f71 removing constexpr at one position 2014-06-06 18:01:01 +02:00
Dennis Luxen 67bcb98a84 make some constants explicit floats to cut down on MSVC conversion warnings 2014-06-06 15:39:29 +02:00
Dennis Luxen 9cd91ae99c Merge pull request #1066 from alex85k/patch-path-cstr
Obtain char* from boost::filesystem::path on all systems
2014-06-06 12:02:32 +02:00
Dennis Luxen d111a0e5e6 guard against an empty alternative path in ExtractRouteNames 2014-06-06 11:50:14 +02:00
Dennis Luxen 11d4c04cea removed left-overs from win/, i.e. a previous windows porting attempt 2014-06-06 11:33:47 +02:00
Dennis Luxen 01773c2a00 fix and refactor the selection of RouteNames 2014-06-06 11:30:12 +02:00
alex85k 1079bf7843 sort vectors before using std::set_difference
discussed in https://github.com/DennisOSRM/Project-OSRM/pull/998#issuecomment-45238338
The vectors are better to be sorted up to ``name_id_comperator`` before running std::set_difference. Elsewhere we get debug checked iterator assertions on Windows and theretically possible incorrect results.
2014-06-06 10:27:35 +02:00
Dennis Luxen 05bcfd2c1c Merge pull request #1065 from alex85k/patch-skip-zero-rw
skip zero bytes reading or wrtiting
2014-06-06 10:22:49 +02:00
Alexei Kasatkin 5357a6a4fd get char* from boost::filesystem::path 2014-06-05 23:48:54 +06:00
Alexei Kasatkin b6787b0014 safeguard: do not read/write 0 bytes (iostream) 2014-06-05 23:16:19 +06:00
Dennis Luxen a32116d24c Merge pull request #1063 from alex85k/patch-6
simplify static asserts
2014-06-05 18:58:08 +02:00
alex85k a03b698e5a simplify static asserts
Simplify static asserts to make them compatible with older compilers and MSVC 2013
2014-06-05 22:55:22 +06:00
Dennis Luxen fa0c5db18c include <string> as it is needed 2014-06-05 18:29:22 +02:00
Dennis Luxen bc063ded7a make sure result is always > 0, hits when origin and destination are on the same one-way segment in reversed order 2014-06-05 18:28:54 +02:00
Dennis Luxen 846505cbc8 Merge pull request #1051 from TheMarex/linker-fix
Fix linking for linux
2014-06-05 18:14:33 +02:00
Dennis Luxen 964118d1d6 add more comments and rename a couple of badly named variables 2014-06-05 17:27:00 +02:00
Patrick Niklaus c43b67ea2e Fixes build using gcc 4.9 with LTO.
Otherwise sem_close is not found.
2014-06-05 17:26:19 +02:00
Dennis Luxen f68af08931 fix short variable names and long lines 2014-06-05 15:40:52 +02:00
Dennis Luxen cdd5a41965 remove duplicate edges from NodeBasedGraph 2014-06-05 15:33:24 +02:00
Dennis Luxen e13ee59af3 remove some code lint 2014-06-05 15:14:39 +02:00
Dennis Luxen 9eb183e01d Merge branch 'alex85k-patch-timing' into develop 2014-06-05 11:22:52 +02:00
Dennis Luxen 1163417722 Merge branch 'patch-timing' of https://github.com/alex85k/Project-OSRM into alex85k-patch-timing
Conflicts:
	extractor.cpp
2014-06-05 11:22:26 +02:00
Dennis Luxen 3edc48cda5 Merge branch 'alex85k-patch-6' into develop 2014-06-05 11:04:35 +02:00
Dennis Luxen 2c01425ee5 Merge branch 'patch-6' of https://github.com/alex85k/Project-OSRM into alex85k-patch-6 2014-06-05 11:04:17 +02:00
Dennis Luxen ed9c72814f Merge pull request #1058 from alex85k/patch-4
add a safe-guard against bad input
2014-06-05 11:02:39 +02:00
Dennis Luxen adbbe2b097 fix broken transmission of checksum/hinting mechanism on shared memory 2014-06-05 10:55:27 +02:00
alex85k 7335e0809a Globally rename UUID to FingerPrint 2014-06-05 10:31:19 +02:00
alex85k 75dabb75e2 Use TimingUtil.h for all time measurement,
and make TimingUtil.h Windows-compatible
2014-06-04 19:52:34 +06:00
alex85k 15adcd24be Remove extra mutex unlocking in ConcurrentQueue.h
As discussed in https://github.com/DennisOSRM/Project-OSRM/pull/998 , unlocking the mutex is performed on destruction. Second unlocking gives an assertion (for debug version) for Windows and FreeBSD 10.
2014-06-04 18:01:48 +06:00
alex85k e98ba99331 add a safe-guard against bad input
do not write empty original_edge_data_vector to file
2014-06-04 16:02:18 +06:00
Dennis Luxen 11459d38d0 Merge pull request #1052 from alex85k/patch-4
add a cmake option WITH_TOOLS
2014-06-03 14:58:36 +02:00
alex85k baf4ea2e8c add a cmake option WITH_TOOLS 2014-06-03 18:38:33 +06:00
Dennis Luxen 6a29168c14 use EdgeWeight typedef where possible 2014-06-03 11:28:39 +02:00
Dennis Luxen a4689c7a27 add some comments to reduce NCSS complexity 2014-06-03 10:49:25 +02:00
Dennis Luxen 8fda5a187b rename variable to a shorter name 2014-06-03 10:44:09 +02:00
Dennis Luxen 7b78270f4b safe-guard against broken input data 2014-06-02 19:23:50 +02:00
Dennis Luxen afd3599a9c remove depth of nested block 2014-06-02 18:18:27 +02:00
Dennis Luxen 4bc8562cd0 further reduce lint 2014-06-02 18:18:03 +02:00
Dennis Luxen 11fed4c06c remove variable name lint 2014-06-02 16:05:19 +02:00
Dennis Luxen 9416a983c6 rename one char variable names 2014-06-02 16:04:44 +02:00
Dennis Luxen 8108c6320d use lambda for complex initialization 2014-06-02 15:56:06 +02:00
Dennis Luxen b40b931568 unlinting DouglasPeucker 2014-06-02 09:48:43 +02:00
Dennis Luxen 282f70ea91 remove debug output 2014-05-30 19:48:34 +02:00
Dennis Luxen a671f63a3e Apply strong heuristics to speed up line generalization 2014-05-30 19:10:37 +02:00
Dennis Luxen f3ad14cb7f use integer approximation for polyline generalization 2014-05-30 14:34:04 +02:00
Dennis Luxen 21eb5b661d add integer based approximation for perpendicular distance 2014-05-30 14:33:37 +02:00
Dennis Luxen 87fe073118 re-layout parameters 2014-05-30 13:30:54 +02:00
Dennis Luxen 507dadebf4 fix a couple of variable names 2014-05-30 10:15:35 +02:00
Dennis Luxen 7dac8c621c fix a couple of OCLint warning, i.e. short variable names and useless parantheses 2014-05-30 10:01:55 +02:00
Dennis Luxen 19f4ebf3c5 make threshold values floats by construction 2014-05-30 10:01:18 +02:00
Dennis Luxen c21b40bebc further renaming of variable names, reduces legacy lint 2014-05-29 19:25:17 +02:00
Dennis Luxen 0766c3c62d refactor member names in ImportEdge 2014-05-29 18:46:20 +02:00
Dennis Luxen cc40eb709c moved ImportNode/Edge into compile units 2014-05-29 18:31:20 +02:00
Dennis Luxen 3625308585 moved ImportNode/Edge into compile units 2014-05-29 18:31:02 +02:00
Dennis Luxen df3a7676eb streamline branch-and-bound query code in R-tree 2014-05-29 17:16:24 +02:00
Dennis Luxen 8f6077e973 add proper c'tor to PhantomNode 2014-05-29 17:15:41 +02:00
Dennis Luxen e6689144c4 remove debug output 2014-05-29 16:27:08 +02:00
Dennis Luxen a67de410bf move TreeNode exploration into its own function, fix performance regression 2014-05-29 15:36:14 +02:00
Dennis Luxen 54ec1a89de use complex const variable initialization w/ lambda functions instead of conditional operator 2014-05-29 12:47:03 +02:00
Dennis Luxen 4b5f744c6f move distance calculations to float 2014-05-28 18:34:48 +02:00
Dennis Luxen df978345d7 rename start->source 2014-05-28 18:20:47 +02:00
Dennis Luxen facc07c60d use correct edge weight type in PathData 2014-05-28 18:20:29 +02:00
Dennis Luxen 2f203ac22c rename start->source 2014-05-28 18:19:27 +02:00
Dennis Luxen cc864191b8 remove some unneeded flags when compiling with clang 2014-05-28 18:18:57 +02:00
Dennis Luxen 547455245e link against UUID (needed in node-OSRM) 2014-05-28 16:09:51 +02:00
Dennis Luxen b0d7449bb4 add type traits include 2014-05-28 12:53:18 +02:00
Dennis Luxen aed04c7d55 server cast int to string only where it is needed 2014-05-28 12:34:48 +02:00
Dennis Luxen bb5973f2fd rename variable 2014-05-28 12:34:24 +02:00
Dennis Luxen f801fd1f0d fix inverted logic 2014-05-28 12:06:57 +02:00
Dennis Luxen 44ca12ead6 fix inverted logic 2014-05-28 12:05:42 +02:00
Dennis Luxen 9c48389f74 collapse if statements 2014-05-28 12:03:07 +02:00
Dennis Luxen acefb5a5f3 remove debug output 2014-05-27 19:05:37 +02:00
Dennis Luxen 3d691a3aec implements #947, free osrm-datastore's shared memory 2014-05-27 18:14:43 +02:00
Dennis Luxen 38ebdbb563 implements #949, wrong duration on first segment 2014-05-27 16:54:10 +02:00
Dennis Luxen 1090325c31 remove superflous check 2014-05-27 14:50:59 +02:00
Dennis Luxen f8ba4b9312 use C++11 shrinktofit() instead of swap tricks 2014-05-27 12:16:53 +02:00
Dennis Luxen 49a1dfff60 fix off-by-one issue related to #1020 2014-05-27 12:09:05 +02:00
Dennis Luxen 5f4d342d45 move last leg handling into DescribeLeg() function 2014-05-27 11:48:19 +02:00
Dennis Luxen e1c1f79068 remove todo marker 2014-05-27 11:44:47 +02:00
Dennis Luxen a716fa252f implements #792 2014-05-27 11:16:55 +02:00
Dennis Luxen 0b12e4d8be remove assert 2014-05-27 10:45:57 +02:00
Dennis Luxen 6ad6c94355 further CMakeLists.txt lint removal 2014-05-26 18:42:29 +02:00
Dennis Luxen 78270c8155 fix unneeded variable warning in release build 2014-05-26 18:40:21 +02:00
Dennis Luxen 4573ae21e6 unlinting CMakeLists.txt 2014-05-26 18:36:11 +02:00
Dennis Luxen 0ab6220635 add some more constness 2014-05-26 18:35:37 +02:00
Dennis Luxen 3b51976b96 remove unneeded include 2014-05-26 18:11:32 +02:00
Dennis Luxen c35211b2f6 add some const keywords where applicable 2014-05-26 17:37:44 +02:00
Dennis Luxen f62515e13b commented assertion that is triggered on trivial instances 2014-05-26 16:03:08 +02:00
Dennis Luxen 7f2daf8926 some variables renamed to replace camel case 2014-05-26 16:02:15 +02:00
Dennis Luxen 0325861ef3 remove an unneeded parameter 2014-05-26 15:31:30 +02:00
Dennis Luxen 37f8285a6e implements #1020 2014-05-26 15:31:09 +02:00
Dennis Luxen d3906cffdc add property to mark end of leg 2014-05-26 15:30:06 +02:00
Dennis Luxen bee1c77efe make variable const 2014-05-26 15:29:28 +02:00
Dennis Luxen 7250a82286 remove dead code 2014-05-26 13:08:10 +02:00
Dennis Luxen 984457f9c6 remove useless parantheses, straighten includes 2014-05-26 12:49:49 +02:00
Dennis Luxen 5db23f7e46 make short variable names more legible 2014-05-26 12:49:24 +02:00
Dennis Luxen f4f49b2b46 remove unused variable 2014-05-26 12:42:47 +02:00
Dennis Luxen 58b35f6e2d make short variable names more legible 2014-05-26 12:41:25 +02:00
Dennis Luxen b51ad16756 remove useless parantheses 2014-05-26 12:37:00 +02:00
Dennis Luxen d790bda7d2 implements #986, streamline error messages 2014-05-26 12:33:35 +02:00
Dennis Luxen 15ce232f61 partially fixes #1034 2014-05-26 11:59:13 +02:00
Dennis Luxen d999a47600 partially fixes #1034 2014-05-26 11:47:01 +02:00
Dennis Luxen 644286111f add test for #1034 2014-05-26 11:46:01 +02:00
Dennis Luxen 917b1cbd6c fix index of instructions 2014-05-26 11:38:35 +02:00
Dennis Luxen 6d1b585212 remove unneeded output 2014-05-26 10:19:45 +02:00
Dennis Luxen 6ca35a6264 remove debug output 2014-05-26 09:25:42 +02:00
Dennis Luxen 0290b1b4e0 Merge branch 'dmbreaker-develop' into develop 2014-05-23 14:50:23 +02:00
Dennis Luxen 1d86bf3e56 Merge branch 'develop' of https://github.com/dmbreaker/Project-OSRM into dmbreaker-develop 2014-05-23 14:50:05 +02:00
Dennis Luxen 3fd8ab8d3a use parallel sorting when loading OSRM data files 2014-05-23 14:49:50 +02:00
Dennis Luxen d240ae3b03 sort edges in StaticGraph in parallel 2014-05-23 14:32:40 +02:00
Emil Tin b875765c52 update test to avoid single ring 2014-05-23 12:52:32 +02:00
shipenok 2bdec31219 minor fix to open result in browser 2014-05-23 14:27:55 +04:00
Emil Tin a9eebdb1fa fix test related to via points and #1034 2014-05-23 11:45:18 +02:00
Emil Tin b25f3a9e91 update test related to via points and #1034 2014-05-23 11:42:44 +02:00
Emil Tin 06f3375a97 test showing bug related to via points. see #1034 2014-05-23 11:23:11 +02:00
Dennis Luxen 5057ae920c replace a couple of std::sort calls with tbb::parallel_sort 2014-05-22 19:07:29 +02:00
Dennis Luxen 6a03f13d55 fixes #1032:
- remove left-overs from OpenMP
- replace omp_* calls with TBB equivalents
2014-05-22 18:39:11 +02:00
Dennis Luxen 20cbfd95d6 remove OpenMP references from CMakeLists.txt 2014-05-22 18:39:11 +02:00
Dennis Luxen 885dbe1e65 Merge pull request #1028 from TheMarex/tbb-port
Port from OpenMP to TBB
2014-05-22 16:57:06 +02:00
Patrick Niklaus e2daf5c2fc Make some temporary variables const 2014-05-21 21:49:22 +02:00
Patrick Niklaus bef113001a Add TBB to travis.ymk 2014-05-21 21:49:22 +02:00
Patrick Niklaus f0b403bc2e Set requested threads in TBB 2014-05-21 21:49:22 +02:00
Patrick Niklaus a21fb5fc89 Use append operator instead of function, because function is inplace. 2014-05-21 21:49:22 +02:00
Patrick Niklaus bbc0424563 Set number of threads in TBB 2014-05-21 21:49:22 +02:00
Patrick Niklaus f487845e9d Port Contractor to TBB 2014-05-21 21:49:22 +02:00
Patrick Niklaus 77641a9fce Port StaticRTree to use TBB 2014-05-21 21:49:22 +02:00
Patrick Niklaus 56d93eb18b Replace omp atomic with std variant 2014-05-21 21:49:22 +02:00
Patrick Niklaus da1fd96d4e Port extractor to TBB 2014-05-21 21:49:22 +02:00
131 changed files with 4172 additions and 5461 deletions
+1 -1
View File
@@ -36,7 +36,7 @@ Thumbs.db
# build related files #
#######################
/build/
/Util/UUID.cpp
/Util/FingerPrint.cpp
/Util/GitDescription.cpp
# Eclipse related files #
+1 -1
View File
@@ -7,7 +7,7 @@ install:
- sudo apt-add-repository -y ppa:ubuntu-toolchain-r/test
- sudo add-apt-repository -y ppa:boost-latest/ppa
- sudo apt-get update >/dev/null
- sudo apt-get -q install libprotoc-dev libprotobuf7 libprotobuf-dev libosmpbf-dev libbz2-dev libstxxl-dev libstxxl1 libxml2-dev libzip-dev lua5.1 liblua5.1-0-dev rubygems
- sudo apt-get -q install libprotoc-dev libprotobuf7 libprotobuf-dev libosmpbf-dev libbz2-dev libstxxl-dev libstxxl1 libxml2-dev libzip-dev lua5.1 liblua5.1-0-dev rubygems libtbb-dev
- sudo apt-get -q install g++-4.7
- sudo apt-get install libboost1.54-all-dev
#luabind
+8
View File
@@ -72,6 +72,14 @@ template <typename GraphT> class BFSComponentExplorer
NodeID node,
unsigned current_component)
{
/*
Graphical representation of variables:
u v w
*---------->*---------->*
e2
*/
bfs_queue.emplace(node, node);
// mark node as read
m_component_index_list[node] = current_component;
+92 -49
View File
@@ -35,44 +35,86 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <cmath>
#include <limits>
#include <algorithm>
struct CoordinatePairCalculator
{
CoordinatePairCalculator() = delete;
CoordinatePairCalculator(const FixedPointCoordinate &coordinate_a,
const FixedPointCoordinate &coordinate_b)
{
// initialize distance calculator with two fixed coordinates a, b
const float RAD = 0.017453292519943295769236907684886f;
first_lat = (coordinate_a.lat / COORDINATE_PRECISION) * RAD;
first_lon = (coordinate_a.lon / COORDINATE_PRECISION) * RAD;
second_lat = (coordinate_b.lat / COORDINATE_PRECISION) * RAD;
second_lon = (coordinate_b.lon / COORDINATE_PRECISION) * RAD;
}
int operator()(FixedPointCoordinate &other) const
{
// set third coordinate c
const float RAD = 0.017453292519943295769236907684886f;
const float earth_radius = 6372797.560856f;
const float float_lat1 = (other.lat / COORDINATE_PRECISION) * RAD;
const float float_lon1 = (other.lon / COORDINATE_PRECISION) * RAD;
// compute distance (a,c)
const float x_value_1 = (first_lon - float_lon1) * cos((float_lat1 + first_lat) / 2.f);
const float y_value_1 = first_lat - float_lat1;
const float dist1 = sqrt(std::pow(x_value_1, 2) + std::pow(y_value_1, 2)) * earth_radius;
// compute distance (b,c)
const float x_value_2 = (second_lon - float_lon1) * cos((float_lat1 + second_lat) / 2.f);
const float y_value_2 = second_lat - float_lat1;
const float dist2 = sqrt(std::pow(x_value_2, 2) + std::pow(y_value_2, 2)) * earth_radius;
// return the minimum
return static_cast<int>(std::min(dist1, dist2));
}
float first_lat;
float first_lon;
float second_lat;
float second_lon;
};
DouglasPeucker::DouglasPeucker()
: douglas_peucker_thresholds({262144., // z0
131072., // z1
65536., // z2
32768., // z3
16384., // z4
8192., // z5
4096., // z6
2048., // z7
960., // z8
480., // z9
240., // z10
90., // z11
50., // z12
25., // z13
15., // z14
5., // z15
.65, // z16
.5, // z17
.35 // z18
: douglas_peucker_thresholds({512440, // z0
256720, // z1
122560, // z2
56780, // z3
28800, // z4
14400, // z5
7200, // z6
3200, // z7
2400, // z8
1000, // z9
600, // z10
120, // z11
60, // z12
45, // z13
36, // z14
20, // z15
8, // z16
6, // z17
4 // z18
})
{
}
void DouglasPeucker::Run(std::vector<SegmentInformation> &input_geometry, const unsigned zoom_level)
{
input_geometry.front().necessary = true;
input_geometry.back().necessary = true;
// check if input data is invalid
BOOST_ASSERT_MSG(!input_geometry.empty(), "geometry invalid");
if (input_geometry.size() < 2)
{
return;
}
SimpleLogger().Write() << "input_geometry.size()=" << input_geometry.size();
input_geometry.front().necessary = true;
input_geometry.back().necessary = true;
{
BOOST_ASSERT_MSG(zoom_level < 19, "unsupported zoom level");
@@ -81,59 +123,60 @@ void DouglasPeucker::Run(std::vector<SegmentInformation> &input_geometry, const
// Sweep over array and identify those ranges that need to be checked
do
{
if (!input_geometry[left_border].necessary)
{
SimpleLogger().Write() << "broken interval [" << left_border << "," << right_border << "]";
}
BOOST_ASSERT_MSG(input_geometry[left_border].necessary,
"left border must be necessary");
BOOST_ASSERT_MSG(input_geometry.back().necessary, "right border must be necessary");
// traverse list until new border element found
if (input_geometry[right_border].necessary)
{
// sanity checks
BOOST_ASSERT(input_geometry[left_border].necessary);
BOOST_ASSERT(input_geometry[right_border].necessary);
recursion_stack.emplace(left_border, right_border);
left_border = right_border;
}
++right_border;
} while (right_border < input_geometry.size());
}
// mark locations as 'necessary' by divide-and-conquer
while (!recursion_stack.empty())
{
// pop next element
const GeometryRange pair = recursion_stack.top();
recursion_stack.pop();
// sanity checks
BOOST_ASSERT_MSG(input_geometry[pair.first].necessary, "left border mus be necessary");
BOOST_ASSERT_MSG(input_geometry[pair.second].necessary, "right border must be necessary");
BOOST_ASSERT_MSG(pair.second < input_geometry.size(), "right border outside of geometry");
BOOST_ASSERT_MSG(pair.first < pair.second, "left border on the wrong side");
double max_distance = std::numeric_limits<double>::min();
unsigned farthest_element_index = pair.second;
// find index idx of element with max_distance
int max_int_distance = 0;
unsigned farthest_entry_index = pair.second;
const CoordinatePairCalculator DistCalc(input_geometry[pair.first].location,
input_geometry[pair.second].location);
// sweep over range to find the maximum
for (unsigned i = pair.first + 1; i < pair.second; ++i)
{
const double temp_dist = FixedPointCoordinate::ComputePerpendicularDistance(
input_geometry[i].location,
input_geometry[pair.first].location,
input_geometry[pair.second].location);
const double distance = std::abs(temp_dist);
if (distance > douglas_peucker_thresholds[zoom_level] && distance > max_distance)
const int distance = DistCalc(input_geometry[i].location);
// found new feasible maximum?
if (distance > max_int_distance && distance > douglas_peucker_thresholds[zoom_level])
{
farthest_element_index = i;
max_distance = distance;
farthest_entry_index = i;
max_int_distance = distance;
}
}
if (max_distance > douglas_peucker_thresholds[zoom_level])
// check if maximum violates a zoom level dependent threshold
if (max_int_distance > douglas_peucker_thresholds[zoom_level])
{
// mark idx as necessary
input_geometry[farthest_element_index].necessary = true;
if (1 < (farthest_element_index - pair.first))
input_geometry[farthest_entry_index].necessary = true;
if (1 < (farthest_entry_index - pair.first))
{
recursion_stack.emplace(pair.first, farthest_element_index);
recursion_stack.emplace(pair.first, farthest_entry_index);
}
if (1 < (pair.second - farthest_element_index))
if (1 < (pair.second - farthest_entry_index))
{
recursion_stack.emplace(farthest_element_index, pair.second);
recursion_stack.emplace(farthest_entry_index, pair.second);
}
}
}
+2 -6
View File
@@ -29,6 +29,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define DOUGLASPEUCKER_H_
#include <stack>
#include <utility>
#include <vector>
/* This class object computes the bitvector of indicating generalized input
@@ -38,22 +39,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* bit indicating if the points is present in the generalization.
* Note: points may also be pre-selected*/
struct FixedPointCoordinate;
struct SegmentInformation;
class DouglasPeucker
{
private:
std::vector<double> douglas_peucker_thresholds;
std::vector<int> douglas_peucker_thresholds;
typedef std::pair<unsigned, unsigned> GeometryRange;
// Stack to simulate the recursion
std::stack<GeometryRange> recursion_stack;
double ComputeDistance(const FixedPointCoordinate &point,
const FixedPointCoordinate &segA,
const FixedPointCoordinate &segB) const;
public:
DouglasPeucker();
void Run(std::vector<SegmentInformation> &input_geometry, const unsigned zoom_level);
+58 -31
View File
@@ -45,18 +45,36 @@ struct RouteNames
// construct routes names
template <class DataFacadeT, class SegmentT> struct ExtractRouteNames
{
private:
SegmentT PickNextLongestSegment(const std::vector<SegmentT> &segment_list,
const unsigned blocked_name_id) const
{
SegmentT result_segment;
result_segment.length = 0;
for (const SegmentT &segment : segment_list)
{
if (segment.name_id != blocked_name_id && segment.length > result_segment.length)
{
result_segment = segment;
}
}
return result_segment;
}
public:
RouteNames operator()(std::vector<SegmentT> &shortest_path_segments,
std::vector<SegmentT> &alternative_path_segments,
const DataFacadeT *facade)
const DataFacadeT *facade) const
{
RouteNames route_names;
SegmentT shortest_segment_1, shortest_segment_2;
SegmentT alternative_segment_1, alternative_segment_2;
auto length_comperator = [](SegmentT a, SegmentT b)
auto length_comperator = [](const SegmentT &a, const SegmentT &b)
{ return a.length > b.length; };
auto name_id_comperator = [](SegmentT a, SegmentT b)
auto name_id_comperator = [](const SegmentT &a, const SegmentT &b)
{ return a.name_id < b.name_id; };
if (shortest_path_segments.empty())
@@ -64,6 +82,7 @@ template <class DataFacadeT, class SegmentT> struct ExtractRouteNames
return route_names;
}
// pick the longest segment for the shortest path.
std::sort(shortest_path_segments.begin(), shortest_path_segments.end(), length_comperator);
shortest_segment_1 = shortest_path_segments[0];
if (!alternative_path_segments.empty())
@@ -71,52 +90,58 @@ template <class DataFacadeT, class SegmentT> struct ExtractRouteNames
std::sort(alternative_path_segments.begin(),
alternative_path_segments.end(),
length_comperator);
// also pick the longest segment for the alternative path
alternative_segment_1 = alternative_path_segments[0];
}
// compute the set difference (for shortest path) depending on names between shortest and
// alternative
std::vector<SegmentT> shortest_path_set_difference(shortest_path_segments.size());
std::vector<SegmentT> alternative_path_set_difference(alternative_path_segments.size());
std::sort(shortest_path_segments.begin(), shortest_path_segments.end(), name_id_comperator);
std::sort(alternative_path_segments.begin(), alternative_path_segments.end(), name_id_comperator);
std::set_difference(shortest_path_segments.begin(),
shortest_path_segments.end(),
alternative_path_segments.begin(),
alternative_path_segments.end(),
shortest_path_set_difference.begin(),
name_id_comperator);
int size_of_difference = shortest_path_set_difference.size();
if (size_of_difference)
{
int i = 0;
while (i < size_of_difference &&
shortest_path_set_difference[i].name_id == shortest_path_segments[0].name_id)
{
++i;
}
if (i < size_of_difference)
{
shortest_segment_2 = shortest_path_set_difference[i];
}
}
std::sort(shortest_path_set_difference.begin(),
shortest_path_set_difference.end(),
length_comperator);
shortest_segment_2 =
PickNextLongestSegment(shortest_path_set_difference, shortest_path_segments[0].name_id);
// compute the set difference (for alternative path) depending on names between shortest and
// alternative
// vectors are still sorted, no need to do again
BOOST_ASSERT(std::is_sorted(shortest_path_segments.begin(),
shortest_path_segments.end(),
name_id_comperator));
BOOST_ASSERT(std::is_sorted(alternative_path_segments.begin(),
alternative_path_segments.end(),
name_id_comperator));
std::vector<SegmentT> alternative_path_set_difference(alternative_path_segments.size());
std::set_difference(alternative_path_segments.begin(),
alternative_path_segments.end(),
shortest_path_segments.begin(),
shortest_path_segments.end(),
alternative_path_set_difference.begin(),
name_id_comperator);
size_of_difference = alternative_path_set_difference.size();
if (size_of_difference)
std::sort(alternative_path_set_difference.begin(),
alternative_path_set_difference.end(),
length_comperator);
if (!alternative_path_segments.empty())
{
int i = 0;
while (i < size_of_difference &&
alternative_path_set_difference[i].name_id ==
alternative_path_segments[0].name_id)
{
++i;
}
if (i < size_of_difference)
{
alternative_segment_2 = alternative_path_set_difference[i];
}
alternative_segment_2 = PickNextLongestSegment(alternative_path_set_difference,
alternative_path_segments[0].name_id);
}
// move the segments into the order in which they occur.
if (shortest_segment_1.position > shortest_segment_2.position)
{
std::swap(shortest_segment_1, shortest_segment_2);
@@ -125,6 +150,8 @@ template <class DataFacadeT, class SegmentT> struct ExtractRouteNames
{
std::swap(alternative_segment_1, alternative_segment_2);
}
// fetching names for the selected segments
route_names.shortest_path_name_1 =
facade->GetEscapedNameForNameID(shortest_segment_1.name_id);
route_names.shortest_path_name_2 =
+2 -2
View File
@@ -32,7 +32,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <iostream>
#if defined(__x86_64__)
#if defined(__x86_64__) && !defined(__MINGW64__)
#include <cpuid.h>
#else
#include <boost/crc.hpp> // for boost::crc_32_type
@@ -105,7 +105,7 @@ template <class ContainerT> class IteratorbasedCRC32
{
static const int SSE42_BIT = 0x00100000;
const unsigned ecx = cpuid();
const bool has_SSE42 = ecx & SSE42_BIT;
const bool has_SSE42 = (ecx & SSE42_BIT) != 0;
if (has_SSE42)
{
SimpleLogger().Write() << "using hardware based CRC32 computation";
+13 -46
View File
@@ -26,14 +26,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "PolylineCompressor.h"
#include "../Util/StringUtil.h"
#include "../DataStructures/SegmentInformation.h"
//TODO: return vector of start indices for each leg
#include <osrm/Coordinate.h>
void PolylineCompressor::encodeVectorSignedNumber(std::vector<int> &numbers, std::string &output)
const
{
const unsigned end = numbers.size();
const unsigned end = static_cast<unsigned>(numbers.size());
for (unsigned i = 0; i < end; ++i)
{
numbers[i] <<= 1;
@@ -42,7 +42,7 @@ void PolylineCompressor::encodeVectorSignedNumber(std::vector<int> &numbers, std
numbers[i] = ~(numbers[i]);
}
}
for (const int number: numbers)
for (const int number : numbers)
{
encodeNumber(number, output);
}
@@ -52,7 +52,7 @@ void PolylineCompressor::encodeNumber(int number_to_encode, std::string &output)
{
while (number_to_encode >= 0x20)
{
int next_value = (0x20 | (number_to_encode & 0x1f)) + 63;
const int next_value = (0x20 | (number_to_encode & 0x1f)) + 63;
output += static_cast<char>(next_value);
if (92 == next_value)
{
@@ -69,7 +69,8 @@ void PolylineCompressor::encodeNumber(int number_to_encode, std::string &output)
}
}
JSON::String PolylineCompressor::printEncodedString(const std::vector<SegmentInformation> &polyline) const
JSON::String PolylineCompressor::printEncodedString(const std::vector<SegmentInformation> &polyline)
const
{
std::string output;
std::vector<int> delta_numbers;
@@ -78,8 +79,10 @@ JSON::String PolylineCompressor::printEncodedString(const std::vector<SegmentInf
FixedPointCoordinate last_coordinate = polyline[0].location;
delta_numbers.emplace_back(last_coordinate.lat);
delta_numbers.emplace_back(last_coordinate.lon);
for (const auto & segment : polyline)
// iterate after skipping the first, already handled, segment
for (auto it = ++polyline.cbegin(); it != polyline.cend(); ++it)
{
const auto &segment = *it;
if (segment.necessary)
{
int lat_diff = segment.location.lat - last_coordinate.lat;
@@ -95,47 +98,11 @@ JSON::String PolylineCompressor::printEncodedString(const std::vector<SegmentInf
return return_value;
}
JSON::String PolylineCompressor::printEncodedString(const std::vector<FixedPointCoordinate> &polyline) const
{
std::string output;
std::vector<int> delta_numbers(2 * polyline.size());
if (!polyline.empty())
{
delta_numbers[0] = polyline[0].lat;
delta_numbers[1] = polyline[0].lon;
for (unsigned i = 1; i < polyline.size(); ++i)
{
int lat_diff = polyline[i].lat - polyline[i - 1].lat;
int lon_diff = polyline[i].lon - polyline[i - 1].lon;
delta_numbers[(2 * i)] = (lat_diff);
delta_numbers[(2 * i) + 1] = (lon_diff);
}
encodeVectorSignedNumber(delta_numbers, output);
}
JSON::String return_value(output);
return return_value;
}
JSON::Array PolylineCompressor::printUnencodedString(const std::vector<FixedPointCoordinate> &polyline) const
JSON::Array
PolylineCompressor::printUnencodedString(const std::vector<SegmentInformation> &polyline) const
{
JSON::Array json_geometry_array;
for( const auto & coordinate : polyline)
{
std::string tmp, output;
FixedPointCoordinate::convertInternalLatLonToString(coordinate.lat, tmp);
output += (tmp + ",");
FixedPointCoordinate::convertInternalLatLonToString(coordinate.lon, tmp);
output += tmp;
json_geometry_array.values.push_back(output);
}
return json_geometry_array;
}
JSON::Array PolylineCompressor::printUnencodedString(const std::vector<SegmentInformation> &polyline) const
{
JSON::Array json_geometry_array;
for( const auto & segment : polyline)
for (const auto &segment : polyline)
{
if (segment.necessary)
{
+2 -5
View File
@@ -28,8 +28,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef POLYLINECOMPRESSOR_H_
#define POLYLINECOMPRESSOR_H_
struct SegmentInformation;
#include "../DataStructures/JSONContainer.h"
#include "../DataStructures/SegmentInformation.h"
#include <string>
#include <vector>
@@ -44,10 +45,6 @@ class PolylineCompressor
public:
JSON::String printEncodedString(const std::vector<SegmentInformation> &polyline) const;
JSON::String printEncodedString(const std::vector<FixedPointCoordinate> &polyline) const;
JSON::Array printUnencodedString(const std::vector<FixedPointCoordinate> &polyline) const;
JSON::Array printUnencodedString(const std::vector<SegmentInformation> &polyline) const;
};
+22 -34
View File
@@ -37,6 +37,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../DataStructures/Restriction.h"
#include "../DataStructures/TurnInstructions.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../Util/StdHashExtensions.h"
@@ -152,52 +153,48 @@ class TarjanSCC
DeallocatingVector<TarjanEdge> edge_list;
for (const NodeBasedEdge &input_edge : input_edges)
{
if (input_edge.source() == input_edge.target())
if (input_edge.source == input_edge.target)
{
continue;
}
TarjanEdge edge;
if (input_edge.isForward())
if (input_edge.forward)
{
edge.source = input_edge.source();
edge.target = input_edge.target();
edge.data.forward = input_edge.isForward();
edge.data.backward = input_edge.isBackward();
edge.source = input_edge.source;
edge.target = input_edge.target;
edge.data.forward = input_edge.forward;
edge.data.backward = input_edge.backward;
}
else
{
edge.source = input_edge.target();
edge.target = input_edge.source();
edge.data.backward = input_edge.isForward();
edge.data.forward = input_edge.isBackward();
edge.source = input_edge.target;
edge.target = input_edge.source;
edge.data.backward = input_edge.forward;
edge.data.forward = input_edge.backward;
}
edge.data.distance = (std::max)((int)input_edge.weight(), 1);
edge.data.distance = (std::max)((int)input_edge.weight, 1);
BOOST_ASSERT(edge.data.distance > 0);
edge.data.shortcut = false;
// edge.data.roundabout = input_edge.isRoundabout();
// edge.data.ignoreInGrid = input_edge.ignoreInGrid();
edge.data.name_id = input_edge.name();
edge.data.type = input_edge.type();
// edge.data.isAccessRestricted = input_edge.isAccessRestricted();
edge.data.name_id = input_edge.name_id;
edge.data.type = input_edge.type;
edge.data.reversedEdge = false;
edge_list.push_back(edge);
if (edge.data.backward)
{
std::swap(edge.source, edge.target);
edge.data.forward = input_edge.isBackward();
edge.data.backward = input_edge.isForward();
edge.data.forward = input_edge.backward;
edge.data.backward = input_edge.forward;
edge.data.reversedEdge = true;
edge_list.push_back(edge);
}
}
std::vector<NodeBasedEdge>().swap(input_edges);
input_edges.shrink_to_fit();
BOOST_ASSERT_MSG(0 == input_edges.size() && 0 == input_edges.capacity(),
"input edge vector not properly deallocated");
std::sort(edge_list.begin(), edge_list.end());
m_node_based_graph = std::make_shared<TarjanDynamicGraph>(number_of_nodes, edge_list);
}
@@ -217,20 +214,20 @@ class TarjanSCC
const char *pszDriverName = "ESRI Shapefile";
OGRSFDriver *poDriver =
OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(pszDriverName);
if (NULL == poDriver)
if (nullptr == poDriver)
{
throw OSRMException("ESRI Shapefile driver not available");
}
OGRDataSource *poDS = poDriver->CreateDataSource("component.shp", NULL);
OGRDataSource *poDS = poDriver->CreateDataSource("component.shp", nullptr);
if (NULL == poDS)
if (nullptr == poDS)
{
throw OSRMException("Creation of output file failed");
}
OGRLayer *poLayer = poDS->CreateLayer("component", NULL, wkbLineString, NULL);
OGRLayer *poLayer = poDS->CreateLayer("component", nullptr, wkbLineString, nullptr);
if (NULL == poLayer)
if (nullptr == poLayer)
{
throw OSRMException("Layer creation failed.");
}
@@ -328,15 +325,6 @@ class TarjanSCC
SimpleLogger().Write() << "identified: " << component_size_vector.size()
<< " many components, marking small components";
// TODO/C++11: prime candidate for lambda function
// unsigned size_one_counter = 0;
// for (unsigned i = 0, end = component_size_vector.size(); i < end; ++i)
// {
// if (1 == component_size_vector[i])
// {
// ++size_one_counter;
// }
// }
unsigned size_one_counter = std::count_if(component_size_vector.begin(),
component_size_vector.end(),
[] (unsigned value) { return 1 == value;});
+69 -44
View File
@@ -8,8 +8,6 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
include(GetGitRevisionDescription)
git_describe(GIT_DESCRIPTION)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
set(bitness 32)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(bitness 64)
@@ -18,18 +16,23 @@ else()
message(WARNING "Building on a 32 bit system is unsupported")
endif()
if (WIN32 AND MSVC_VERSION LESS 1800)
message(FATAL_ERROR "Building with Microsoft compiler needs Visual Studio 2013 or later (Express version works too)")
endif()
OPTION(WITH_TOOLS "Build ORSM tools" OFF)
include_directories(${CMAKE_SOURCE_DIR}/Include/)
add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/Util/UUID.cpp UUID.cpp.alwaysbuild
add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/Util/FingerPrint.cpp FingerPrint.cpp.alwaysbuild
COMMAND ${CMAKE_COMMAND} -DSOURCE_DIR=${CMAKE_SOURCE_DIR}
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/UUID-Config.cmake
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/FingerPrint-Config.cmake
DEPENDS
${CMAKE_SOURCE_DIR}/Util/UUID.cpp.in
${CMAKE_SOURCE_DIR}/cmake/UUID-Config.cmake
COMMENT "Configuring UUID.cpp"
${CMAKE_SOURCE_DIR}/Util/FingerPrint.cpp.in
COMMENT "Configuring FingerPrint.cpp"
VERBATIM)
add_custom_target(UUIDConfigure DEPENDS ${CMAKE_SOURCE_DIR}/Util/UUID.cpp)
add_custom_target(FingerPrintConfigure DEPENDS ${CMAKE_SOURCE_DIR}/Util/FingerPrint.cpp)
set(BOOST_COMPONENTS date_time filesystem iostreams program_options regex system thread)
@@ -38,6 +41,8 @@ configure_file(
${CMAKE_SOURCE_DIR}/Util/GitDescription.cpp
)
file(GLOB ExtractorGlob Extractor/*.cpp)
file(GLOB ImporterGlob DataStructures/Import*.cpp)
add_library(IMPORT STATIC ${ImporterGlob})
set(ExtractorSources extractor.cpp ${ExtractorGlob})
add_executable(osrm-extract ${ExtractorSources})
@@ -63,14 +68,12 @@ set(
${HttpGlob}
)
add_library(COORDLIB STATIC ${CoordinateGlob})
add_library(OSRM ${OSRMSources} Util/GitDescription.cpp Util/UUID.cpp)
add_library(UUID STATIC Util/UUID.cpp)
add_library(FINGERPRINT STATIC Util/FingerPrint.cpp)
add_library(OSRM ${OSRMSources} Util/GitDescription.cpp Util/FingerPrint.cpp)
add_library(GITDESCRIPTION STATIC Util/GitDescription.cpp)
add_dependencies(UUID UUIDConfigure)
add_dependencies(GITDESCRIPTION GIT_DESCRIPTION)
add_dependencies(FINGERPRINT FingerPrintConfigure)
add_executable(osrm-routed routed.cpp ${ServerGlob})
set_target_properties(osrm-routed PROPERTIES COMPILE_FLAGS -DROUTED)
add_executable(osrm-datastore datastore.cpp)
# Check the release mode
@@ -106,16 +109,26 @@ endif()
# Configuring compilers
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
# using Clang
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wunreachable-code -Wno-unknown-pragmas -Wno-unneeded-internal-declaration -pedantic -fPIC")
message(STATUS "OpenMP parallelization not available using clang++")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wunreachable-code -pedantic -fPIC")
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
# using GCC
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fopenmp -pedantic -fPIC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic -fPIC")
if (WIN32) # using mingw
add_definitions(-DM_PI=3.141592653589793238462643383) # define M_PI
add_definitions(-DWIN32)
SET(OPTIONAL_SOCKET_LIBS ws2_32 wsock32)
SET(OPTIONAL_OMP_LIB gomp)
endif()
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
# using Intel C++
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-intel -wd10237 -Wall -openmp -ipo -fPIC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-intel -wd10237 -Wall -ipo -fPIC")
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
# using Visual Studio C++
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} date_time chrono zlib)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
add_definitions(-DNOMINMAX) # avoid min and max macros that can break compilation
add_definitions(-D_USE_MATH_DEFINES) # define M_PI
add_definitions(-D_WIN32_WINNT=0x0501)
endif()
# disable partitioning of LTO process when possible (fixes Debian issues)
@@ -131,10 +144,9 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${LTO_FLAGS} ${LTO_P
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${LTO_FLAGS} ${LTO_PARTITION_FLAGS}")
# Activate C++11
ADD_DEFINITIONS(
-std=c++11 # Or -std=c++0x
# Other flags
)
if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
ADD_DEFINITIONS(-std=c++11)
endif()
# Configuring other platform dependencies
if(APPLE)
@@ -142,10 +154,6 @@ if(APPLE)
message(STATUS "Set Architecture to x64 on OS X")
exec_program(uname ARGS -v OUTPUT_VARIABLE DARWIN_VERSION)
string(REGEX MATCH "[0-9]+" DARWIN_VERSION ${DARWIN_VERSION})
# if(DARWIN_VERSION GREATER 12 AND NOT OSXLIBSTD)
# message(STATUS "Activating -std=c++11 flag for >= OS X 10.9")
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
# endif()
if(OSXLIBSTD)
message(STATUS "linking against ${OSXLIBSTD}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=${OSXLIBSTD}")
@@ -156,6 +164,7 @@ if(APPLE)
endif()
if(UNIX AND NOT APPLE)
target_link_libraries(osrm-prepare rt)
target_link_libraries(osrm-datastore rt)
target_link_libraries(OSRM rt)
endif()
@@ -169,13 +178,25 @@ endif()
include_directories(${Boost_INCLUDE_DIRS})
target_link_libraries(OSRM ${Boost_LIBRARIES} COORDLIB)
target_link_libraries(osrm-extract ${Boost_LIBRARIES} UUID GITDESCRIPTION COORDLIB)
target_link_libraries(osrm-prepare ${Boost_LIBRARIES} UUID GITDESCRIPTION COORDLIB)
target_link_libraries(osrm-routed ${Boost_LIBRARIES} OSRM UUID GITDESCRIPTION)
target_link_libraries(osrm-datastore ${Boost_LIBRARIES} UUID GITDESCRIPTION COORDLIB)
target_link_libraries(osrm-extract ${Boost_LIBRARIES} FINGERPRINT GITDESCRIPTION COORDLIB IMPORT)
target_link_libraries(osrm-prepare ${Boost_LIBRARIES} FINGERPRINT GITDESCRIPTION COORDLIB IMPORT)
target_link_libraries(osrm-routed ${Boost_LIBRARIES} ${OPTIONAL_SOCKET_LIBS} OSRM FINGERPRINT GITDESCRIPTION)
target_link_libraries(osrm-datastore ${Boost_LIBRARIES} FINGERPRINT GITDESCRIPTION COORDLIB)
find_package(Threads REQUIRED)
target_link_libraries(osrm-extract ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(osrm-extract ${CMAKE_THREAD_LIBS_INIT} ${OPTIONAL_OMP_LIB})
target_link_libraries(osrm-datastore ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(OSRM ${CMAKE_THREAD_LIBS_INIT})
find_package(TBB REQUIRED)
if(WIN32 AND CMAKE_BUILD_TYPE MATCHES Debug)
set(TBB_LIBRARIES ${TBB_DEBUG_LIBRARIES})
endif()
target_link_libraries(osrm-datastore ${TBB_LIBRARIES})
target_link_libraries(osrm-extract ${TBB_LIBRARIES})
target_link_libraries(osrm-prepare ${TBB_LIBRARIES})
target_link_libraries(osrm-routed ${TBB_LIBRARIES})
include_directories(${TBB_INCLUDE_DIR})
find_package(Lua52)
if(NOT LUA52_FOUND)
@@ -189,6 +210,11 @@ else()
endif()
endif()
find_package( Luabind REQUIRED )
include_directories(${LUABIND_INCLUDE_DIR})
target_link_libraries(osrm-extract ${LUABIND_LIBRARY})
target_link_libraries(osrm-prepare ${LUABIND_LIBRARY})
if( LUAJIT_FOUND )
target_link_libraries(osrm-extract ${LUAJIT_LIBRARIES})
target_link_libraries(osrm-prepare ${LUAJIT_LIBRARIES})
@@ -202,11 +228,6 @@ find_package(LibXml2 REQUIRED)
include_directories(${LIBXML2_INCLUDE_DIR})
target_link_libraries(osrm-extract ${LIBXML2_LIBRARIES})
find_package( Luabind REQUIRED )
include_directories(${LUABIND_INCLUDE_DIR})
target_link_libraries(osrm-extract ${LUABIND_LIBRARY})
target_link_libraries(osrm-prepare ${LUABIND_LIBRARY})
find_package( STXXL REQUIRED )
include_directories(${STXXL_INCLUDE_DIR})
target_link_libraries(OSRM ${STXXL_LIBRARY})
@@ -237,20 +258,24 @@ if(WITH_TOOLS)
find_package(GDAL)
if(GDAL_FOUND)
add_executable(osrm-components Tools/components.cpp)
target_link_libraries(osrm-components ${TBB_LIBRARIES} IMPORT)
include_directories(${GDAL_INCLUDE_DIR})
target_link_libraries(
osrm-components
${GDAL_LIBRARIES} ${Boost_LIBRARIES} UUID GITDESCRIPTION COORDLIB)
${GDAL_LIBRARIES} ${Boost_LIBRARIES} FINGERPRINT GITDESCRIPTION COORDLIB)
else()
message(FATAL_ERROR "libgdal and/or development headers not found")
endif()
add_executable(osrm-cli Tools/simpleclient.cpp)
target_link_libraries(osrm-cli ${Boost_LIBRARIES} OSRM UUID GITDESCRIPTION)
add_executable(osrm-io-benchmark Tools/io-benchmark.cpp)
target_link_libraries(osrm-io-benchmark ${Boost_LIBRARIES} GITDESCRIPTION)
add_executable(osrm-unlock-all Tools/unlock_all_mutexes.cpp)
target_link_libraries(osrm-unlock-all ${Boost_LIBRARIES} GITDESCRIPTION)
if(UNIX AND NOT APPLE)
target_link_libraries(osrm-unlock-all rt)
endif()
target_link_libraries(osrm-cli ${Boost_LIBRARIES} ${OPTIONAL_SOCKET_LIBS} OSRM FINGERPRINT GITDESCRIPTION)
target_link_libraries(osrm-cli ${TBB_LIBRARIES})
add_executable(osrm-io-benchmark Tools/io-benchmark.cpp)
target_link_libraries(osrm-io-benchmark ${Boost_LIBRARIES} GITDESCRIPTION)
add_executable(osrm-unlock-all Tools/unlock_all_mutexes.cpp)
target_link_libraries(osrm-unlock-all ${Boost_LIBRARIES} GITDESCRIPTION)
if(UNIX AND NOT APPLE)
target_link_libraries(osrm-unlock-all rt)
endif()
endif()
file(GLOB InstallGlob Include/osrm/*.h Library/OSRM.h)
+159 -116
View File
@@ -35,12 +35,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../DataStructures/Percent.h"
#include "../DataStructures/XORFastHash.h"
#include "../DataStructures/XORFastHashStorage.h"
#include "../Util/OpenMPWrapper.h"
#include "../Util/SimpleLogger.h"
#include "../Util/StringUtil.h"
#include "../Util/TimingUtil.h"
#include <boost/assert.hpp>
#include <tbb/enumerable_thread_specific.h>
#include <tbb/parallel_for.h>
#include <tbb/parallel_sort.h>
#include <algorithm>
#include <limits>
#include <vector>
@@ -125,6 +129,28 @@ class Contractor
bool is_independent : 1;
};
struct ThreadDataContainer
{
ThreadDataContainer(int number_of_nodes) : number_of_nodes(number_of_nodes) {}
inline ContractorThreadData* getThreadData()
{
bool exists = false;
auto& ref = data.local(exists);
if (!exists)
{
ref = std::make_shared<ContractorThreadData>(number_of_nodes);
}
return ref.get();
}
int number_of_nodes;
typedef tbb::enumerable_thread_specific<std::shared_ptr<ContractorThreadData>> EnumerableThreadData;
EnumerableThreadData data;
};
public:
template <class ContainerT> Contractor(int nodes, ContainerT &input_edge_list)
{
@@ -138,14 +164,15 @@ class Contractor
ContractorEdge new_edge;
while (diter != dend)
{
new_edge.source = diter->source();
new_edge.target = diter->target();
new_edge.data = ContractorEdgeData((std::max)((int)diter->weight(), 1),
1,
diter->id(),
false,
diter->isForward(),
diter->isBackward());
new_edge.source = diter->source;
new_edge.target = diter->target;
new_edge.data = { static_cast<unsigned int>(std::max(diter->weight, 1)),
1,
diter->edge_id,
false,
diter->forward,
diter->backward};
BOOST_ASSERT_MSG(new_edge.data.distance > 0, "edge distance < 1");
#ifndef NDEBUG
if (new_edge.data.distance > 24 * 60 * 60 * 10)
@@ -156,14 +183,15 @@ class Contractor
#endif
edges.push_back(new_edge);
std::swap(new_edge.source, new_edge.target);
new_edge.data.forward = diter->isBackward();
new_edge.data.backward = diter->isForward();
new_edge.data.forward = diter->backward;
new_edge.data.backward = diter->forward;
edges.push_back(new_edge);
++diter;
}
// clear input vector and trim the current set of edges with the well-known swap trick
// clear input vector
edges.shrink_to_fit();
input_edge_list.clear();
sort(edges.begin(), edges.end());
tbb::parallel_sort(edges.begin(), edges.end());
NodeID edge = 0;
for (NodeID i = 0; i < edges.size();)
{
@@ -262,39 +290,51 @@ class Contractor
void Run()
{
// for the preperation we can use a big grain size, which is much faster (probably cache)
constexpr size_t InitGrainSize = 100000;
constexpr size_t PQGrainSize = 100000;
// auto_partitioner will automatically increase the blocksize if we have
// a lot of data. It is *important* for the last loop iterations
// (which have a very small dataset) that it is devisible.
constexpr size_t IndependentGrainSize = 1;
constexpr size_t ContractGrainSize = 1;
constexpr size_t NeighboursGrainSize = 1;
constexpr size_t DeleteGrainSize = 1;
const NodeID number_of_nodes = contractor_graph->GetNumberOfNodes();
Percent p(number_of_nodes);
const unsigned thread_count = omp_get_max_threads();
std::vector<ContractorThreadData *> thread_data_list;
for (unsigned thread_id = 0; thread_id < thread_count; ++thread_id)
{
thread_data_list.push_back(new ContractorThreadData(number_of_nodes));
}
std::cout << "Contractor is using " << thread_count << " threads" << std::endl;
ThreadDataContainer thread_data_list(number_of_nodes);
NodeID number_of_contracted_nodes = 0;
std::vector<RemainingNodeData> remaining_nodes(number_of_nodes);
std::vector<float> node_priorities(number_of_nodes);
std::vector<NodePriorityData> node_data(number_of_nodes);
// initialize priorities in parallel
#pragma omp parallel for schedule(guided)
for (int x = 0; x < (int)number_of_nodes; ++x)
{
remaining_nodes[x].id = x;
}
// initialize priorities in parallel
tbb::parallel_for(tbb::blocked_range<int>(0, number_of_nodes, InitGrainSize),
[&remaining_nodes](const tbb::blocked_range<int>& range)
{
for (int x = range.begin(); x != range.end(); ++x)
{
remaining_nodes[x].id = x;
}
}
);
std::cout << "initializing elimination PQ ..." << std::flush;
#pragma omp parallel
{
ContractorThreadData *data = thread_data_list[omp_get_thread_num()];
#pragma omp parallel for schedule(guided)
for (int x = 0; x < (int)number_of_nodes; ++x)
tbb::parallel_for(tbb::blocked_range<int>(0, number_of_nodes, PQGrainSize),
[this, &node_priorities, &node_data, &thread_data_list](const tbb::blocked_range<int>& range)
{
node_priorities[x] = EvaluateNodePriority(data, &node_data[x], x);
ContractorThreadData *data = thread_data_list.getThreadData();
for (int x = range.begin(); x != range.end(); ++x)
{
node_priorities[x] = this->EvaluateNodePriority(data, &node_data[x], x);
}
}
}
);
std::cout << "ok" << std::endl << "preprocessing " << number_of_nodes << " nodes ..."
<< std::flush;
@@ -309,11 +349,7 @@ class Contractor
std::cout << " [flush " << number_of_contracted_nodes << " nodes] " << std::flush;
// Delete old heap data to free memory that we need for the coming operations
for (ContractorThreadData *data : thread_data_list)
{
delete data;
}
thread_data_list.clear();
thread_data_list.data.clear();
// Create new priority array
std::vector<float> new_node_priority(remaining_nodes.size());
@@ -339,8 +375,8 @@ class Contractor
// walk over all nodes
for (unsigned i = 0; i < contractor_graph->GetNumberOfNodes(); ++i)
{
const NodeID start = i;
for (auto current_edge : contractor_graph->GetAdjacentEdgeRange(start))
const NodeID source = i;
for (auto current_edge : contractor_graph->GetAdjacentEdgeRange(source))
{
ContractorGraph::EdgeData &data =
contractor_graph->GetEdgeData(current_edge);
@@ -349,7 +385,7 @@ class Contractor
{
// Save edges of this node w/o renumbering.
temporary_storage.WriteToSlot(
edge_storage_slot, (char *)&start, sizeof(NodeID));
edge_storage_slot, (char *)&source, sizeof(NodeID));
temporary_storage.WriteToSlot(
edge_storage_slot, (char *)&target, sizeof(NodeID));
temporary_storage.WriteToSlot(edge_storage_slot,
@@ -362,12 +398,12 @@ class Contractor
// node is not yet contracted.
// add (renumbered) outgoing edges to new DynamicGraph.
ContractorEdge new_edge;
new_edge.source = new_node_id_from_orig_id_map[start];
new_edge.source = new_node_id_from_orig_id_map[source];
new_edge.target = new_node_id_from_orig_id_map[target];
new_edge.data = data;
new_edge.data.is_original_via_node_ID = true;
BOOST_ASSERT_MSG(UINT_MAX != new_node_id_from_orig_id_map[start],
"new start id not resolveable");
BOOST_ASSERT_MSG(UINT_MAX != new_node_id_from_orig_id_map[source],
"new source id not resolveable");
BOOST_ASSERT_MSG(UINT_MAX != new_node_id_from_orig_id_map[target],
"new target id not resolveable");
new_edge_set.push_back(new_edge);
@@ -382,7 +418,8 @@ class Contractor
// Replace old priorities array by new one
node_priorities.swap(new_node_priority);
// Delete old node_priorities vector
std::vector<float>().swap(new_node_priority);
new_node_priority.clear();
new_node_priority.shrink_to_fit();
// old Graph is removed
contractor_graph.reset();
@@ -396,61 +433,69 @@ class Contractor
// INFO: MAKE SURE THIS IS THE LAST OPERATION OF THE FLUSH!
// reinitialize heaps and ThreadData objects with appropriate size
for (unsigned thread_id = 0; thread_id < thread_count; ++thread_id)
{
thread_data_list.push_back(
new ContractorThreadData(contractor_graph->GetNumberOfNodes()));
}
thread_data_list.number_of_nodes = contractor_graph->GetNumberOfNodes();
}
const int last = (int)remaining_nodes.size();
#pragma omp parallel
{
// determine independent node set
ContractorThreadData *const data = thread_data_list[omp_get_thread_num()];
#pragma omp for schedule(guided)
for (int i = 0; i < last; ++i)
tbb::parallel_for(tbb::blocked_range<int>(0, last, IndependentGrainSize),
[this, &node_priorities, &remaining_nodes, &thread_data_list](const tbb::blocked_range<int>& range)
{
const NodeID node = remaining_nodes[i].id;
remaining_nodes[i].is_independent =
IsNodeIndependent(node_priorities, data, node);
ContractorThreadData *data = thread_data_list.getThreadData();
// determine independent node set
for (int i = range.begin(); i != range.end(); ++i)
{
const NodeID node = remaining_nodes[i].id;
remaining_nodes[i].is_independent =
this->IsNodeIndependent(node_priorities, data, node);
}
}
}
);
const auto first = stable_partition(remaining_nodes.begin(),
remaining_nodes.end(),
[](RemainingNodeData node_data)
{ return !node_data.is_independent; });
const int first_independent_node = first - remaining_nodes.begin();
// contract independent nodes
#pragma omp parallel
{
ContractorThreadData *data = thread_data_list[omp_get_thread_num()];
#pragma omp for schedule(guided) nowait
for (int position = first_independent_node; position < last; ++position)
{
NodeID x = remaining_nodes[position].id;
ContractNode<false>(data, x);
}
const int first_independent_node = static_cast<int>(first - remaining_nodes.begin());
std::sort(data->inserted_edges.begin(), data->inserted_edges.end());
}
#pragma omp parallel
{
ContractorThreadData *data = thread_data_list[omp_get_thread_num()];
#pragma omp for schedule(guided) nowait
for (int position = first_independent_node; position < last; ++position)
// contract independent nodes
tbb::parallel_for(tbb::blocked_range<int>(first_independent_node, last, ContractGrainSize),
[this, &remaining_nodes, &thread_data_list](const tbb::blocked_range<int>& range)
{
NodeID x = remaining_nodes[position].id;
DeleteIncomingEdges(data, x);
ContractorThreadData *data = thread_data_list.getThreadData();
for (int position = range.begin(); position != range.end(); ++position)
{
const NodeID x = remaining_nodes[position].id;
this->ContractNode<false>(data, x);
}
}
}
// insert new edges
for (unsigned thread_id = 0; thread_id < thread_count; ++thread_id)
{
ContractorThreadData &data = *thread_data_list[thread_id];
for (const ContractorEdge &edge : data.inserted_edges)
);
// make sure we really sort each block
tbb::parallel_for(thread_data_list.data.range(),
[&](const ThreadDataContainer::EnumerableThreadData::range_type& range)
{
auto current_edge_ID = contractor_graph->FindEdge(edge.source, edge.target);
for (auto& data : range)
std::sort(data->inserted_edges.begin(),
data->inserted_edges.end());
}
);
tbb::parallel_for(tbb::blocked_range<int>(first_independent_node, last, DeleteGrainSize),
[this, &remaining_nodes, &thread_data_list](const tbb::blocked_range<int>& range)
{
ContractorThreadData *data = thread_data_list.getThreadData();
for (int position = range.begin(); position != range.end(); ++position)
{
const NodeID x = remaining_nodes[position].id;
this->DeleteIncomingEdges(data, x);
}
}
);
// insert new edges
for (auto& data : thread_data_list.data)
{
for (const ContractorEdge &edge : data->inserted_edges)
{
const EdgeID current_edge_ID = contractor_graph->FindEdge(edge.source, edge.target);
if (current_edge_ID < contractor_graph->EndEdges(edge.source))
{
ContractorGraph::EdgeData &current_data =
@@ -466,23 +511,25 @@ class Contractor
}
contractor_graph->InsertEdge(edge.source, edge.target, edge.data);
}
data.inserted_edges.clear();
data->inserted_edges.clear();
}
// update priorities
#pragma omp parallel
{
ContractorThreadData *data = thread_data_list[omp_get_thread_num()];
#pragma omp for schedule(guided) nowait
for (int position = first_independent_node; position < last; ++position)
tbb::parallel_for(tbb::blocked_range<int>(first_independent_node, last, NeighboursGrainSize),
[this, &remaining_nodes, &node_priorities, &node_data, &thread_data_list](const tbb::blocked_range<int>& range)
{
NodeID x = remaining_nodes[position].id;
UpdateNodeNeighbours(node_priorities, node_data, data, x);
ContractorThreadData *data = thread_data_list.getThreadData();
for (int position = range.begin(); position != range.end(); ++position)
{
NodeID x = remaining_nodes[position].id;
this->UpdateNodeNeighbours(node_priorities, node_data, data, x);
}
}
}
);
// remove contracted nodes from the pool
number_of_contracted_nodes += last - first_independent_node;
remaining_nodes.resize(first_independent_node);
std::vector<RemainingNodeData>(remaining_nodes).swap(remaining_nodes);
remaining_nodes.shrink_to_fit();
// unsigned maxdegree = 0;
// unsigned avgdegree = 0;
// unsigned mindegree = UINT_MAX;
@@ -510,18 +557,15 @@ class Contractor
p.printStatus(number_of_contracted_nodes);
}
for (ContractorThreadData *data : thread_data_list)
{
delete data;
}
thread_data_list.clear();
thread_data_list.data.clear();
}
template <class Edge> inline void GetEdges(DeallocatingVector<Edge> &edges)
{
Percent p(contractor_graph->GetNumberOfNodes());
SimpleLogger().Write() << "Getting edges of minimized graph";
NodeID number_of_nodes = contractor_graph->GetNumberOfNodes();
const NodeID number_of_nodes = contractor_graph->GetNumberOfNodes();
if (contractor_graph->GetNumberOfNodes())
{
Edge new_edge;
@@ -569,18 +613,18 @@ class Contractor
BOOST_ASSERT(0 == orig_node_id_to_new_id_map.capacity());
TemporaryStorage &temporary_storage = TemporaryStorage::GetInstance();
// loads edges of graph before renumbering, no need for further numbering action.
NodeID start;
NodeID source;
NodeID target;
ContractorGraph::EdgeData data;
Edge restored_edge;
for (unsigned i = 0; i < temp_edge_counter; ++i)
{
temporary_storage.ReadFromSlot(edge_storage_slot, (char *)&start, sizeof(NodeID));
temporary_storage.ReadFromSlot(edge_storage_slot, (char *)&source, sizeof(NodeID));
temporary_storage.ReadFromSlot(edge_storage_slot, (char *)&target, sizeof(NodeID));
temporary_storage.ReadFromSlot(
edge_storage_slot, (char *)&data, sizeof(ContractorGraph::EdgeData));
restored_edge.source = start;
restored_edge.source = source;
restored_edge.target = target;
restored_edge.data.distance = data.distance;
restored_edge.data.shortcut = data.shortcut;
@@ -672,14 +716,14 @@ class Contractor
float result;
if (0 == (stats.edges_deleted_count * stats.original_edges_deleted_count))
{
result = 1 * node_data->depth;
result = 1.f * node_data->depth;
}
else
{
result = 2 * (((float)stats.edges_added_count) / stats.edges_deleted_count) +
4 * (((float)stats.original_edges_added_count) /
stats.original_edges_deleted_count) +
1 * node_data->depth;
result = 2.f * (((float)stats.edges_added_count) / stats.edges_deleted_count) +
4.f * (((float)stats.original_edges_added_count) /
stats.original_edges_deleted_count) +
1.f * node_data->depth;
}
BOOST_ASSERT(result >= 0);
return result;
@@ -687,7 +731,7 @@ class Contractor
template <bool RUNSIMULATION>
inline bool
ContractNode(ContractorThreadData *data, NodeID node, ContractionStats *stats = NULL)
ContractNode(ContractorThreadData *data, NodeID node, ContractionStats *stats = nullptr)
{
ContractorHeap &heap = data->heap;
int inserted_edges_size = data->inserted_edges.size();
@@ -699,7 +743,7 @@ class Contractor
const NodeID source = contractor_graph->GetTarget(in_edge);
if (RUNSIMULATION)
{
BOOST_ASSERT(stats != NULL);
BOOST_ASSERT(stats != nullptr);
++stats->edges_deleted_count;
stats->original_edges_deleted_count += in_data.originalEdges;
}
@@ -752,7 +796,7 @@ class Contractor
{
if (RUNSIMULATION)
{
BOOST_ASSERT(stats != NULL);
BOOST_ASSERT(stats != nullptr);
stats->edges_added_count += 2;
stats->original_edges_added_count +=
2 * (out_data.originalEdges + in_data.originalEdges);
@@ -769,7 +813,6 @@ class Contractor
true,
true,
false);
;
inserted_edges.push_back(new_edge);
std::swap(new_edge.source, new_edge.target);
new_edge.data.forward = false;
+15 -11
View File
@@ -155,7 +155,7 @@ EdgeBasedGraphFactory::InsertEdgeBasedNode(NodeID u, NodeID v, EdgeID e1, bool b
const unsigned geometry_size = forward_geometry.size();
BOOST_ASSERT(geometry_size > 1);
NodeID current_edge_start_coordinate_id = u;
NodeID current_edge_source_coordinate_id = u;
if (forward_data.edgeBasedNodeID != SPECIAL_NODEID)
{
@@ -169,15 +169,15 @@ EdgeBasedGraphFactory::InsertEdgeBasedNode(NodeID u, NodeID v, EdgeID e1, bool b
// traverse arrays from start and end respectively
for (unsigned i = 0; i < geometry_size; ++i)
{
BOOST_ASSERT(current_edge_start_coordinate_id ==
BOOST_ASSERT(current_edge_source_coordinate_id ==
reverse_geometry[geometry_size - 1 - i].first);
const NodeID current_edge_target_coordinate_id = forward_geometry[i].first;
BOOST_ASSERT(current_edge_target_coordinate_id != current_edge_start_coordinate_id);
BOOST_ASSERT(current_edge_target_coordinate_id != current_edge_source_coordinate_id);
// build edges
m_edge_based_node_list.emplace_back(forward_data.edgeBasedNodeID,
reverse_data.edgeBasedNodeID,
current_edge_start_coordinate_id,
current_edge_source_coordinate_id,
current_edge_target_coordinate_id,
forward_data.nameID,
forward_geometry[i].second,
@@ -187,7 +187,7 @@ EdgeBasedGraphFactory::InsertEdgeBasedNode(NodeID u, NodeID v, EdgeID e1, bool b
m_geometry_compressor.GetPositionForID(e1),
i,
belongs_to_tiny_cc);
current_edge_start_coordinate_id = current_edge_target_coordinate_id;
current_edge_source_coordinate_id = current_edge_target_coordinate_id;
BOOST_ASSERT(m_edge_based_node_list.back().IsCompressed());
@@ -198,7 +198,7 @@ EdgeBasedGraphFactory::InsertEdgeBasedNode(NodeID u, NodeID v, EdgeID e1, bool b
v != m_edge_based_node_list.back().u);
}
BOOST_ASSERT(current_edge_start_coordinate_id == v);
BOOST_ASSERT(current_edge_source_coordinate_id == v);
BOOST_ASSERT(m_edge_based_node_list.back().IsCompressed());
}
else
@@ -244,6 +244,9 @@ EdgeBasedGraphFactory::InsertEdgeBasedNode(NodeID u, NodeID v, EdgeID e1, bool b
void EdgeBasedGraphFactory::FlushVectorToStream(
std::ofstream &edge_data_file, std::vector<OriginalEdgeData> &original_edge_data_vector) const
{
if (original_edge_data_vector.empty()) {
return;
}
edge_data_file.write((char *)&(original_edge_data_vector[0]),
original_edge_data_vector.size() * sizeof(OriginalEdgeData));
original_edge_data_vector.clear();
@@ -273,10 +276,10 @@ void EdgeBasedGraphFactory::Run(const std::string &original_edge_data_filename,
m_geometry_compressor.SerializeInternalVector(geometry_filename);
SimpleLogger().Write() << "Timing statistics for edge-expanded graph:";
SimpleLogger().Write() << "Geometry compression: " << TIMER_MSEC(geometry)*0.001 << "s";
SimpleLogger().Write() << "Renumbering edges: " << TIMER_MSEC(renumber)*0.001 << "s";
SimpleLogger().Write() << "Generating nodes: " << TIMER_MSEC(generate_nodes)*0.001 << "s";
SimpleLogger().Write() << "Generating edges: " << TIMER_MSEC(generate_edges)*0.001 << "s";
SimpleLogger().Write() << "Geometry compression: " << TIMER_SEC(geometry) << "s";
SimpleLogger().Write() << "Renumbering edges: " << TIMER_SEC(renumber) << "s";
SimpleLogger().Write() << "Generating nodes: " << TIMER_SEC(generate_nodes) << "s";
SimpleLogger().Write() << "Generating edges: " << TIMER_SEC(generate_edges) << "s";
}
void EdgeBasedGraphFactory::CompressGeometry()
@@ -306,7 +309,7 @@ void EdgeBasedGraphFactory::CompressGeometry()
}
// check if v is a via node for a turn restriction, i.e. a 'directed' barrier node
if (m_restriction_map->IsNodeAViaNode(v))
if (m_restriction_map->IsViaNode(v))
{
continue;
}
@@ -605,6 +608,7 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edg
(to_node_of_only_restriction == SPECIAL_NODEID) &&
(w != to_node_of_only_restriction))
{
// We are at an only_-restriction but not at the right turn.
++restricted_turns_counter;
continue;
}
-2
View File
@@ -32,12 +32,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../typedefs.h"
#include "../DataStructures/DeallocatingVector.h"
#include "../DataStructures/DynamicGraph.h"
#include "../DataStructures/EdgeBasedNode.h"
#include "../DataStructures/OriginalEdgeData.h"
#include "../DataStructures/QueryNode.h"
#include "../DataStructures/TurnInstructions.h"
#include "../DataStructures/Restriction.h"
#include "../DataStructures/NodeBasedGraph.h"
#include "../DataStructures/RestrictionMap.h"
#include "GeometryCompressor.h"
+15 -13
View File
@@ -35,8 +35,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <limits>
#include <string>
int current_free_list_maximum = 0;
int UniqueNumber() { return ++current_free_list_maximum; }
int free_list_maximum = 0;
int UniqueNumber() { return ++free_list_maximum; }
GeometryCompressor::GeometryCompressor()
{
@@ -49,14 +49,15 @@ void GeometryCompressor::IncreaseFreeList()
m_compressed_geometries.resize(m_compressed_geometries.size() + 100);
for (unsigned i = 100; i > 0; --i)
{
m_free_list.emplace_back(current_free_list_maximum);
++current_free_list_maximum;
m_free_list.emplace_back(free_list_maximum);
++free_list_maximum;
}
}
bool GeometryCompressor::HasEntryForID(const EdgeID edge_id) const
{
return (m_edge_id_to_list_index_map.find(edge_id) != m_edge_id_to_list_index_map.end());
auto iter = m_edge_id_to_list_index_map.find(edge_id);
return iter != m_edge_id_to_list_index_map.end();
}
unsigned GeometryCompressor::GetPositionForID(const EdgeID edge_id) const
@@ -71,9 +72,9 @@ void GeometryCompressor::SerializeInternalVector(const std::string &path) const
{
boost::filesystem::fstream geometry_out_stream(path, std::ios::binary | std::ios::out);
const unsigned number_of_compressed_geometries = m_compressed_geometries.size() + 1;
BOOST_ASSERT(std::numeric_limits<unsigned>::max() != number_of_compressed_geometries);
geometry_out_stream.write((char *)&number_of_compressed_geometries, sizeof(unsigned));
const unsigned compressed_geometries = m_compressed_geometries.size() + 1;
BOOST_ASSERT(std::numeric_limits<unsigned>::max() != compressed_geometries);
geometry_out_stream.write((char *)&compressed_geometries, sizeof(unsigned));
// write indices array
unsigned prefix_sum_of_list_indices = 0;
@@ -146,6 +147,7 @@ void GeometryCompressor::CompressEdge(const EdgeID edge_id_1,
m_free_list.pop_back();
}
// find bucket index
const auto iter = m_edge_id_to_list_index_map.find(edge_id_1);
BOOST_ASSERT(iter != m_edge_id_to_list_index_map.end());
const unsigned edge_bucket_id1 = iter->second;
@@ -197,23 +199,23 @@ void GeometryCompressor::PrintStatistics() const
BOOST_ASSERT(0 == compressed_edges % 2);
BOOST_ASSERT(m_compressed_geometries.size() + m_free_list.size() > 0);
uint64_t number_of_compressed_geometries = 0;
uint64_t compressed_geometries = 0;
uint64_t longest_chain_length = 0;
for (const std::vector<CompressedNode> &current_vector : m_compressed_geometries)
{
number_of_compressed_geometries += current_vector.size();
compressed_geometries += current_vector.size();
longest_chain_length = std::max(longest_chain_length, (uint64_t)current_vector.size());
}
SimpleLogger().Write() << "Geometry successfully removed:"
"\n compressed edges: " << compressed_edges
<< "\n compressed geometries: " << number_of_compressed_geometries
<< "\n compressed geometries: " << compressed_geometries
<< "\n longest chain length: " << longest_chain_length
<< "\n cmpr ratio: "
<< ((float)compressed_edges /
std::max(number_of_compressed_geometries, (uint64_t)1))
std::max(compressed_geometries, (uint64_t)1))
<< "\n avg chain length: "
<< (float)number_of_compressed_geometries /
<< (float)compressed_geometries /
std::max((uint64_t)1, compressed_edges);
}
+12 -12
View File
@@ -28,8 +28,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "TemporaryStorage.h"
StreamData::StreamData()
: write_mode(true), temp_path(boost::filesystem::unique_path(temp_directory.append(
TemporaryFilePattern.begin(), TemporaryFilePattern.end()))),
: write_mode(true),
temp_path(boost::filesystem::unique_path(temp_directory / TemporaryFilePattern)),
temp_file(new boost::filesystem::fstream(
temp_path, std::ios::in | std::ios::out | std::ios::trunc | std::ios::binary)),
readWriteMutex(std::make_shared<boost::mutex>())
@@ -126,7 +126,7 @@ void TemporaryStorage::ReadFromSlot(const int slot_id, char *pointer, const std:
BOOST_ASSERT(!data.write_mode);
data.temp_file->read(pointer, size);
}
catch (boost::filesystem::filesystem_error &e) { Abort(e); }
catch (boost::filesystem::filesystem_error &error) { Abort(error); }
}
uint64_t TemporaryStorage::GetFreeBytesOnTemporaryDevice()
@@ -134,19 +134,19 @@ uint64_t TemporaryStorage::GetFreeBytesOnTemporaryDevice()
uint64_t value = -1;
try
{
boost::filesystem::path p = boost::filesystem::temp_directory_path();
boost::filesystem::space_info s = boost::filesystem::space(p);
value = s.free;
boost::filesystem::path path = boost::filesystem::temp_directory_path();
boost::filesystem::space_info space_info = boost::filesystem::space(path);
value = space_info.free;
}
catch (boost::filesystem::filesystem_error &e) { Abort(e); }
catch (boost::filesystem::filesystem_error &error) { Abort(error); }
return value;
}
void TemporaryStorage::CheckIfTemporaryDeviceFull()
{
boost::filesystem::path p = boost::filesystem::temp_directory_path();
boost::filesystem::space_info s = boost::filesystem::space(p);
if ((1024 * 1024) > s.free)
boost::filesystem::path path = boost::filesystem::temp_directory_path();
boost::filesystem::space_info space_info = boost::filesystem::space(path);
if ((1024 * 1024) > space_info.free)
{
throw OSRMException("temporary device is full");
}
@@ -165,8 +165,8 @@ boost::filesystem::fstream::pos_type TemporaryStorage::Tell(const int slot_id)
return position;
}
void TemporaryStorage::Abort(const boost::filesystem::filesystem_error &e)
void TemporaryStorage::Abort(const boost::filesystem::filesystem_error &error)
{
RemoveAll();
throw OSRMException(e.what());
throw OSRMException(error.what());
}
-3
View File
@@ -46,7 +46,6 @@ template <typename Data> class ConcurrentQueue
[this]
{ return m_internal_queue.size() < m_internal_queue.capacity(); });
m_internal_queue.push_back(data);
m_mutex.unlock();
m_not_empty.notify_one();
}
@@ -60,7 +59,6 @@ template <typename Data> class ConcurrentQueue
{ return !m_internal_queue.empty(); });
popped_value = m_internal_queue.front();
m_internal_queue.pop_front();
m_mutex.unlock();
m_not_full.notify_one();
}
@@ -73,7 +71,6 @@ template <typename Data> class ConcurrentQueue
}
popped_value = m_internal_queue.front();
m_internal_queue.pop_front();
m_mutex.unlock();
m_not_full.notify_one();
return true;
}
+169 -103
View File
@@ -29,7 +29,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../Util/MercatorUtil.h"
#include "../Util/SimpleLogger.h"
#include "../Util/StringUtil.h"
#include "../Util/TrigonometryTables.h"
#include <boost/assert.hpp>
@@ -49,13 +48,15 @@ FixedPointCoordinate::FixedPointCoordinate(int lat, int lon) : lat(lat), lon(lon
#ifndef NDEBUG
if (0 != (std::abs(lat) >> 30))
{
std::bitset<32> y(lat);
SimpleLogger().Write(logDEBUG) << "broken lat: " << lat << ", bits: " << y;
std::bitset<32> y_coordinate_vector(lat);
SimpleLogger().Write(logDEBUG) << "broken lat: " << lat
<< ", bits: " << y_coordinate_vector;
}
if (0 != (std::abs(lon) >> 30))
{
std::bitset<32> x(lon);
SimpleLogger().Write(logDEBUG) << "broken lon: " << lon << ", bits: " << x;
std::bitset<32> x_coordinate_vector(lon);
SimpleLogger().Write(logDEBUG) << "broken lon: " << lon
<< ", bits: " << x_coordinate_vector;
}
#endif
}
@@ -114,128 +115,132 @@ double FixedPointCoordinate::ApproximateDistance(const int lat1,
return earth * cHarv;
}
double FixedPointCoordinate::ApproximateDistance(const FixedPointCoordinate &c1,
const FixedPointCoordinate &c2)
double FixedPointCoordinate::ApproximateDistance(const FixedPointCoordinate &coordinate_1,
const FixedPointCoordinate &coordinate_2)
{
return ApproximateDistance(c1.lat, c1.lon, c2.lat, c2.lon);
return ApproximateDistance(
coordinate_1.lat, coordinate_1.lon, coordinate_2.lat, coordinate_2.lon);
}
float FixedPointCoordinate::ApproximateEuclideanDistance(const FixedPointCoordinate &c1,
const FixedPointCoordinate &c2)
float FixedPointCoordinate::ApproximateEuclideanDistance(const FixedPointCoordinate &coordinate_1,
const FixedPointCoordinate &coordinate_2)
{
return ApproximateEuclideanDistance(c1.lat, c1.lon, c2.lat, c2.lon);
return ApproximateEuclideanDistance(
coordinate_1.lat, coordinate_1.lon, coordinate_2.lat, coordinate_2.lon);
}
float FixedPointCoordinate::ApproximateEuclideanDistance(const int lat1,
const int lon1,
const int lat2,
const int lon2)
const int lon1,
const int lat2,
const int lon2)
{
BOOST_ASSERT(lat1 != std::numeric_limits<int>::min());
BOOST_ASSERT(lon1 != std::numeric_limits<int>::min());
BOOST_ASSERT(lat2 != std::numeric_limits<int>::min());
BOOST_ASSERT(lon2 != std::numeric_limits<int>::min());
const float RAD = 0.017453292519943295769236907684886;
const float RAD = 0.017453292519943295769236907684886f;
const float float_lat1 = (lat1 / COORDINATE_PRECISION) * RAD;
const float float_lon1 = (lon1 / COORDINATE_PRECISION) * RAD;
const float float_lat2 = (lat2 / COORDINATE_PRECISION) * RAD;
const float float_lon2 = (lon2 / COORDINATE_PRECISION) * RAD;
const float x = (float_lon2 - float_lon1) * cos((float_lat1 + float_lat2) / 2.);
const float y = (float_lat2 - float_lat1);
const float earth_radius = 6372797.560856;
return sqrt(x * x + y * y) * earth_radius;
const float x_value = (float_lon2 - float_lon1) * cos((float_lat1 + float_lat2) / 2.f);
const float y_value = float_lat2 - float_lat1;
const float earth_radius = 6372797.560856f;
return sqrt(x_value * x_value + y_value * y_value) * earth_radius;
}
float FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordinate &point,
const FixedPointCoordinate &segA,
const FixedPointCoordinate &segB)
float
FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordinate &source_coordinate,
const FixedPointCoordinate &target_coordinate,
const FixedPointCoordinate &point)
{
const float x = lat2y(point.lat / COORDINATE_PRECISION);
const float y = point.lon / COORDINATE_PRECISION;
const float a = lat2y(segA.lat / COORDINATE_PRECISION);
const float b = segA.lon / COORDINATE_PRECISION;
const float c = lat2y(segB.lat / COORDINATE_PRECISION);
const float d = segB.lon / COORDINATE_PRECISION;
float p, q, nY;
// initialize values
const float x_value = lat2y(point.lat / COORDINATE_PRECISION);
const float y_value = point.lon / COORDINATE_PRECISION;
const float a = lat2y(source_coordinate.lat / COORDINATE_PRECISION);
const float b = source_coordinate.lon / COORDINATE_PRECISION;
const float c = lat2y(target_coordinate.lat / COORDINATE_PRECISION);
const float d = target_coordinate.lon / COORDINATE_PRECISION;
float p, q;
if (std::abs(a - c) > std::numeric_limits<float>::epsilon())
{
const float m = (d - b) / (c - a); // slope
const float slope = (d - b) / (c - a); // slope
// Projection of (x,y) on line joining (a,b) and (c,d)
p = ((x + (m * y)) + (m * m * a - m * b)) / (1. + m * m);
q = b + m * (p - a);
p = ((x_value + (slope * y_value)) + (slope * slope * a - slope * b)) /
(1.f + slope * slope);
q = b + slope * (p - a);
}
else
{
p = c;
q = y;
q = y_value;
}
nY = (d * p - c * q) / (a * d - b * c);
float nY = (d * p - c * q) / (a * d - b * c);
// discretize the result to coordinate precision. it's a hack!
if (std::abs(nY) < (1. / COORDINATE_PRECISION))
if (std::abs(nY) < (1.f / COORDINATE_PRECISION))
{
nY = 0.;
nY = 0.f;
}
float r = (p - nY * a) / c;
if (std::isnan(r))
// compute ratio
float ratio = (p - nY * a) / c;
if (std::isnan(ratio))
{
r = ((segB.lat == point.lat) && (segB.lon == point.lon)) ? 1. : 0.;
ratio = (target_coordinate == point ? 1.f : 0.f);
}
else if (std::abs(r) <= std::numeric_limits<float>::epsilon())
else if (std::abs(ratio) <= std::numeric_limits<float>::epsilon())
{
r = 0.;
ratio = 0.f;
}
else if (std::abs(r - 1.) <= std::numeric_limits<float>::epsilon())
else if (std::abs(ratio - 1.f) <= std::numeric_limits<float>::epsilon())
{
r = 1.;
ratio = 1.f;
}
//compute the nearest location
FixedPointCoordinate nearest_location;
BOOST_ASSERT(!std::isnan(r));
if (r <= 0.)
BOOST_ASSERT(!std::isnan(ratio));
if (ratio <= 0.f)
{ // point is "left" of edge
nearest_location.lat = segA.lat;
nearest_location.lon = segA.lon;
nearest_location = source_coordinate;
}
else if (r >= 1.)
else if (ratio >= 1.f)
{ // point is "right" of edge
nearest_location.lat = segB.lat;
nearest_location.lon = segB.lon;
nearest_location = target_coordinate;
}
else
{ // point lies in between
nearest_location.lat = y2lat(p) * COORDINATE_PRECISION;
nearest_location.lon = q * COORDINATE_PRECISION;
nearest_location.lat = static_cast<int>(y2lat(p) * COORDINATE_PRECISION);
nearest_location.lon = static_cast<int>(q * COORDINATE_PRECISION);
}
BOOST_ASSERT(nearest_location.isValid());
const float approximated_distance =
FixedPointCoordinate::ApproximateEuclideanDistance(point, nearest_location);
BOOST_ASSERT(0. <= approximated_distance);
return approximated_distance;
return FixedPointCoordinate::ApproximateEuclideanDistance(point, nearest_location);
}
float FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordinate &coord_a,
const FixedPointCoordinate &coord_b,
const FixedPointCoordinate &query_location,
FixedPointCoordinate &nearest_location,
float &r)
float FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordinate &segment_source,
const FixedPointCoordinate &segment_target,
const FixedPointCoordinate &query_location,
FixedPointCoordinate &nearest_location,
float &ratio)
{
BOOST_ASSERT(query_location.isValid());
// initialize values
const float x = lat2y(query_location.lat / COORDINATE_PRECISION);
const float y = query_location.lon / COORDINATE_PRECISION;
const float a = lat2y(coord_a.lat / COORDINATE_PRECISION);
const float b = coord_a.lon / COORDINATE_PRECISION;
const float c = lat2y(coord_b.lat / COORDINATE_PRECISION);
const float d = coord_b.lon / COORDINATE_PRECISION;
const float a = lat2y(segment_source.lat / COORDINATE_PRECISION);
const float b = segment_source.lon / COORDINATE_PRECISION;
const float c = lat2y(segment_target.lat / COORDINATE_PRECISION);
const float d = segment_target.lon / COORDINATE_PRECISION;
float p, q /*,mX*/, nY;
if (std::abs(a - c) > std::numeric_limits<float>::epsilon())
{
const float m = (d - b) / (c - a); // slope
// Projection of (x,y) on line joining (a,b) and (c,d)
p = ((x + (m * y)) + (m * m * a - m * b)) / (1. + m * m);
p = ((x + (m * y)) + (m * m * a - m * b)) / (1.f + m * m);
q = b + m * (p - a);
}
else
@@ -246,49 +251,50 @@ float FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordin
nY = (d * p - c * q) / (a * d - b * c);
// discretize the result to coordinate precision. it's a hack!
if (std::abs(nY) < (1. / COORDINATE_PRECISION))
if (std::abs(nY) < (1.f / COORDINATE_PRECISION))
{
nY = 0.;
nY = 0.f;
}
r = (p - nY * a) / c; // These values are actually n/m+n and m/m+n , we need
// compute ratio
ratio = (p - nY * a) / c; // These values are actually n/m+n and m/m+n , we need
// not calculate the explicit values of m an n as we
// are just interested in the ratio
if (std::isnan(r))
if (std::isnan(ratio))
{
r = ((coord_b.lat == query_location.lat) && (coord_b.lon == query_location.lon)) ? 1. : 0.;
ratio = (segment_target == query_location ? 1.f : 0.f);
}
else if (std::abs(r) <= std::numeric_limits<float>::epsilon())
else if (std::abs(ratio) <= std::numeric_limits<float>::epsilon())
{
r = 0.;
ratio = 0.;
}
else if (std::abs(r - 1.) <= std::numeric_limits<float>::epsilon())
else if (std::abs(ratio - 1.f) <= std::numeric_limits<float>::epsilon())
{
r = 1.;
ratio = 1.f;
}
BOOST_ASSERT(!std::isnan(r));
if (r <= 0.)
// compute nearest location
BOOST_ASSERT(!std::isnan(ratio));
if (ratio <= 0.f)
{
nearest_location = coord_a;
nearest_location = segment_source;
}
else if (r >= 1.)
else if (ratio >= 1.)
{
nearest_location = coord_b;
nearest_location = segment_target;
}
else
{
// point lies in between
nearest_location.lat = y2lat(p) * COORDINATE_PRECISION;
nearest_location.lon = q * COORDINATE_PRECISION;
nearest_location.lat = static_cast<int>(y2lat(p) * COORDINATE_PRECISION);
nearest_location.lon = static_cast<int>(q * COORDINATE_PRECISION);
}
BOOST_ASSERT(nearest_location.isValid());
// TODO: Replace with euclidean approximation when k-NN search is done
// const float approximated_distance = FixedPointCoordinate::ApproximateEuclideanDistance(
const float approximated_distance =
const float approximate_distance =
FixedPointCoordinate::ApproximateEuclideanDistance(query_location, nearest_location);
BOOST_ASSERT(0. <= approximated_distance);
return approximated_distance;
BOOST_ASSERT(0. <= approximate_distance);
return approximate_distance;
}
void FixedPointCoordinate::convertInternalLatLonToString(const int value, std::string &output)
@@ -328,13 +334,15 @@ void FixedPointCoordinate::Output(std::ostream &out) const
out << "(" << lat / COORDINATE_PRECISION << "," << lon / COORDINATE_PRECISION << ")";
}
float FixedPointCoordinate::GetBearing(const FixedPointCoordinate &A, const FixedPointCoordinate &B)
float FixedPointCoordinate::GetBearing(const FixedPointCoordinate &first_coordinate,
const FixedPointCoordinate &second_coordinate)
{
const float delta_long = DegreeToRadian(B.lon / COORDINATE_PRECISION - A.lon / COORDINATE_PRECISION);
const float lat1 = DegreeToRadian(A.lat / COORDINATE_PRECISION);
const float lat2 = DegreeToRadian(B.lat / COORDINATE_PRECISION);
const float y = sin(delta_long) * cos(lat2);
const float x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(delta_long);
const float lon_diff = second_coordinate.lon / COORDINATE_PRECISION - first_coordinate.lon / COORDINATE_PRECISION;
const float lon_delta = DegreeToRadian(lon_diff);
const float lat1 = DegreeToRadian(first_coordinate.lat / COORDINATE_PRECISION);
const float lat2 = DegreeToRadian(second_coordinate.lat / COORDINATE_PRECISION);
const float y = sin(lon_delta) * cos(lat2);
const float x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(lon_delta);
float result = RadianToDegree(std::atan2(y, x));
while (result < 0.f)
{
@@ -350,12 +358,14 @@ float FixedPointCoordinate::GetBearing(const FixedPointCoordinate &A, const Fixe
float FixedPointCoordinate::GetBearing(const FixedPointCoordinate &other) const
{
const float delta_long = DegreeToRadian(lon / COORDINATE_PRECISION - other.lon / COORDINATE_PRECISION);
const float lon_delta =
DegreeToRadian(lon / COORDINATE_PRECISION - other.lon / COORDINATE_PRECISION);
const float lat1 = DegreeToRadian(other.lat / COORDINATE_PRECISION);
const float lat2 = DegreeToRadian(lat / COORDINATE_PRECISION);
const float y = std::sin(delta_long) * std::cos(lat2);
const float x = std::cos(lat1) * std::sin(lat2) - std::sin(lat1) * std::cos(lat2) * std::cos(delta_long);
float result = RadianToDegree(std::atan2(y, x));
const float y_value = std::sin(lon_delta) * std::cos(lat2);
const float x_value =
std::cos(lat1) * std::sin(lat2) - std::sin(lat1) * std::cos(lat2) * std::cos(lon_delta);
float result = RadianToDegree(std::atan2(y_value, x_value));
while (result < 0.f)
{
@@ -369,12 +379,68 @@ float FixedPointCoordinate::GetBearing(const FixedPointCoordinate &other) const
return result;
}
float FixedPointCoordinate::DegreeToRadian(const float degree)
{
return degree * (M_PI / 180.f);
}
float FixedPointCoordinate::DegreeToRadian(const float degree) { return degree * (static_cast<float>(M_PI) / 180.f); }
float FixedPointCoordinate::RadianToDegree(const float radian)
float FixedPointCoordinate::RadianToDegree(const float radian) { return radian * (180.f * static_cast<float>(M_1_PI)); }
// This distance computation does integer arithmetic only and is a lot faster than
// the other distance function which are numerically correct('ish).
// It preserves some order among the elements that make it useful for certain purposes
int FixedPointCoordinate::OrderedPerpendicularDistanceApproximation(
const FixedPointCoordinate &input_point,
const FixedPointCoordinate &segment_source,
const FixedPointCoordinate &segment_target)
{
return radian * (180.f / M_PI);
// initialize values
const float x = lat2y(input_point.lat / COORDINATE_PRECISION);
const float y = input_point.lon / COORDINATE_PRECISION;
const float a = lat2y(segment_source.lat / COORDINATE_PRECISION);
const float b = segment_source.lon / COORDINATE_PRECISION;
const float c = lat2y(segment_target.lat / COORDINATE_PRECISION);
const float d = segment_target.lon / COORDINATE_PRECISION;
float p, q;
if (a == c)
{
p = c;
q = y;
}
else
{
const float m = (d - b) / (c - a); // slope
// Projection of (x,y) on line joining (a,b) and (c,d)
p = ((x + (m * y)) + (m * m * a - m * b)) / (1.f + m * m);
q = b + m * (p - a);
}
const float nY = (d * p - c * q) / (a * d - b * c);
float ratio = (p - nY * a) / c; // These values are actually n/m+n and m/m+n , we need
// not calculate the explicit values of m an n as we
// are just interested in the ratio
if (std::isnan(ratio))
{
ratio = (segment_target == input_point) ? 1.f : 0.f;
}
// compute target quasi-location
int dx, dy;
if (ratio < 0.f)
{
dx = input_point.lon - segment_source.lon;
dy = input_point.lat - segment_source.lat;
}
else if (ratio > 1.f)
{
dx = input_point.lon - segment_target.lon;
dy = input_point.lat - segment_target.lat;
}
else
{
// point lies in between
dx = input_point.lon - static_cast<int>(q * COORDINATE_PRECISION);
dy = input_point.lat - static_cast<int>(y2lat(p) * COORDINATE_PRECISION);
}
// return an approximation in the plane
return static_cast<int>(sqrt(dx * dx + dy * dy));
}
+1 -1
View File
@@ -338,7 +338,7 @@ class DeallocatingVector
{
const std::size_t number_of_necessary_buckets = 1 + (new_size / bucketSizeC);
for (unsigned i = number_of_necessary_buckets; i < bucket_list.size(); ++i)
for (std::size_t i = number_of_necessary_buckets; i < bucket_list.size(); ++i)
{
delete[] bucket_list[i];
}
+3 -4
View File
@@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <algorithm>
#include <limits>
#include <vector>
#include <atomic>
template <typename EdgeDataT> class DynamicGraph
{
@@ -91,7 +92,7 @@ template <typename EdgeDataT> class DynamicGraph
position += m_nodes[node].edges;
}
m_nodes.back().firstEdge = position;
m_edges.reserve(position * 1.1);
m_edges.reserve(static_cast<std::size_t>(position * 1.1));
m_edges.resize(position);
edge = 0;
for (NodeIterator node = 0; node < m_numNodes; ++node)
@@ -198,7 +199,6 @@ template <typename EdgeDataT> class DynamicGraph
void DeleteEdge(const NodeIterator source, const EdgeIterator e)
{
Node &node = m_nodes[source];
#pragma omp atomic
--m_numEdges;
--node.edges;
BOOST_ASSERT(std::numeric_limits<unsigned>::max() != node.edges);
@@ -226,7 +226,6 @@ template <typename EdgeDataT> class DynamicGraph
}
}
#pragma omp atomic
m_numEdges -= deleted;
m_nodes[source].edges -= deleted;
@@ -272,7 +271,7 @@ template <typename EdgeDataT> class DynamicGraph
};
NodeIterator m_numNodes;
EdgeIterator m_numEdges;
std::atomic_uint m_numEdges;
std::vector<Node> m_nodes;
DeallocatingVector<Edge> m_edges;
+26 -13
View File
@@ -28,37 +28,50 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef HASH_TABLE_H
#define HASH_TABLE_H
#include <unordered_map>
#include <vector>
template <typename Key, typename Value> class HashTable : public std::unordered_map<Key, Value>
template <typename Key, typename Value>
class HashTable
{
private:
typedef std::unordered_map<Key, Value> super;
typedef std::pair<Key, Value> KeyValPair;
std::vector<KeyValPair> table;
public:
HashTable() : super() {}
HashTable() {}
explicit HashTable(const unsigned size) : super(size) {}
inline void Add(Key const &key, Value const &value)
{
table.emplace_back(std::move(key), std::move(value));
}
inline void Add(Key const &key, Value const &value) { super::emplace(key, value); }
inline void Clear()
{
table.clear();
}
inline const Value Find(Key const &key) const
{
auto iter = super::find(key);
if (iter == super::end())
for (const auto &key_val_pair : table)
{
return Value();
if (key_val_pair.first == key)
{
return key_val_pair.second;
}
}
return iter->second;
return Value();
}
inline const bool Holds(Key const &key) const
{
if (super::find(key) == super::end())
for (const auto &key_val_pair : table)
{
return false;
if (key_val_pair.first == key)
{
return true;
}
}
return true;
return false;
}
};
+2 -2
View File
@@ -32,8 +32,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
uint64_t HilbertCode::operator()(const FixedPointCoordinate &current_coordinate) const
{
unsigned location[2];
location[0] = current_coordinate.lat + (90 * COORDINATE_PRECISION);
location[1] = current_coordinate.lon + (180 * COORDINATE_PRECISION);
location[0] = current_coordinate.lat + static_cast<int>(90 * COORDINATE_PRECISION);
location[1] = current_coordinate.lon + static_cast<int>(180 * COORDINATE_PRECISION);
TransposeCoordinate(location);
return BitInterleaving(location[0], location[1]);
+107
View File
@@ -0,0 +1,107 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ImportEdge.h"
#include <boost/assert.hpp>
bool NodeBasedEdge::operator<(const NodeBasedEdge &other) const
{
if (source == other.source)
{
if (target == other.target)
{
if (weight == other.weight)
{
return forward && backward && ((!other.forward) || (!other.backward));
}
return weight < other.weight;
}
return target < other.target;
}
return source < other.source;
}
NodeBasedEdge::NodeBasedEdge(NodeID source,
NodeID target,
NodeID name_id,
EdgeWeight weight,
bool forward,
bool backward,
short type,
bool roundabout,
bool in_tiny_cc,
bool access_restricted,
bool contra_flow,
bool is_split)
: source(source), target(target), name_id(name_id), weight(weight), type(type),
forward(forward), backward(backward), roundabout(roundabout), in_tiny_cc(in_tiny_cc),
access_restricted(access_restricted), contra_flow(contra_flow), is_split(is_split)
{
BOOST_ASSERT_MSG(type > 0, "negative edge type");
}
bool EdgeBasedEdge::operator<(const EdgeBasedEdge &other) const
{
if (source == other.source)
{
if (target == other.target)
{
if (weight == other.weight)
{
return forward && backward && ((!other.forward) || (!other.backward));
}
return weight < other.weight;
}
return target < other.target;
}
return source < other.source;
}
template <class EdgeT>
EdgeBasedEdge::EdgeBasedEdge(const EdgeT &other)
: source(other.source), target(other.target), edge_id(other.data.via),
weight(other.data.distance), forward(other.data.forward), backward(other.data.backward)
{
}
/** Default constructor. target and weight are set to 0.*/
EdgeBasedEdge::EdgeBasedEdge()
: source(0), target(0), edge_id(0), weight(0), forward(false), backward(false)
{
}
EdgeBasedEdge::EdgeBasedEdge(const NodeID source,
const NodeID target,
const NodeID edge_id,
const EdgeWeight weight,
const bool forward,
const bool backward)
: source(source), target(target), edge_id(edge_id), weight(weight), forward(forward),
backward(backward)
{
}
+40 -126
View File
@@ -28,149 +28,63 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef IMPORT_EDGE_H
#define IMPORT_EDGE_H
#include "../Util/OSRMException.h"
#include "../typedefs.h"
#include <boost/assert.hpp>
class NodeBasedEdge
struct NodeBasedEdge
{
bool operator<(const NodeBasedEdge &e) const;
public:
bool operator<(const NodeBasedEdge &e) const
{
if (source() == e.source())
{
if (target() == e.target())
{
if (weight() == e.weight())
{
return (isForward() && isBackward() && ((!e.isForward()) || (!e.isBackward())));
}
return (weight() < e.weight());
}
return (target() < e.target());
}
return (source() < e.source());
}
explicit NodeBasedEdge(NodeID source,
NodeID target,
NodeID name_id,
EdgeWeight weight,
bool forward,
bool backward,
short type,
bool roundabout,
bool in_tiny_cc,
bool access_restricted,
bool contra_flow,
bool is_split);
explicit NodeBasedEdge(NodeID s,
NodeID t,
NodeID n,
EdgeWeight w,
bool f,
bool b,
short ty,
bool ra,
bool ig,
bool ar,
bool cf,
bool is_split)
: _source(s), _target(t), _name(n), _weight(w), _type(ty), forward(f), backward(b),
_roundabout(ra), _ignoreInGrid(ig), _accessRestricted(ar), _contraFlow(cf),
is_split(is_split)
{
if (ty < 0)
{
throw OSRMException("negative edge type");
}
}
NodeID target() const { return _target; }
NodeID source() const { return _source; }
NodeID name() const { return _name; }
EdgeWeight weight() const { return _weight; }
short type() const
{
BOOST_ASSERT_MSG(_type >= 0, "type of ImportEdge invalid");
return _type;
}
bool isBackward() const { return backward; }
bool isForward() const { return forward; }
bool isLocatable() const { return _type != 14; }
bool isRoundabout() const { return _roundabout; }
bool ignoreInGrid() const { return _ignoreInGrid; }
bool isAccessRestricted() const { return _accessRestricted; }
bool isContraFlow() const { return _contraFlow; }
bool IsSplit() const { return is_split; }
// TODO: names need to be fixed.
NodeID _source;
NodeID _target;
NodeID _name;
EdgeWeight _weight;
short _type;
NodeID source;
NodeID target;
NodeID name_id;
EdgeWeight weight;
short type;
bool forward : 1;
bool backward : 1;
bool _roundabout : 1;
bool _ignoreInGrid : 1;
bool _accessRestricted : 1;
bool _contraFlow : 1;
bool roundabout : 1;
bool in_tiny_cc : 1;
bool access_restricted : 1;
bool contra_flow : 1;
bool is_split : 1;
private:
NodeBasedEdge() {}
NodeBasedEdge() = delete;
};
class EdgeBasedEdge
struct EdgeBasedEdge
{
public:
bool operator<(const EdgeBasedEdge &e) const
{
if (source() == e.source())
{
if (target() == e.target())
{
if (weight() == e.weight())
{
return (isForward() && isBackward() && ((!e.isForward()) || (!e.isBackward())));
}
return (weight() < e.weight());
}
return (target() < e.target());
}
return (source() < e.source());
}
bool operator<(const EdgeBasedEdge &e) const;
template <class EdgeT>
explicit EdgeBasedEdge(const EdgeT &myEdge)
: m_source(myEdge.source), m_target(myEdge.target), m_edgeID(myEdge.data.via),
m_weight(myEdge.data.distance), m_forward(myEdge.data.forward),
m_backward(myEdge.data.backward)
{
}
template <class EdgeT> explicit EdgeBasedEdge(const EdgeT &myEdge);
/** Default constructor. target and weight are set to 0.*/
EdgeBasedEdge()
: m_source(0), m_target(0), m_edgeID(0), m_weight(0), m_forward(false), m_backward(false)
{
}
EdgeBasedEdge();
explicit EdgeBasedEdge(const NodeID s,
const NodeID t,
const NodeID v,
const EdgeWeight w,
const bool f,
const bool b)
: m_source(s), m_target(t), m_edgeID(v), m_weight(w), m_forward(f), m_backward(b)
{
}
NodeID target() const { return m_target; }
NodeID source() const { return m_source; }
EdgeWeight weight() const { return m_weight; }
NodeID id() const { return m_edgeID; }
bool isBackward() const { return m_backward; }
bool isForward() const { return m_forward; }
private:
NodeID m_source;
NodeID m_target;
NodeID m_edgeID;
EdgeWeight m_weight : 30;
bool m_forward : 1;
bool m_backward : 1;
explicit EdgeBasedEdge(const NodeID source,
const NodeID target,
const NodeID edge_id,
const EdgeWeight weight,
const bool forward,
const bool backward);
NodeID source;
NodeID target;
NodeID edge_id;
EdgeWeight weight : 30;
bool forward : 1;
bool backward : 1;
};
typedef NodeBasedEdge ImportEdge;
@@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -25,17 +25,40 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OPENMP_WRAPPER_H
#define OPENMP_WRAPPER_H
#include "ImportNode.h"
#ifdef _OPENMP
extern "C" {
#include <omp.h>
#include <limits>
ExternalMemoryNode::ExternalMemoryNode(
int lat, int lon, unsigned int node_id, bool bollard, bool traffic_light)
: NodeInfo(lat, lon, node_id), bollard(bollard), trafficLight(traffic_light)
{
}
ExternalMemoryNode::ExternalMemoryNode() : bollard(false), trafficLight(false)
{
}
ExternalMemoryNode ExternalMemoryNode::min_value()
{
return ExternalMemoryNode(0, 0, 0, false, false);
}
ExternalMemoryNode ExternalMemoryNode::max_value()
{
return ExternalMemoryNode(std::numeric_limits<int>::max(),
std::numeric_limits<int>::max(),
std::numeric_limits<unsigned>::max(),
false,
false);
}
void ImportNode::Clear()
{
keyVals.Clear();
lat = 0;
lon = 0;
node_id = 0;
bollard = false;
trafficLight = false;
}
#else
inline int omp_get_num_procs() { return 1; }
inline int omp_get_max_threads() { return 1; }
inline int omp_get_thread_num() { return 0; }
inline void omp_set_num_threads(int i) {}
#endif // _OPENMP
#endif // OPENMP_WRAPPER_H
+5 -26
View File
@@ -31,30 +31,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "QueryNode.h"
#include "../DataStructures/HashTable.h"
#include <limits>
#include <string>
struct ExternalMemoryNode : NodeInfo
{
ExternalMemoryNode(int lat, int lon, unsigned int id, bool bollard, bool traffic_light)
: NodeInfo(lat, lon, id), bollard(bollard), trafficLight(traffic_light)
{
}
ExternalMemoryNode(int lat, int lon, unsigned int id, bool bollard, bool traffic_light);
ExternalMemoryNode() : bollard(false), trafficLight(false) {}
ExternalMemoryNode();
static ExternalMemoryNode min_value() { return ExternalMemoryNode(0, 0, 0, false, false); }
static ExternalMemoryNode min_value();
static ExternalMemoryNode max_value()
{
return ExternalMemoryNode(std::numeric_limits<int>::max(),
std::numeric_limits<int>::max(),
std::numeric_limits<unsigned>::max(),
false,
false);
}
NodeID key() const { return id; }
static ExternalMemoryNode max_value();
bool bollard;
bool trafficLight;
@@ -64,15 +51,7 @@ struct ImportNode : public ExternalMemoryNode
{
HashTable<std::string, std::string> keyVals;
inline void Clear()
{
keyVals.clear();
lat = 0;
lon = 0;
id = 0;
bollard = false;
trafficLight = false;
}
inline void Clear();
};
#endif /* IMPORTNODE_H_ */
+6 -6
View File
@@ -44,8 +44,8 @@ struct BZ2Context
int readFromBz2Stream(void *pointer, char *buffer, int len)
{
void *unusedTmpVoid = NULL;
char *unusedTmp = NULL;
void *unusedTmpVoid = nullptr;
char *unusedTmp = nullptr;
BZ2Context *context = (BZ2Context *)pointer;
int read = 0;
while (0 == read &&
@@ -76,7 +76,7 @@ int readFromBz2Stream(void *pointer, char *buffer, int len)
{
context->bz2 = BZ2_bzReadOpen(
&context->error, context->file, 0, 0, context->unused, context->nUnused);
BOOST_ASSERT_MSG(NULL != context->bz2, "Could not open file");
BOOST_ASSERT_MSG(nullptr != context->bz2, "Could not open file");
}
}
else
@@ -107,12 +107,12 @@ xmlTextReaderPtr inputReaderFactory(const char *name)
int error;
context->bz2 =
BZ2_bzReadOpen(&error, context->file, 0, 0, context->unused, context->nUnused);
if (context->bz2 == NULL || context->file == NULL)
if (context->bz2 == nullptr || context->file == nullptr)
{
delete context;
return NULL;
return nullptr;
}
return xmlReaderForIO(readFromBz2Stream, closeBz2Stream, (void *)context, NULL, NULL, 0);
return xmlReaderForIO(readFromBz2Stream, closeBz2Stream, (void *)context, nullptr, nullptr, 0);
}
else
{
+80 -24
View File
@@ -3,6 +3,9 @@
#include "DynamicGraph.h"
#include "ImportEdge.h"
#include "../Util/SimpleLogger.h"
#include <tbb/parallel_sort.h>
#include <memory>
@@ -50,27 +53,25 @@ inline std::shared_ptr<NodeBasedDynamicGraph>
NodeBasedDynamicGraphFromImportEdges(int number_of_nodes, std::vector<ImportEdge> &input_edge_list)
{
static_assert(sizeof(NodeBasedEdgeData) == 16, "changing node based edge data size changes memory consumption");
std::sort(input_edge_list.begin(), input_edge_list.end());
// tbb::parallel_sort(input_edge_list.begin(), input_edge_list.end());
// TODO: remove duplicate edges
DeallocatingVector<NodeBasedDynamicGraph::InputEdge> edges_list;
NodeBasedDynamicGraph::InputEdge edge;
for (const ImportEdge &import_edge : input_edge_list)
{
// TODO: give ImportEdge a proper c'tor to use emplace_back's below
if (!import_edge.isForward())
if (import_edge.forward)
{
edge.source = import_edge.target();
edge.target = import_edge.source();
edge.data.backward = import_edge.isForward();
edge.data.forward = import_edge.isBackward();
edge.source = import_edge.source;
edge.target = import_edge.target;
edge.data.forward = import_edge.forward;
edge.data.backward = import_edge.backward;
}
else
{
edge.source = import_edge.source();
edge.target = import_edge.target();
edge.data.forward = import_edge.isForward();
edge.data.backward = import_edge.isBackward();
edge.source = import_edge.target;
edge.target = import_edge.source;
edge.data.backward = import_edge.forward;
edge.data.forward = import_edge.backward;
}
if (edge.source == edge.target)
@@ -78,18 +79,18 @@ NodeBasedDynamicGraphFromImportEdges(int number_of_nodes, std::vector<ImportEdge
continue;
}
edge.data.distance = (std::max)((int)import_edge.weight(), 1);
edge.data.distance = (std::max)((int)import_edge.weight, 1);
BOOST_ASSERT(edge.data.distance > 0);
edge.data.shortcut = false;
edge.data.roundabout = import_edge.isRoundabout();
edge.data.ignore_in_grid = import_edge.ignoreInGrid();
edge.data.nameID = import_edge.name();
edge.data.type = import_edge.type();
edge.data.isAccessRestricted = import_edge.isAccessRestricted();
edge.data.contraFlow = import_edge.isContraFlow();
edge.data.roundabout = import_edge.roundabout;
edge.data.ignore_in_grid = import_edge.in_tiny_cc;
edge.data.nameID = import_edge.name_id;
edge.data.type = import_edge.type;
edge.data.isAccessRestricted = import_edge.access_restricted;
edge.data.contraFlow = import_edge.contra_flow;
edges_list.push_back(edge);
if (!import_edge.IsSplit())
if (!import_edge.is_split)
{
using std::swap; // enable ADL
swap(edge.source, edge.target);
@@ -98,12 +99,67 @@ NodeBasedDynamicGraphFromImportEdges(int number_of_nodes, std::vector<ImportEdge
}
}
// remove duplicate edges
std::sort(edges_list.begin(), edges_list.end());
NodeID edge_count = 0;
for (NodeID i = 0; i < edges_list.size(); )
{
const NodeID source = edges_list[i].source;
const NodeID target = edges_list[i].target;
// remove eigenloops
if (source == target)
{
i++;
continue;
}
NodeBasedDynamicGraph::InputEdge forward_edge;
NodeBasedDynamicGraph::InputEdge reverse_edge;
forward_edge = reverse_edge = edges_list[i];
forward_edge.data.forward = reverse_edge.data.backward = true;
forward_edge.data.backward = reverse_edge.data.forward = false;
forward_edge.data.shortcut = reverse_edge.data.shortcut = false;
forward_edge.data.distance = reverse_edge.data.distance =
std::numeric_limits<int>::max();
// remove parallel edges
while (i < edges_list.size() && edges_list[i].source == source && edges_list[i].target == target)
{
if (edges_list[i].data.forward)
{
forward_edge.data.distance =
std::min(edges_list[i].data.distance, forward_edge.data.distance);
}
if (edges_list[i].data.backward)
{
reverse_edge.data.distance =
std::min(edges_list[i].data.distance, reverse_edge.data.distance);
}
++i;
}
// merge edges (s,t) and (t,s) into bidirectional edge
if (forward_edge.data.distance == reverse_edge.data.distance)
{
if ((int)forward_edge.data.distance != std::numeric_limits<int>::max())
{
forward_edge.data.backward = true;
edges_list[edge_count++] = forward_edge;
}
}
else
{ // insert seperate edges
if (((int)forward_edge.data.distance) != std::numeric_limits<int>::max())
{
edges_list[edge_count++] = forward_edge;
}
if ((int)reverse_edge.data.distance != std::numeric_limits<int>::max())
{
edges_list[edge_count++] = reverse_edge;
}
}
}
edges_list.resize(edge_count);
SimpleLogger().Write() << "merged " << edges_list.size() - edge_count << " edges out of " << edges_list.size();
auto graph = std::make_shared<NodeBasedDynamicGraph>(number_of_nodes, edges_list);
edges_list.clear();
BOOST_ASSERT(0 == edges_list.size());
return graph;
}
+2 -4
View File
@@ -28,8 +28,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef PERCENT_H
#define PERCENT_H
#include "../Util/OpenMPWrapper.h"
#include <iostream>
#include <atomic>
class Percent
{
@@ -61,20 +61,18 @@ class Percent
void printIncrement()
{
#pragma omp atomic
++m_current_value;
printStatus(m_current_value);
}
void printAddition(const unsigned addition)
{
#pragma omp atomic
m_current_value += addition;
printStatus(m_current_value);
}
private:
unsigned m_current_value;
std::atomic_uint m_current_value;
unsigned m_max_value;
unsigned m_percent_interval;
unsigned m_next_threshold;
+26 -33
View File
@@ -32,8 +32,26 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../Util/SimpleLogger.h"
#include "../typedefs.h"
#include <vector>
struct PhantomNode
{
PhantomNode(NodeID forward_node_id, NodeID reverse_node_id, unsigned name_id,
int forward_weight, int reverse_weight, int forward_offset, int reverse_offset,
unsigned packed_geometry_id, FixedPointCoordinate &location,
unsigned short fwd_segment_position) :
forward_node_id(forward_node_id),
reverse_node_id(reverse_node_id),
name_id(name_id),
forward_weight(forward_weight),
reverse_weight(reverse_weight),
forward_offset(forward_offset),
reverse_offset(reverse_offset),
packed_geometry_id(packed_geometry_id),
location(location),
fwd_segment_position(fwd_segment_position)
{ }
PhantomNode() :
forward_node_id(SPECIAL_NODEID),
reverse_node_id(SPECIAL_NODEID),
@@ -77,17 +95,6 @@ struct PhantomNode
return result;
}
void Reset()
{
forward_node_id = SPECIAL_NODEID;
name_id = SPECIAL_NODEID;
forward_weight = INVALID_EDGE_WEIGHT;
reverse_weight = INVALID_EDGE_WEIGHT;
forward_offset = 0;
reverse_offset = 0;
location.Reset();
}
bool isBidirected() const
{
return (forward_node_id != SPECIAL_NODEID) &&
@@ -127,32 +134,18 @@ struct PhantomNode
}
};
typedef std::vector<std::vector<PhantomNode>> PhantomNodeArray;
struct PhantomNodeLists
{
std::vector<PhantomNode> source_phantom_list;
std::vector<PhantomNode> target_phantom_list;
};
struct PhantomNodes
{
PhantomNode source_phantom;
PhantomNode target_phantom;
void Reset()
{
source_phantom.Reset();
target_phantom.Reset();
}
bool PhantomsAreOnSameNodeBasedEdge() const
{
return (source_phantom.forward_node_id == target_phantom.forward_node_id);
}
bool AtLeastOnePhantomNodeIsInvalid() const
{
return ((source_phantom.forward_node_id == SPECIAL_NODEID) && (source_phantom.reverse_node_id == SPECIAL_NODEID)) ||
((target_phantom.forward_node_id == SPECIAL_NODEID) && (target_phantom.reverse_node_id == SPECIAL_NODEID));
}
bool PhantomNodesHaveEqualLocation() const
{
return source_phantom == target_phantom;
}
};
inline std::ostream& operator<<(std::ostream &out, const PhantomNodes & pn)
+7 -7
View File
@@ -41,28 +41,28 @@ struct NodeInfo
typedef NodeID key_type; // type of NodeID
typedef int value_type; // type of lat,lons
NodeInfo(int lat, int lon, NodeID id) : lat(lat), lon(lon), id(id) {}
explicit NodeInfo(int lat, int lon, NodeID node_id) : lat(lat), lon(lon), node_id(node_id) {}
NodeInfo()
: lat(std::numeric_limits<int>::max()), lon(std::numeric_limits<int>::max()),
id(std::numeric_limits<unsigned>::max())
node_id(std::numeric_limits<unsigned>::max())
{
}
int lat;
int lon;
NodeID id;
NodeID node_id;
static NodeInfo min_value()
{
return NodeInfo(-90 * COORDINATE_PRECISION,
-180 * COORDINATE_PRECISION,
return NodeInfo(static_cast<int>(-90 * COORDINATE_PRECISION),
static_cast<int>(-180 * COORDINATE_PRECISION),
std::numeric_limits<NodeID>::min());
}
static NodeInfo max_value()
{
return NodeInfo(90 * COORDINATE_PRECISION,
180 * COORDINATE_PRECISION,
return NodeInfo(static_cast<int>(90 * COORDINATE_PRECISION),
static_cast<int>(180 * COORDINATE_PRECISION),
std::numeric_limits<NodeID>::max());
}
+231
View File
@@ -0,0 +1,231 @@
#ifndef __RANGE_TABLE_H__
#define __RANGE_TABLE_H__
#include "SharedMemoryFactory.h"
#include "SharedMemoryVectorWrapper.h"
#include <boost/range/irange.hpp>
#include <fstream>
#include <vector>
#include <array>
/*
* These pre-declarations are needed because parsing C++ is hard
* and otherwise the compiler gets confused.
*/
template<unsigned BLOCK_SIZE=16, bool USE_SHARED_MEMORY = false> class RangeTable;
template<unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
std::ostream& operator<<(std::ostream &out, const RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY> &table);
template<unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
std::istream& operator>>(std::istream &in, RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY> &table);
/**
* Stores adjacent ranges in a compressed format.
*
* Maximum supported length of a range is 255.
*
* Note: BLOCK_SIZE is the number of differential encodoed values.
* But each block consists of an absolute value and BLOCK_SIZE differential values.
* So the effective block size is sizeof(unsigned) + BLOCK_SIZE.
*/
template<unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
class RangeTable
{
public:
typedef std::array<unsigned char, BLOCK_SIZE> BlockT;
typedef typename ShM<BlockT, USE_SHARED_MEMORY>::vector BlockContainerT;
typedef typename ShM<unsigned, USE_SHARED_MEMORY>::vector OffsetContainerT;
typedef decltype(boost::irange(0u,0u)) RangeT;
friend std::ostream& operator<< <>(std::ostream &out, const RangeTable &table);
friend std::istream& operator>> <>(std::istream &in, RangeTable &table);
RangeTable() : sum_lengths(0) {}
// for loading from shared memory
explicit RangeTable(OffsetContainerT& external_offsets, BlockContainerT& external_blocks, const unsigned sum_lengths)
: sum_lengths(sum_lengths)
{
block_offsets.swap(external_offsets);
diff_blocks.swap(external_blocks);
}
// construct table from length vector
explicit RangeTable(const std::vector<unsigned>& lengths)
{
const unsigned number_of_blocks = [&lengths]() {
unsigned num = (lengths.size() + 1) / (BLOCK_SIZE + 1);
if ((lengths.size() + 1) % (BLOCK_SIZE + 1) != 0)
{
num += 1;
}
return num;
}();
block_offsets.reserve(number_of_blocks);
diff_blocks.reserve(number_of_blocks);
unsigned last_length = 0;
unsigned lengths_prefix_sum = 0;
unsigned block_idx = 0;
unsigned block_counter = 0;
BlockT block;
unsigned block_sum = 0;
for (const unsigned l : lengths)
{
// first entry of a block: encode absolute offset
if (block_idx == 0)
{
block_offsets.push_back(lengths_prefix_sum);
block_sum = 0;
}
else
{
block[block_idx - 1] = last_length;
block_sum += last_length;
}
BOOST_ASSERT((block_idx == 0 && block_offsets[block_counter] == lengths_prefix_sum)
|| lengths_prefix_sum == (block_offsets[block_counter]+block_sum));
// block is full
if (BLOCK_SIZE == block_idx)
{
diff_blocks.push_back(block);
block_counter++;
}
// we can only store strings with length 255
BOOST_ASSERT(l <= 255);
lengths_prefix_sum += l;
last_length = l;
block_idx = (block_idx + 1) % (BLOCK_SIZE + 1);
}
// Last block can't be finished because we didn't add the sentinel
BOOST_ASSERT (block_counter == (number_of_blocks - 1));
// one block missing: starts with guard value
if (0 == block_idx)
{
// the last value is used as sentinel
block_offsets.push_back(lengths_prefix_sum);
block_idx = (block_idx + 1) % BLOCK_SIZE;
}
while (0 != block_idx)
{
block[block_idx - 1] = last_length;
last_length = 0;
block_idx = (block_idx + 1) % (BLOCK_SIZE + 1);
}
diff_blocks.push_back(block);
BOOST_ASSERT(diff_blocks.size() == number_of_blocks && block_offsets.size() == number_of_blocks);
sum_lengths = lengths_prefix_sum;
}
inline RangeT GetRange(const unsigned id) const
{
BOOST_ASSERT(id < block_offsets.size() + diff_blocks.size() * BLOCK_SIZE);
// internal_idx 0 is implicitly stored in block_offsets[block_idx]
const unsigned internal_idx = id % (BLOCK_SIZE + 1);
const unsigned block_idx = id / (BLOCK_SIZE + 1);
BOOST_ASSERT(block_idx < diff_blocks.size());
unsigned begin_idx = 0;
unsigned end_idx = 0;
begin_idx = block_offsets[block_idx];
const BlockT& block = diff_blocks[block_idx];
if (internal_idx > 0)
{
begin_idx += PrefixSumAtIndex(internal_idx - 1, block);
}
// next index inside current block
if (internal_idx < BLOCK_SIZE)
{
// note internal_idx - 1 is the *current* index for uint8_blocks
end_idx = begin_idx + block[internal_idx];
}
else
{
BOOST_ASSERT(block_idx < block_offsets.size() - 1);
end_idx = block_offsets[block_idx + 1];
}
BOOST_ASSERT(begin_idx < sum_lengths && end_idx <= sum_lengths);
BOOST_ASSERT(begin_idx <= end_idx);
return boost::irange(begin_idx, end_idx);
}
private:
inline unsigned PrefixSumAtIndex(int index, const BlockT& block) const;
// contains offset for each differential block
OffsetContainerT block_offsets;
// blocks of differential encoded offsets, should be aligned
BlockContainerT diff_blocks;
unsigned sum_lengths;
};
template<unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
unsigned RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY>::PrefixSumAtIndex(int index, const BlockT& block) const
{
// this loop looks inefficent, but a modern compiler
// will emit nice SIMD here, at least for sensible block sizes. (I checked.)
unsigned sum = 0;
for (int i = 0; i <= index; ++i)
{
sum += block[i];
}
return sum;
}
template<unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
std::ostream& operator<<(std::ostream &out, const RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY> &table)
{
// write number of block
const unsigned number_of_blocks = table.diff_blocks.size();
out.write((char *) &number_of_blocks, sizeof(unsigned));
// write total length
out.write((char *) &table.sum_lengths, sizeof(unsigned));
// write block offsets
out.write((char *) table.block_offsets.data(), sizeof(unsigned) * table.block_offsets.size());
// write blocks
out.write((char *) table.diff_blocks.data(), BLOCK_SIZE * table.diff_blocks.size());
return out;
}
template<unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
std::istream& operator>>(std::istream &in, RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY> &table)
{
// read number of block
unsigned number_of_blocks;
in.read((char *) &number_of_blocks, sizeof(unsigned));
// read total length
in.read((char *) &table.sum_lengths, sizeof(unsigned));
table.block_offsets.resize(number_of_blocks);
table.diff_blocks.resize(number_of_blocks);
// read block offsets
in.read((char *) table.block_offsets.data(), sizeof(unsigned) * number_of_blocks);
// read blocks
in.read((char *) table.diff_blocks.data(), BLOCK_SIZE * number_of_blocks);
return in;
}
#endif
+11 -15
View File
@@ -34,26 +34,24 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <osrm/Coordinate.h>
#include <limits>
#include <vector>
struct PathData
{
PathData()
: node(std::numeric_limits<unsigned>::max()), name_id(std::numeric_limits<unsigned>::max()),
segment_duration(std::numeric_limits<unsigned>::max()),
: node(SPECIAL_NODEID), name_id(INVALID_EDGE_WEIGHT),
segment_duration(INVALID_EDGE_WEIGHT),
turn_instruction(TurnInstruction::NoTurn)
{
}
PathData(NodeID node, unsigned name_id, TurnInstruction turn_instruction, unsigned segment_duration)
PathData(NodeID node, unsigned name_id, TurnInstruction turn_instruction, EdgeWeight segment_duration)
: node(node), name_id(name_id), segment_duration(segment_duration), turn_instruction(turn_instruction)
{
}
NodeID node;
unsigned name_id;
unsigned segment_duration;
EdgeWeight segment_duration;
TurnInstruction turn_instruction;
};
@@ -63,20 +61,18 @@ struct RawRouteData
std::vector<PathData> unpacked_alternative;
std::vector<PhantomNodes> segment_end_coordinates;
std::vector<FixedPointCoordinate> raw_via_node_coordinates;
std::vector<bool> source_traversed_in_reverse;
std::vector<bool> target_traversed_in_reverse;
std::vector<bool> alt_source_traversed_in_reverse;
std::vector<bool> alt_target_traversed_in_reverse;
unsigned check_sum;
int shortest_path_length;
int alternative_path_length;
bool source_traversed_in_reverse;
bool target_traversed_in_reverse;
bool alt_source_traversed_in_reverse;
bool alt_target_traversed_in_reverse;
RawRouteData()
: check_sum(std::numeric_limits<unsigned>::max()),
shortest_path_length(std::numeric_limits<int>::max()),
alternative_path_length(std::numeric_limits<int>::max()),
source_traversed_in_reverse(false), target_traversed_in_reverse(false),
alt_source_traversed_in_reverse(false), alt_target_traversed_in_reverse(false)
: check_sum(SPECIAL_NODEID),
shortest_path_length(INVALID_EDGE_WEIGHT),
alternative_path_length(INVALID_EDGE_WEIGHT)
{
}
};
+53 -44
View File
@@ -30,23 +30,23 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../Util/SimpleLogger.h"
bool RestrictionMap::IsNodeAViaNode(const NodeID node) const
bool RestrictionMap::IsViaNode(const NodeID node) const
{
return m_no_turn_via_node_set.find(node) != m_no_turn_via_node_set.end();
}
RestrictionMap::RestrictionMap(const std::shared_ptr<NodeBasedDynamicGraph> &graph,
const std::vector<TurnRestriction> &input_restrictions_list)
const std::vector<TurnRestriction> &restriction_list)
: m_count(0), m_graph(graph)
{
// decompose restriction consisting of a start, via and end node into a
// a pair of starting edge and a list of all end nodes
for (auto &restriction : input_restrictions_list)
for (auto &restriction : restriction_list)
{
m_restriction_start_nodes.insert(restriction.fromNode);
m_no_turn_via_node_set.insert(restriction.viaNode);
std::pair<NodeID, NodeID> restriction_source = {restriction.fromNode, restriction.viaNode};
RestrictionSource restriction_source = {restriction.fromNode, restriction.viaNode};
unsigned index;
auto restriction_iter = m_restriction_map.find(restriction_source);
@@ -60,7 +60,7 @@ RestrictionMap::RestrictionMap(const std::shared_ptr<NodeBasedDynamicGraph> &gra
{
index = restriction_iter->second;
// Map already contains an is_only_*-restriction
if (m_restriction_bucket_list.at(index).begin()->second)
if (m_restriction_bucket_list.at(index).begin()->is_only)
{
continue;
}
@@ -78,33 +78,35 @@ RestrictionMap::RestrictionMap(const std::shared_ptr<NodeBasedDynamicGraph> &gra
}
// Replace end v with w in each turn restriction containing u as via node
void RestrictionMap::FixupArrivingTurnRestriction(const NodeID u, const NodeID v, const NodeID w)
void RestrictionMap::FixupArrivingTurnRestriction(const NodeID node_u,
const NodeID node_v,
const NodeID node_w)
{
BOOST_ASSERT(u != SPECIAL_NODEID);
BOOST_ASSERT(v != SPECIAL_NODEID);
BOOST_ASSERT(w != SPECIAL_NODEID);
BOOST_ASSERT(node_u != SPECIAL_NODEID);
BOOST_ASSERT(node_v != SPECIAL_NODEID);
BOOST_ASSERT(node_w != SPECIAL_NODEID);
if (!RestrictionStartsAtNode(u))
if (!IsViaNode(node_u))
{
return;
}
// find all potential start edges
// it is more efficent to get a (small) list of potential start edges than iterating over all buckets
// find all potential start edges. It is more efficent to get a (small) list
// of potential start edges than iterating over all buckets
std::vector<NodeID> predecessors;
for (const EdgeID current_edge_id : m_graph->GetAdjacentEdgeRange(u))
for (const EdgeID current_edge_id : m_graph->GetAdjacentEdgeRange(node_u))
{
const EdgeData &edge_data = m_graph->GetEdgeData(current_edge_id);
const NodeID target = m_graph->GetTarget(current_edge_id);
if (edge_data.backward && (v != target))
if (edge_data.backward && (node_v != target))
{
predecessors.push_back(target);
}
}
for (const NodeID x : predecessors)
for (const NodeID node_x : predecessors)
{
auto restriction_iterator = m_restriction_map.find({x, u});
const auto restriction_iterator = m_restriction_map.find({node_x, node_u});
if (restriction_iterator == m_restriction_map.end())
{
continue;
@@ -114,61 +116,63 @@ void RestrictionMap::FixupArrivingTurnRestriction(const NodeID u, const NodeID v
auto &bucket = m_restriction_bucket_list.at(index);
for (RestrictionTarget &restriction_target : bucket)
{
if (v == restriction_target.first)
if (node_v == restriction_target.target_node)
{
restriction_target.first = w;
restriction_target.target_node = node_w;
}
}
}
}
// Replaces start edge (v, w) with (u, w). Only start node changes.
void RestrictionMap::FixupStartingTurnRestriction(const NodeID u, const NodeID v, const NodeID w)
void RestrictionMap::FixupStartingTurnRestriction(const NodeID node_u,
const NodeID node_v,
const NodeID node_w)
{
BOOST_ASSERT(u != SPECIAL_NODEID);
BOOST_ASSERT(v != SPECIAL_NODEID);
BOOST_ASSERT(w != SPECIAL_NODEID);
BOOST_ASSERT(node_u != SPECIAL_NODEID);
BOOST_ASSERT(node_v != SPECIAL_NODEID);
BOOST_ASSERT(node_w != SPECIAL_NODEID);
if (!RestrictionStartsAtNode(u))
if (!IsSourceNode(node_v))
{
return;
}
const auto restriction_iterator = m_restriction_map.find({v, w});
const auto restriction_iterator = m_restriction_map.find({node_v, node_w});
if (restriction_iterator != m_restriction_map.end())
{
const unsigned index = restriction_iterator->second;
// remove old restriction start (v,w)
m_restriction_map.erase(restriction_iterator);
// insert new restriction start (u,w) (point to index)
RestrictionSource new_source = {u, w};
m_restriction_start_nodes.emplace(node_u);
// insert new restriction start (u,w) (pointing to index)
RestrictionSource new_source = {node_u, node_w};
m_restriction_map.emplace(new_source, index);
}
}
// Check if edge (u, v) is the start of any turn restriction.
// If so returns id of first target node.
NodeID RestrictionMap::CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const
NodeID RestrictionMap::CheckForEmanatingIsOnlyTurn(const NodeID node_u, const NodeID node_v) const
{
BOOST_ASSERT(u != SPECIAL_NODEID);
BOOST_ASSERT(v != SPECIAL_NODEID);
BOOST_ASSERT(node_u != SPECIAL_NODEID);
BOOST_ASSERT(node_v != SPECIAL_NODEID);
if (!RestrictionStartsAtNode(u))
if (!IsSourceNode(node_u))
{
return SPECIAL_NODEID;
}
auto restriction_iter = m_restriction_map.find({u, v});
auto restriction_iter = m_restriction_map.find({node_u, node_v});
if (restriction_iter != m_restriction_map.end())
{
const unsigned index = restriction_iter->second;
auto &bucket = m_restriction_bucket_list.at(index);
for (const RestrictionSource &restriction_target : bucket)
for (const RestrictionTarget &restriction_target : bucket)
{
if (restriction_target.second)
if (restriction_target.is_only)
{
return restriction_target.first;
return restriction_target.target_node;
}
}
}
@@ -176,26 +180,31 @@ NodeID RestrictionMap::CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID
}
// Checks if turn <u,v,w> is actually a turn restriction.
bool RestrictionMap::CheckIfTurnIsRestricted(const NodeID u, const NodeID v, const NodeID w) const
bool RestrictionMap::CheckIfTurnIsRestricted(const NodeID node_u,
const NodeID node_v,
const NodeID node_w) const
{
BOOST_ASSERT(u != SPECIAL_NODEID);
BOOST_ASSERT(v != SPECIAL_NODEID);
BOOST_ASSERT(w != SPECIAL_NODEID);
// return false;
if (!RestrictionStartsAtNode(u))
BOOST_ASSERT(node_u != SPECIAL_NODEID);
BOOST_ASSERT(node_v != SPECIAL_NODEID);
BOOST_ASSERT(node_w != SPECIAL_NODEID);
if (!IsSourceNode(node_u))
{
return false;
}
auto restriction_iter = m_restriction_map.find({u, v});
auto restriction_iter = m_restriction_map.find({node_u, node_v});
if (restriction_iter != m_restriction_map.end())
{
const unsigned index = restriction_iter->second;
const auto &bucket = m_restriction_bucket_list.at(index);
for (const RestrictionTarget &restriction_target : bucket)
{
if ((w == restriction_target.first) && // target found
(!restriction_target.second)) // and not an only_-restr.
if ((node_w == restriction_target.target_node) && // target found
(!restriction_target.is_only) // and not an only_-restr.
)
{
return true;
}
@@ -205,7 +214,7 @@ bool RestrictionMap::CheckIfTurnIsRestricted(const NodeID u, const NodeID v, con
}
// check of node is the start of any restriction
bool RestrictionMap::RestrictionStartsAtNode(const NodeID node) const
bool RestrictionMap::IsSourceNode(const NodeID node) const
{
if (m_restriction_start_nodes.find(node) == m_restriction_start_nodes.end())
{
+59 -7
View File
@@ -39,8 +39,59 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <unordered_map>
#include <unordered_set>
// Efficent look up if an edge is the start + via node of a TurnRestriction
// EdgeBasedEdgeFactory decides by it if edges are inserted or geometry is compressed
struct RestrictionSource
{
NodeID start_node;
NodeID via_node;
RestrictionSource(NodeID start, NodeID via) : start_node(start), via_node(via)
{
}
friend inline bool operator==(const RestrictionSource &lhs, const RestrictionSource &rhs)
{
return (lhs.start_node == rhs.start_node && lhs.via_node == rhs.via_node);
}
};
struct RestrictionTarget
{
NodeID target_node;
bool is_only;
explicit RestrictionTarget(NodeID target, bool only) : target_node(target), is_only(only)
{
}
friend inline bool operator==(const RestrictionTarget &lhs, const RestrictionTarget &rhs)
{
return (lhs.target_node == rhs.target_node && lhs.is_only == rhs.is_only);
}
};
namespace std
{
template <> struct hash<RestrictionSource>
{
size_t operator()(const RestrictionSource &r_source) const
{
return hash_val(r_source.start_node, r_source.via_node);
}
};
template <> struct hash<RestrictionTarget>
{
size_t operator()(const RestrictionTarget &r_target) const
{
return hash_val(r_target.target_node, r_target.is_only);
}
};
}
/**
\brief Efficent look up if an edge is the start + via node of a TurnRestriction
EdgeBasedEdgeFactory decides by it if edges are inserted or geometry is compressed
*/
class RestrictionMap
{
public:
@@ -51,13 +102,14 @@ class RestrictionMap
void FixupStartingTurnRestriction(const NodeID u, const NodeID v, const NodeID w);
NodeID CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const;
bool CheckIfTurnIsRestricted(const NodeID u, const NodeID v, const NodeID w) const;
bool IsNodeAViaNode(const NodeID node) const;
unsigned size() { return m_count; }
bool IsViaNode(const NodeID node) const;
unsigned size()
{
return m_count;
}
private:
bool RestrictionStartsAtNode(const NodeID node) const;
typedef std::pair<NodeID, NodeID> RestrictionSource;
typedef std::pair<NodeID, bool> RestrictionTarget;
bool IsSourceNode(const NodeID node) const;
typedef std::vector<RestrictionTarget> EmanatingRestrictionsVector;
typedef NodeBasedDynamicGraph::EdgeData EdgeData;
+13 -6
View File
@@ -57,7 +57,10 @@ void RouteParameters::setService(const std::string &service_string) { service =
void RouteParameters::setOutputFormat(const std::string &format) { output_format = format; }
void RouteParameters::setJSONpParameter(const std::string &parameter) { jsonp_parameter = parameter; }
void RouteParameters::setJSONpParameter(const std::string &parameter)
{
jsonp_parameter = parameter;
}
void RouteParameters::addHint(const std::string &hint)
{
@@ -68,15 +71,19 @@ void RouteParameters::addHint(const std::string &hint)
}
}
void RouteParameters::setLanguage(const std::string &language_string) { language = language_string; }
void RouteParameters::setLanguage(const std::string &language_string)
{
language = language_string;
}
void RouteParameters::setGeometryFlag(const bool flag) { geometry = flag; }
void RouteParameters::setCompressionFlag(const bool flag) { compression = flag; }
void RouteParameters::addCoordinate(const boost::fusion::vector<double, double> &transmitted_coordinates)
void
RouteParameters::addCoordinate(const boost::fusion::vector<double, double> &transmitted_coordinates)
{
const int lat = COORDINATE_PRECISION * boost::fusion::at_c<0>(transmitted_coordinates);
const int lon = COORDINATE_PRECISION * boost::fusion::at_c<1>(transmitted_coordinates);
coordinates.emplace_back(lat, lon);
coordinates.emplace_back(
static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<0>(transmitted_coordinates)),
static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<1>(transmitted_coordinates)));
}
+2 -2
View File
@@ -50,8 +50,8 @@ template <class DataFacadeT> class SearchEngine
: facade(facade), shortest_path(facade, engine_working_data),
alternative_path(facade, engine_working_data), distance_table(facade, engine_working_data)
{
static_assert(!std::is_pointer<DataFacadeT>(), "don't instantiate with ptr type");
static_assert(std::is_object<DataFacadeT>(), "don't instantiate with void, function, or reference");
static_assert(!std::is_pointer<DataFacadeT>::value, "don't instantiate with ptr type");
static_assert(std::is_object<DataFacadeT>::value, "don't instantiate with void, function, or reference");
}
~SearchEngine() {}
+2
View File
@@ -27,6 +27,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "SearchEngineData.h"
#include "BinaryHeap.h"
void SearchEngineData::InitializeOrClearFirstThreadLocalStorage(const unsigned number_of_nodes)
{
if (forwardHeap.get())
+2 -7
View File
@@ -28,15 +28,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef SEARCH_ENGINE_DATA_H
#define SEARCH_ENGINE_DATA_H
#include "BinaryHeap.h"
#include "QueryEdge.h"
#include "StaticGraph.h"
#include <boost/thread/tss.hpp>
#include "../typedefs.h"
#include <boost/thread.hpp>
#include <vector>
#include "BinaryHeap.h"
struct HeapData
{
+12 -10
View File
@@ -39,30 +39,32 @@ struct SegmentInformation
{
FixedPointCoordinate location;
NodeID name_id;
unsigned duration;
double length;
EdgeWeight duration;
float length;
short bearing; // more than enough [0..3600] fits into 12 bits
TurnInstruction turn_instruction;
bool necessary;
bool necessary:1;
bool is_via_location:1;
explicit SegmentInformation(const FixedPointCoordinate &location,
const NodeID name_id,
const unsigned duration,
const double length,
const EdgeWeight duration,
const float length,
const TurnInstruction turn_instruction,
const bool necessary)
const bool necessary,
const bool is_via_location)
: location(location), name_id(name_id), duration(duration), length(length), bearing(0),
turn_instruction(turn_instruction), necessary(necessary)
turn_instruction(turn_instruction), necessary(necessary), is_via_location(is_via_location)
{
}
explicit SegmentInformation(const FixedPointCoordinate &location,
const NodeID name_id,
const unsigned duration,
const double length,
const EdgeWeight duration,
const float length,
const TurnInstruction turn_instruction)
: location(location), name_id(name_id), duration(duration), length(length), bearing(0),
turn_instruction(turn_instruction), necessary(turn_instruction != TurnInstruction::NoTurn)
turn_instruction(turn_instruction), necessary(turn_instruction != TurnInstruction::NoTurn), is_via_location(false)
{
}
};
+137
View File
@@ -34,7 +34,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/interprocess/mapped_region.hpp>
#ifndef WIN32
#include <boost/interprocess/xsi_shared_memory.hpp>
#else
#include <boost/interprocess/shared_memory_object.hpp>
#endif
#ifdef __linux__
#include <sys/ipc.h>
@@ -57,6 +61,7 @@ struct OSRMLockFile
}
};
#ifndef WIN32
class SharedMemory
{
@@ -189,6 +194,138 @@ class SharedMemory
boost::interprocess::mapped_region region;
shm_remove remover;
};
#else
// Windows - specific code
class SharedMemory : boost::noncopyable
{
// Remove shared memory on destruction
class shm_remove : boost::noncopyable
{
private:
char *m_shmid;
bool m_initialized;
public:
void SetID(char *shmid)
{
m_shmid = shmid;
m_initialized = true;
}
shm_remove() : m_shmid("undefined"), m_initialized(false) {}
~shm_remove()
{
if (m_initialized)
{
SimpleLogger().Write(logDEBUG) << "automatic memory deallocation";
if (!boost::interprocess::shared_memory_object::remove(m_shmid))
{
SimpleLogger().Write(logDEBUG) << "could not deallocate id " << m_shmid;
}
}
}
};
public:
void *Ptr() const { return region.get_address(); }
SharedMemory(const boost::filesystem::path &lock_file,
const int id,
const uint64_t size = 0,
bool read_write = false,
bool remove_prev = true)
{
sprintf(key, "%s.%d", "osrm.lock", id);
if (0 == size)
{ // read_only
shm = boost::interprocess::shared_memory_object(
boost::interprocess::open_only,
key,
read_write ? boost::interprocess::read_write : boost::interprocess::read_only);
region = boost::interprocess::mapped_region(
shm, read_write ? boost::interprocess::read_write : boost::interprocess::read_only);
}
else
{ // writeable pointer
// remove previously allocated mem
if (remove_prev)
{
Remove(key);
}
shm = boost::interprocess::shared_memory_object(
boost::interprocess::open_or_create, key, boost::interprocess::read_write);
shm.truncate(size);
region = boost::interprocess::mapped_region(shm, boost::interprocess::read_write);
remover.SetID(key);
SimpleLogger().Write(logDEBUG) << "writeable memory allocated " << size << " bytes";
}
}
static bool RegionExists(const int id)
{
bool result = true;
try
{
char k[500];
build_key(id, k);
result = RegionExists(k);
}
catch (...) { result = false; }
return result;
}
static bool Remove(const int id)
{
char k[500];
build_key(id, k);
return Remove(k);
}
private:
static void build_key(int id, char *key)
{
OSRMLockFile lock_file;
sprintf(key, "%s.%d", "osrm.lock", id);
}
static bool RegionExists(const char *key)
{
bool result = true;
try
{
boost::interprocess::shared_memory_object shm(
boost::interprocess::open_only, key, boost::interprocess::read_write);
}
catch (...) { result = false; }
return result;
}
static bool Remove(char *key)
{
bool ret = false;
try
{
SimpleLogger().Write(logDEBUG) << "deallocating prev memory";
ret = boost::interprocess::shared_memory_object::remove(key);
}
catch (const boost::interprocess::interprocess_exception &e)
{
if (e.get_error_code() != boost::interprocess::not_found_error)
{
throw;
}
}
return ret;
}
char key[500];
boost::interprocess::shared_memory_object shm;
boost::interprocess::mapped_region region;
shm_remove remover;
};
#endif
template <class LockFileT = OSRMLockFile> class SharedMemoryFactory_tmpl
{
+2 -2
View File
@@ -128,8 +128,8 @@ template <> class SharedMemoryWrapper<bool>
bool at(const std::size_t index) const
{
const unsigned bucket = index / 32;
const unsigned offset = index % 32;
const std::size_t bucket = index / 32;
const unsigned offset = static_cast<unsigned>(index % 32);
return m_ptr[bucket] & (1 << offset);
}
+24 -20
View File
@@ -33,8 +33,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../Util/SimpleLogger.h"
#include "../typedefs.h"
#include <boost/assert.hpp>
#include <boost/range/irange.hpp>
#include <tbb/parallel_sort.h>
#include <algorithm>
#include <limits>
#include <vector>
@@ -81,7 +84,7 @@ template <typename EdgeDataT, bool UseSharedMemory = false> class StaticGraph
StaticGraph(const int nodes, std::vector<InputEdge> &graph)
{
std::sort(graph.begin(), graph.end());
tbb::parallel_sort(graph.begin(), graph.end());
number_of_nodes = nodes;
number_of_edges = (EdgeIterator)graph.size();
node_array.resize(number_of_nodes + 1);
@@ -106,7 +109,7 @@ template <typename EdgeDataT, bool UseSharedMemory = false> class StaticGraph
{
edge_array[i].target = graph[edge].target;
edge_array[i].data = graph[edge].data;
assert(edge_array[i].data.distance > 0);
BOOST_ASSERT(edge_array[i].data.distance > 0);
edge++;
}
}
@@ -127,26 +130,27 @@ template <typename EdgeDataT, bool UseSharedMemory = false> class StaticGraph
{
for (auto eid : GetAdjacentEdgeRange(u))
{
const unsigned v = GetTarget(eid);
const EdgeData &data = GetEdgeData(eid);
if (data.shortcut)
if (!data.shortcut)
{
const EdgeID first_edge_id = FindEdgeInEitherDirection(u, data.id);
if (SPECIAL_EDGEID == first_edge_id)
{
SimpleLogger().Write(logWARNING) << "cannot find first segment of edge ("
<< u << "," << data.id << "," << v
<< "), eid: " << eid;
BOOST_ASSERT(false);
}
const EdgeID second_edge_id = FindEdgeInEitherDirection(data.id, v);
if (SPECIAL_EDGEID == second_edge_id)
{
SimpleLogger().Write(logWARNING) << "cannot find second segment of edge ("
<< u << "," << data.id << "," << v
<< "), eid: " << eid;
BOOST_ASSERT(false);
}
continue;
}
const unsigned v = GetTarget(eid);
const EdgeID first_edge_id = FindEdgeInEitherDirection(u, data.id);
if (SPECIAL_EDGEID == first_edge_id)
{
SimpleLogger().Write(logWARNING) << "cannot find first segment of edge ("
<< u << "," << data.id << "," << v
<< "), eid: " << eid;
BOOST_ASSERT(false);
}
const EdgeID second_edge_id = FindEdgeInEitherDirection(data.id, v);
if (SPECIAL_EDGEID == second_edge_id)
{
SimpleLogger().Write(logWARNING) << "cannot find second segment of edge ("
<< u << "," << data.id << "," << v
<< "), eid: " << eid;
BOOST_ASSERT(false);
}
}
p.printIncrement();
+434 -179
View File
@@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../Util/MercatorUtil.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../Util/TimingUtil.h"
#include "../typedefs.h"
#include <osrm/Coordinate.h>
@@ -45,12 +46,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/thread.hpp>
#include <boost/variant.hpp>
#include <tbb/parallel_for.h>
#include <tbb/parallel_sort.h>
#include <algorithm>
#include <array>
#include <chrono>
#include <limits>
#include <memory>
#include <queue>
@@ -64,7 +67,7 @@ const static uint32_t RTREE_LEAF_NODE_SIZE = 1024;
static boost::thread_specific_ptr<boost::filesystem::ifstream> thread_local_rtree_stream;
// Implements a static, i.e. packed, R-tree
template <class DataT,
template <class EdgeDataT,
class CoordinateListT = std::vector<FixedPointCoordinate>,
bool UseSharedMemory = false>
class StaticRTree
@@ -77,7 +80,7 @@ class StaticRTree
int32_t min_lon, max_lon;
int32_t min_lat, max_lat;
inline void InitializeMBRectangle(const std::array<DataT, RTREE_LEAF_NODE_SIZE> &objects,
inline void InitializeMBRectangle(const std::array<EdgeDataT, RTREE_LEAF_NODE_SIZE> &objects,
const uint32_t element_count,
const std::vector<NodeInfo> &coordinate_list)
{
@@ -97,14 +100,22 @@ class StaticRTree
std::max(coordinate_list.at(objects[i].u).lat,
coordinate_list.at(objects[i].v).lat));
}
BOOST_ASSERT(min_lat != std::numeric_limits<int>::min());
BOOST_ASSERT(min_lon != std::numeric_limits<int>::min());
BOOST_ASSERT(max_lat != std::numeric_limits<int>::min());
BOOST_ASSERT(max_lon != std::numeric_limits<int>::min());
}
inline void AugmentMBRectangle(const RectangleInt2D &other)
inline void MergeBoundingBoxes(const RectangleInt2D &other)
{
min_lon = std::min(min_lon, other.min_lon);
max_lon = std::max(max_lon, other.max_lon);
min_lat = std::min(min_lat, other.min_lat);
max_lat = std::max(max_lat, other.max_lat);
BOOST_ASSERT(min_lat != std::numeric_limits<int>::min());
BOOST_ASSERT(min_lon != std::numeric_limits<int>::min());
BOOST_ASSERT(max_lat != std::numeric_limits<int>::min());
BOOST_ASSERT(max_lon != std::numeric_limits<int>::min());
}
inline FixedPointCoordinate Centroid() const
@@ -130,7 +141,7 @@ class StaticRTree
inline float GetMinDist(const FixedPointCoordinate &location) const
{
bool is_contained = Contains(location);
const bool is_contained = Contains(location);
if (is_contained)
{
return 0.;
@@ -215,15 +226,15 @@ class StaticRTree
private:
struct WrappedInputElement
{
explicit WrappedInputElement(const uint32_t _array_index, const uint64_t _hilbert_value)
: m_array_index(_array_index), m_hilbert_value(_hilbert_value)
explicit WrappedInputElement(const uint64_t _hilbert_value, const uint32_t _array_index)
: m_hilbert_value(_hilbert_value), m_array_index(_array_index)
{
}
WrappedInputElement() : m_array_index(UINT_MAX), m_hilbert_value(0) {}
WrappedInputElement() : m_hilbert_value(0), m_array_index(UINT_MAX) {}
uint32_t m_array_index;
uint64_t m_hilbert_value;
uint32_t m_array_index;
inline bool operator<(const WrappedInputElement &other) const
{
@@ -235,24 +246,60 @@ class StaticRTree
{
LeafNode() : object_count(0) {}
uint32_t object_count;
std::array<DataT, RTREE_LEAF_NODE_SIZE> objects;
std::array<EdgeDataT, RTREE_LEAF_NODE_SIZE> objects;
};
struct QueryCandidate
{
explicit QueryCandidate(const uint32_t n_id, const float dist)
: node_id(n_id), min_dist(dist)
explicit QueryCandidate(const float dist, const uint32_t n_id)
: min_dist(dist), node_id(n_id)
{
}
QueryCandidate() : node_id(UINT_MAX), min_dist(std::numeric_limits<float>::max()) {}
uint32_t node_id;
QueryCandidate() : min_dist(std::numeric_limits<float>::max()), node_id(UINT_MAX) {}
float min_dist;
uint32_t node_id;
inline bool operator<(const QueryCandidate &other) const
{
return min_dist < other.min_dist;
// Attn: this is reversed order. std::pq is a max pq!
return other.min_dist < min_dist;
}
};
typedef boost::variant<TreeNode, EdgeDataT> IncrementalQueryNodeType;
struct IncrementalQueryCandidate
{
explicit IncrementalQueryCandidate(const float dist, const IncrementalQueryNodeType &node)
: min_dist(dist), node(node)
{
}
IncrementalQueryCandidate() : min_dist(std::numeric_limits<float>::max()) {}
inline bool operator<(const IncrementalQueryCandidate &other) const
{
// Attn: this is reversed order. std::pq is a max pq!
return other.min_dist < min_dist;
}
inline bool RepresentsTreeNode() const
{
return boost::apply_visitor(decide_type_visitor(), node);
}
float min_dist;
IncrementalQueryNodeType node;
private:
class decide_type_visitor : public boost::static_visitor<bool>
{
public:
bool operator()(const TreeNode &) const { return true; }
template<typename AnotherType>
bool operator()(const AnotherType &) const { return false; }
};
};
typename ShM<TreeNode, UseSharedMemory>::vector m_search_tree;
uint64_t m_element_count;
const std::string m_leaf_node_filename;
@@ -263,7 +310,7 @@ class StaticRTree
StaticRTree(const StaticRTree &) = delete;
// Construct a packed Hilbert-R-Tree with Kamel-Faloutsos algorithm [1]
explicit StaticRTree(std::vector<DataT> &input_data_vector,
explicit StaticRTree(std::vector<EdgeDataT> &input_data_vector,
const std::string tree_node_filename,
const std::string leaf_node_filename,
const std::vector<NodeInfo> &coordinate_list)
@@ -273,36 +320,44 @@ class StaticRTree
<< " edge elements build on-top of " << coordinate_list.size()
<< " coordinates";
std::chrono::time_point<std::chrono::steady_clock> time0 = std::chrono::steady_clock::now();
TIMER_START(construction);
std::vector<WrappedInputElement> input_wrapper_vector(m_element_count);
HilbertCode get_hilbert_number;
// generate auxiliary vector of hilbert-values
#pragma omp parallel for schedule(guided)
for (uint64_t element_counter = 0; element_counter < m_element_count; ++element_counter)
{
input_wrapper_vector[element_counter].m_array_index = element_counter;
// Get Hilbert-Value for centroid in mercartor projection
DataT const &current_element = input_data_vector[element_counter];
FixedPointCoordinate current_centroid =
DataT::Centroid(FixedPointCoordinate(coordinate_list.at(current_element.u).lat,
coordinate_list.at(current_element.u).lon),
FixedPointCoordinate(coordinate_list.at(current_element.v).lat,
coordinate_list.at(current_element.v).lon));
current_centroid.lat =
COORDINATE_PRECISION * lat2y(current_centroid.lat / COORDINATE_PRECISION);
// generate auxiliary vector of hilbert-values
tbb::parallel_for(
tbb::blocked_range<uint64_t>(0, m_element_count),
[&input_data_vector, &input_wrapper_vector, &get_hilbert_number, &coordinate_list](
const tbb::blocked_range<uint64_t> &range)
{
for (uint64_t element_counter = range.begin(); element_counter != range.end();
++element_counter)
{
WrappedInputElement &current_wrapper = input_wrapper_vector[element_counter];
current_wrapper.m_array_index = element_counter;
uint64_t current_hilbert_value = get_hilbert_number(current_centroid);
input_wrapper_vector[element_counter].m_hilbert_value = current_hilbert_value;
}
EdgeDataT const &current_element = input_data_vector[element_counter];
// Get Hilbert-Value for centroid in mercartor projection
FixedPointCoordinate current_centroid = EdgeDataT::Centroid(
FixedPointCoordinate(coordinate_list.at(current_element.u).lat,
coordinate_list.at(current_element.u).lon),
FixedPointCoordinate(coordinate_list.at(current_element.v).lat,
coordinate_list.at(current_element.v).lon));
current_centroid.lat =
COORDINATE_PRECISION * lat2y(current_centroid.lat / COORDINATE_PRECISION);
current_wrapper.m_hilbert_value = get_hilbert_number(current_centroid);
}
});
// open leaf file
boost::filesystem::ofstream leaf_node_file(leaf_node_filename, std::ios::binary);
leaf_node_file.write((char *)&m_element_count, sizeof(uint64_t));
// sort the hilbert-value representatives
std::sort(input_wrapper_vector.begin(), input_wrapper_vector.end());
tbb::parallel_sort(input_wrapper_vector.begin(), input_wrapper_vector.end());
std::vector<TreeNode> tree_nodes_in_level;
// pack M elements into leaf node and write to leaf file
@@ -363,8 +418,8 @@ class StaticRTree
// add tree node to parent entry
parent_node.children[current_child_node_index] = m_search_tree.size();
m_search_tree.emplace_back(current_child_node);
// augment MBR of parent
parent_node.minimum_bounding_rectangle.AugmentMBRectangle(
// merge MBRs
parent_node.minimum_bounding_rectangle.MergeBoundingBoxes(
current_child_node.minimum_bounding_rectangle);
// increase counters
++parent_node.child_count;
@@ -383,17 +438,21 @@ class StaticRTree
// reverse and renumber tree to have root at index 0
std::reverse(m_search_tree.begin(), m_search_tree.end());
#pragma omp parallel for schedule(guided)
for (uint32_t i = 0; i < m_search_tree.size(); ++i)
{
TreeNode &current_tree_node = m_search_tree[i];
for (uint32_t j = 0; j < current_tree_node.child_count; ++j)
uint32_t search_tree_size = m_search_tree.size();
tbb::parallel_for(tbb::blocked_range<uint32_t>(0, search_tree_size),
[this, &search_tree_size](const tbb::blocked_range<uint32_t> &range)
{
for (uint32_t i = range.begin(); i != range.end(); ++i)
{
const uint32_t old_id = current_tree_node.children[j];
const uint32_t new_id = m_search_tree.size() - old_id - 1;
current_tree_node.children[j] = new_id;
TreeNode &current_tree_node = this->m_search_tree[i];
for (uint32_t j = 0; j < current_tree_node.child_count; ++j)
{
const uint32_t old_id = current_tree_node.children[j];
const uint32_t new_id = search_tree_size - old_id - 1;
current_tree_node.children[j] = new_id;
}
}
}
});
// open tree file
boost::filesystem::ofstream tree_node_file(tree_node_filename, std::ios::binary);
@@ -404,9 +463,9 @@ class StaticRTree
tree_node_file.write((char *)&m_search_tree[0], sizeof(TreeNode) * size_of_tree);
// close tree node file.
tree_node_file.close();
std::chrono::time_point<std::chrono::steady_clock> time1 = std::chrono::steady_clock::now();
std::chrono::duration<double> elapsed_seconds = time1 - time0;
SimpleLogger().Write() << "finished r-tree construction in " << (elapsed_seconds.count())
TIMER_STOP(construction);
SimpleLogger().Write() << "finished r-tree construction in " << TIMER_SEC(construction)
<< " seconds";
}
@@ -433,7 +492,10 @@ class StaticRTree
tree_node_file.read((char *)&tree_size, sizeof(uint32_t));
m_search_tree.resize(tree_size);
tree_node_file.read((char *)&m_search_tree[0], sizeof(TreeNode) * tree_size);
if (tree_size > 0)
{
tree_node_file.read((char *)&m_search_tree[0], sizeof(TreeNode) * tree_size);
}
tree_node_file.close();
// open leaf node file and store thread specific pointer
if (!boost::filesystem::exists(leaf_file))
@@ -489,16 +551,13 @@ class StaticRTree
const unsigned zoom_level)
{
bool ignore_tiny_components = (zoom_level <= 14);
DataT nearest_edge;
float min_dist = std::numeric_limits<float>::max();
float min_max_dist = std::numeric_limits<float>::max();
bool found_a_nearest_edge = false;
// initialize queue with root element
std::priority_queue<QueryCandidate> traversal_queue;
float current_min_dist =
m_search_tree[0].minimum_bounding_rectangle.GetMinDist(input_coordinate);
traversal_queue.emplace(0, current_min_dist);
traversal_queue.emplace(0.f, 0);
while (!traversal_queue.empty())
{
@@ -516,7 +575,7 @@ class StaticRTree
LoadLeafFromDisk(current_tree_node.children[0], current_leaf_node);
for (uint32_t i = 0; i < current_leaf_node.object_count; ++i)
{
DataT const &current_edge = current_leaf_node.objects[i];
EdgeDataT const &current_edge = current_leaf_node.objects[i];
if (ignore_tiny_components && current_edge.is_in_tiny_cc)
{
continue;
@@ -532,9 +591,7 @@ class StaticRTree
{
// found a new minimum
min_dist = current_minimum_distance;
result_coordinate.lat = m_coordinate_list->at(current_edge.u).lat;
result_coordinate.lon = m_coordinate_list->at(current_edge.u).lon;
found_a_nearest_edge = true;
result_coordinate = m_coordinate_list->at(current_edge.u);
}
current_minimum_distance =
@@ -548,94 +605,281 @@ class StaticRTree
{
// found a new minimum
min_dist = current_minimum_distance;
result_coordinate.lat = m_coordinate_list->at(current_edge.v).lat;
result_coordinate.lon = m_coordinate_list->at(current_edge.v).lon;
found_a_nearest_edge = true;
result_coordinate = m_coordinate_list->at(current_edge.v);
}
}
}
else
{
// traverse children, prune if global mindist is smaller than local one
min_max_dist = ExploreTreeNode(current_tree_node,
input_coordinate,
min_dist,
min_max_dist,
traversal_queue);
}
}
}
return result_coordinate.isValid();
}
// implementation of the Hjaltason/Samet query [3], a BFS traversal of the tree
bool
IncrementalFindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
std::vector<PhantomNode> &result_phantom_node_vector,
const unsigned zoom_level,
const unsigned number_of_results,
const unsigned max_checked_segments = 4*RTREE_LEAF_NODE_SIZE)
{
// TIMER_START(samet);
// SimpleLogger().Write(logDEBUG) << "searching for " << number_of_results << " results";
std::vector<float> min_found_distances(number_of_results, std::numeric_limits<float>::max());
unsigned dequeues = 0;
unsigned inspected_mbrs = 0;
unsigned loaded_leafs = 0;
unsigned inspected_segments = 0;
unsigned pruned_elements = 0;
unsigned ignored_segments = 0;
unsigned ignored_mbrs = 0;
unsigned number_of_results_found_in_big_cc = 0;
unsigned number_of_results_found_in_tiny_cc = 0;
// initialize queue with root element
std::priority_queue<IncrementalQueryCandidate> traversal_queue;
traversal_queue.emplace(0.f, m_search_tree[0]);
while (!traversal_queue.empty())
{
const IncrementalQueryCandidate current_query_node = traversal_queue.top();
traversal_queue.pop();
++dequeues;
const float current_min_dist = min_found_distances[number_of_results-1];
if (current_query_node.min_dist > current_min_dist)
{
++pruned_elements;
continue;
}
if (current_query_node.RepresentsTreeNode())
{
const TreeNode & current_tree_node = boost::get<TreeNode>(current_query_node.node);
if (current_tree_node.child_is_on_disk)
{
++loaded_leafs;
// SimpleLogger().Write(logDEBUG) << "loading leaf: " << current_tree_node.children[0] << " w/ mbr [" <<
// current_tree_node.minimum_bounding_rectangle.min_lat/COORDINATE_PRECISION << "," <<
// current_tree_node.minimum_bounding_rectangle.min_lon/COORDINATE_PRECISION << "," <<
// current_tree_node.minimum_bounding_rectangle.max_lat/COORDINATE_PRECISION << "-" <<
// current_tree_node.minimum_bounding_rectangle.max_lon/COORDINATE_PRECISION << "]";
LeafNode current_leaf_node;
LoadLeafFromDisk(current_tree_node.children[0], current_leaf_node);
// Add all objects from leaf into queue
for (uint32_t i = 0; i < current_leaf_node.object_count; ++i)
{
const auto &current_edge = current_leaf_node.objects[i];
const float current_perpendicular_distance =
FixedPointCoordinate::ComputePerpendicularDistance(
m_coordinate_list->at(current_edge.u),
m_coordinate_list->at(current_edge.v),
input_coordinate);
// distance must be non-negative
BOOST_ASSERT(0. <= current_perpendicular_distance);
if (current_perpendicular_distance < current_min_dist)
{
traversal_queue.emplace(current_perpendicular_distance, current_edge);
}
else
{
++ignored_segments;
}
}
// SimpleLogger().Write(logDEBUG) << "added " << current_leaf_node.object_count << " roads into queue of " << traversal_queue.size();
}
else
{
++inspected_mbrs;
// explore inner node
// SimpleLogger().Write(logDEBUG) << "explore inner node w/ mbr [" <<
// current_tree_node.minimum_bounding_rectangle.min_lat/COORDINATE_PRECISION << "," <<
// current_tree_node.minimum_bounding_rectangle.min_lon/COORDINATE_PRECISION << "," <<
// current_tree_node.minimum_bounding_rectangle.max_lat/COORDINATE_PRECISION << "-" <<
// current_tree_node.minimum_bounding_rectangle.max_lon/COORDINATE_PRECISION << "," << "]";
// for each child mbr
for (uint32_t i = 0; i < current_tree_node.child_count; ++i)
{
const int32_t child_id = current_tree_node.children[i];
const TreeNode &child_tree_node = m_search_tree[child_id];
const RectangleT &child_rectangle =
child_tree_node.minimum_bounding_rectangle;
const float current_min_dist =
child_rectangle.GetMinDist(input_coordinate);
const float current_min_max_dist =
child_rectangle.GetMinMaxDist(input_coordinate);
if (current_min_max_dist < min_max_dist)
const RectangleT &child_rectangle = child_tree_node.minimum_bounding_rectangle;
const float lower_bound_to_element = child_rectangle.GetMinDist(input_coordinate);
// TODO - enough elements found, i.e. nearest distance > maximum distance?
// ie. some measure of 'confidence of accuracy'
// check if it needs to be explored by mindist
if (lower_bound_to_element < current_min_dist)
{
min_max_dist = current_min_max_dist;
traversal_queue.emplace(lower_bound_to_element, child_tree_node);
}
if (current_min_dist > min_max_dist)
else
{
continue;
++ignored_mbrs;
}
if (current_min_dist > min_dist)
{ // upward pruning
continue;
}
traversal_queue.emplace(child_id, current_min_dist);
}
// SimpleLogger().Write(logDEBUG) << "added " << current_tree_node.child_count << " mbrs into queue of " << traversal_queue.size();
}
}
else
{
++inspected_segments;
// inspecting an actual road segment
const EdgeDataT & current_segment = boost::get<EdgeDataT>(current_query_node.node);
// don't collect too many results from small components
if (number_of_results_found_in_big_cc == number_of_results && !current_segment.is_in_tiny_cc)
{
continue;
}
// don't collect too many results from big components
if (number_of_results_found_in_tiny_cc == number_of_results && current_segment.is_in_tiny_cc)
{
continue;
}
// check if it is smaller than what we had before
float current_ratio = 0.;
FixedPointCoordinate foot_point_coordinate_on_segment;
const float current_perpendicular_distance =
FixedPointCoordinate::ComputePerpendicularDistance(
m_coordinate_list->at(current_segment.u),
m_coordinate_list->at(current_segment.v),
input_coordinate,
foot_point_coordinate_on_segment,
current_ratio);
BOOST_ASSERT(0. <= current_perpendicular_distance);
if ((current_perpendicular_distance < current_min_dist) &&
!EpsilonCompare(current_perpendicular_distance, current_min_dist))
{
// store phantom node in result vector
result_phantom_node_vector.emplace_back(
current_segment.forward_edge_based_node_id,
current_segment.reverse_edge_based_node_id,
current_segment.name_id,
current_segment.forward_weight,
current_segment.reverse_weight,
current_segment.forward_offset,
current_segment.reverse_offset,
current_segment.packed_geometry_id,
foot_point_coordinate_on_segment,
current_segment.fwd_segment_position);
// Hack to fix rounding errors and wandering via nodes.
FixUpRoundingIssue(input_coordinate, result_phantom_node_vector.back());
// set forward and reverse weights on the phantom node
SetForwardAndReverseWeightsOnPhantomNode(current_segment,
result_phantom_node_vector.back());
// do we have results only in a small scc
if (current_segment.is_in_tiny_cc)
{
++number_of_results_found_in_tiny_cc;
}
else
{
// found an element in a large component
min_found_distances[number_of_results_found_in_big_cc] = current_perpendicular_distance;
++number_of_results_found_in_big_cc;
// SimpleLogger().Write(logDEBUG) << std::setprecision(8) << foot_point_coordinate_on_segment << " at " << current_perpendicular_distance;
}
}
}
// TODO add indicator to prune if maxdist > threshold
if (number_of_results == number_of_results_found_in_big_cc || inspected_segments >= max_checked_segments)
{
// SimpleLogger().Write(logDEBUG) << "flushing queue of " << traversal_queue.size() << " elements";
// work-around for traversal_queue.clear();
traversal_queue = std::priority_queue<IncrementalQueryCandidate>{};
}
}
return found_a_nearest_edge;
// for (const PhantomNode& result_node : result_phantom_node_vector)
// {
// SimpleLogger().Write(logDEBUG) << std::setprecision(8) << "found location " << result_node.forward_node_id << " at " << result_node.location;
// }
// SimpleLogger().Write(logDEBUG) << "dequeues: " << dequeues;
// SimpleLogger().Write(logDEBUG) << "inspected_mbrs: " << inspected_mbrs;
// SimpleLogger().Write(logDEBUG) << "loaded_leafs: " << loaded_leafs;
// SimpleLogger().Write(logDEBUG) << "inspected_segments: " << inspected_segments;
// SimpleLogger().Write(logDEBUG) << "pruned_elements: " << pruned_elements;
// SimpleLogger().Write(logDEBUG) << "ignored_segments: " << ignored_segments;
// SimpleLogger().Write(logDEBUG) << "ignored_mbrs: " << ignored_mbrs;
// SimpleLogger().Write(logDEBUG) << "number_of_results_found_in_big_cc: " << number_of_results_found_in_big_cc;
// SimpleLogger().Write(logDEBUG) << "number_of_results_found_in_tiny_cc: " << number_of_results_found_in_tiny_cc;
// TIMER_STOP(samet);
// SimpleLogger().Write() << "query took " << TIMER_MSEC(samet) << "ms";
// if we found an element in either category, then we are good
return !result_phantom_node_vector.empty();
}
bool FindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
PhantomNode &result_phantom_node,
const unsigned zoom_level)
{
// SimpleLogger().Write() << "searching for coordinate " << input_coordinate;
std::vector<PhantomNode> result_phantom_node_vector;
IncrementalFindPhantomNodeForCoordinate(input_coordinate, result_phantom_node_vector, zoom_level, 2);
// if (!result_phantom_node_vector.empty())
// {
// result_phantom_node = result_phantom_node_vector.front();
// }
// return !result_phantom_node_vector.empty();
const bool ignore_tiny_components = (zoom_level <= 14);
DataT nearest_edge;
EdgeDataT nearest_edge;
float min_dist = std::numeric_limits<float>::max();
float min_max_dist = std::numeric_limits<float>::max();
bool found_a_nearest_edge = false;
FixedPointCoordinate nearest, current_start_coordinate, current_end_coordinate;
// initialize queue with root element
std::priority_queue<QueryCandidate> traversal_queue;
float current_min_dist =
m_search_tree[0].minimum_bounding_rectangle.GetMinDist(input_coordinate);
traversal_queue.emplace(0, current_min_dist);
traversal_queue.emplace(0.f, 0);
BOOST_ASSERT_MSG(std::numeric_limits<float>::epsilon() >
(0. - traversal_queue.top().min_dist),
"Root element in NN Search has min dist != 0.");
LeafNode current_leaf_node;
while (!traversal_queue.empty())
{
const QueryCandidate current_query_node = traversal_queue.top();
traversal_queue.pop();
const bool prune_downward = (current_query_node.min_dist >= min_max_dist);
const bool prune_upward = (current_query_node.min_dist >= min_dist);
const bool prune_downward = (current_query_node.min_dist > min_max_dist);
const bool prune_upward = (current_query_node.min_dist > min_dist);
if (!prune_downward && !prune_upward)
{ // downward pruning
const TreeNode &current_tree_node = m_search_tree[current_query_node.node_id];
if (current_tree_node.child_is_on_disk)
{
LeafNode current_leaf_node;
LoadLeafFromDisk(current_tree_node.children[0], current_leaf_node);
for (uint32_t i = 0; i < current_leaf_node.object_count; ++i)
{
DataT &current_edge = current_leaf_node.objects[i];
const EdgeDataT &current_edge = current_leaf_node.objects[i];
if (ignore_tiny_components && current_edge.is_in_tiny_cc)
{
continue;
}
float current_ratio = 0.;
FixedPointCoordinate nearest;
const float current_perpendicular_distance =
FixedPointCoordinate::ComputePerpendicularDistance(
m_coordinate_list->at(current_edge.u),
@@ -650,99 +894,107 @@ class StaticRTree
!EpsilonCompare(current_perpendicular_distance, min_dist))
{ // found a new minimum
min_dist = current_perpendicular_distance;
// TODO: use assignment c'tor in PhantomNode
result_phantom_node.forward_node_id =
current_edge.forward_edge_based_node_id;
result_phantom_node.reverse_node_id =
current_edge.reverse_edge_based_node_id;
result_phantom_node.name_id = current_edge.name_id;
result_phantom_node.forward_weight = current_edge.forward_weight;
result_phantom_node.reverse_weight = current_edge.reverse_weight;
result_phantom_node.forward_offset = current_edge.forward_offset;
result_phantom_node.reverse_offset = current_edge.reverse_offset;
result_phantom_node.packed_geometry_id =
current_edge.packed_geometry_id;
result_phantom_node.fwd_segment_position =
current_edge.fwd_segment_position;
result_phantom_node.location = nearest;
current_start_coordinate.lat =
m_coordinate_list->at(current_edge.u).lat;
current_start_coordinate.lon =
m_coordinate_list->at(current_edge.u).lon;
current_end_coordinate.lat = m_coordinate_list->at(current_edge.v).lat;
current_end_coordinate.lon = m_coordinate_list->at(current_edge.v).lon;
result_phantom_node = {current_edge.forward_edge_based_node_id,
current_edge.reverse_edge_based_node_id,
current_edge.name_id,
current_edge.forward_weight,
current_edge.reverse_weight,
current_edge.forward_offset,
current_edge.reverse_offset,
current_edge.packed_geometry_id,
nearest,
current_edge.fwd_segment_position};
nearest_edge = current_edge;
found_a_nearest_edge = true;
}
}
}
else
{
// traverse children, prune if global mindist is smaller than local one
for (uint32_t i = 0; i < current_tree_node.child_count; ++i)
{
const int32_t child_id = current_tree_node.children[i];
TreeNode &child_tree_node = m_search_tree[child_id];
RectangleT &child_rectangle = child_tree_node.minimum_bounding_rectangle;
const float current_min_dist =
child_rectangle.GetMinDist(input_coordinate);
const float current_min_max_dist =
child_rectangle.GetMinMaxDist(input_coordinate);
if (current_min_max_dist < min_max_dist)
{
min_max_dist = current_min_max_dist;
}
if (current_min_dist > min_max_dist)
{
continue;
}
if (current_min_dist > min_dist)
{ // upward pruning
continue;
}
traversal_queue.emplace(child_id, current_min_dist);
}
min_max_dist = ExploreTreeNode(current_tree_node,
input_coordinate,
min_dist,
min_max_dist,
traversal_queue);
}
}
}
// Hack to fix rounding errors and wandering via nodes.
if (1 == std::abs(input_coordinate.lon - result_phantom_node.location.lon))
if (result_phantom_node.location.isValid())
{
result_phantom_node.location.lon = input_coordinate.lon;
// Hack to fix rounding errors and wandering via nodes.
FixUpRoundingIssue(input_coordinate, result_phantom_node);
// set forward and reverse weights on the phantom node
SetForwardAndReverseWeightsOnPhantomNode(nearest_edge, result_phantom_node);
}
if (1 == std::abs(input_coordinate.lat - result_phantom_node.location.lat))
{
result_phantom_node.location.lat = input_coordinate.lat;
}
float ratio = 0.f;
if (found_a_nearest_edge)
{
const float distance_1 = FixedPointCoordinate::ApproximateEuclideanDistance(
current_start_coordinate, result_phantom_node.location);
const float distance_2 = FixedPointCoordinate::ApproximateEuclideanDistance(
current_start_coordinate, current_end_coordinate);
ratio = distance_1 / distance_2;
ratio = std::min(1.f, ratio);
if (SPECIAL_NODEID != result_phantom_node.forward_node_id)
{
result_phantom_node.forward_weight *= ratio;
}
if (SPECIAL_NODEID != result_phantom_node.reverse_node_id)
{
result_phantom_node.reverse_weight *= (1. - ratio);
}
}
return found_a_nearest_edge;
return result_phantom_node.location.isValid();
}
private:
inline void SetForwardAndReverseWeightsOnPhantomNode(const EdgeDataT & nearest_edge,
PhantomNode &result_phantom_node) const
{
const float distance_1 = FixedPointCoordinate::ApproximateEuclideanDistance(
m_coordinate_list->at(nearest_edge.u), result_phantom_node.location);
const float distance_2 = FixedPointCoordinate::ApproximateEuclideanDistance(
m_coordinate_list->at(nearest_edge.u), m_coordinate_list->at(nearest_edge.v));
const float ratio = std::min(1.f, distance_1 / distance_2);
if (SPECIAL_NODEID != result_phantom_node.forward_node_id)
{
result_phantom_node.forward_weight *= ratio;
}
if (SPECIAL_NODEID != result_phantom_node.reverse_node_id)
{
result_phantom_node.reverse_weight *= (1.f - ratio);
}
}
// fixup locations if too close to inputs
inline void FixUpRoundingIssue(const FixedPointCoordinate &input_coordinate,
PhantomNode &result_phantom_node) const
{
if (1 == std::abs(input_coordinate.lon - result_phantom_node.location.lon))
{
result_phantom_node.location.lon = input_coordinate.lon;
}
if (1 == std::abs(input_coordinate.lat - result_phantom_node.location.lat))
{
result_phantom_node.location.lat = input_coordinate.lat;
}
}
template <class QueueT>
inline float ExploreTreeNode(const TreeNode &parent,
const FixedPointCoordinate &input_coordinate,
const float min_dist,
const float min_max_dist,
QueueT &traversal_queue)
{
float new_min_max_dist = min_max_dist;
// traverse children, prune if global mindist is smaller than local one
for (uint32_t i = 0; i < parent.child_count; ++i)
{
const int32_t child_id = parent.children[i];
const TreeNode &child_tree_node = m_search_tree[child_id];
const RectangleT &child_rectangle = child_tree_node.minimum_bounding_rectangle;
const float lower_bound_to_element = child_rectangle.GetMinDist(input_coordinate);
const float upper_bound_to_element = child_rectangle.GetMinMaxDist(input_coordinate);
new_min_max_dist = std::min(new_min_max_dist, upper_bound_to_element);
if (lower_bound_to_element > new_min_max_dist)
{
continue;
}
if (lower_bound_to_element > min_dist)
{
continue;
}
traversal_queue.emplace(lower_bound_to_element, child_id);
}
return new_min_max_dist;
}
inline void LoadLeafFromDisk(const uint32_t leaf_id, LeafNode &result_node)
{
if (!thread_local_rtree_stream.get() || !thread_local_rtree_stream->is_open())
@@ -755,9 +1007,12 @@ class StaticRTree
thread_local_rtree_stream->clear(std::ios::goodbit);
SimpleLogger().Write(logDEBUG) << "Resetting stale filestream";
}
uint64_t seek_pos = sizeof(uint64_t) + leaf_id * sizeof(LeafNode);
const uint64_t seek_pos = sizeof(uint64_t) + leaf_id * sizeof(LeafNode);
thread_local_rtree_stream->seekg(seek_pos);
BOOST_ASSERT_MSG(thread_local_rtree_stream->good(),
"Seeking to position in leaf file failed.");
thread_local_rtree_stream->read((char *)&result_node, sizeof(LeafNode));
BOOST_ASSERT_MSG(thread_local_rtree_stream->good(), "Reading from leaf file failed.");
}
inline bool EdgesAreEquivalent(const FixedPointCoordinate &a,
@@ -768,8 +1023,7 @@ class StaticRTree
return (a == b && c == d) || (a == c && b == d) || (a == d && b == c);
}
template<typename FloatT>
inline bool EpsilonCompare(const FloatT d1, const FloatT d2) const
template <typename FloatT> inline bool EpsilonCompare(const FloatT d1, const FloatT d2) const
{
return (std::abs(d1 - d2) < std::numeric_limits<FloatT>::epsilon());
}
@@ -777,5 +1031,6 @@ class StaticRTree
//[1] "On Packing R-Trees"; I. Kamel, C. Faloutsos; 1993; DOI: 10.1145/170088.170403
//[2] "Nearest Neighbor Queries", N. Roussopulos et al; 1995; DOI: 10.1145/223784.223794
//[3] "Distance Browsing in Spatial Databases"; G. Hjaltason, H. Samet; 1999; ACM Trans. DB Sys
// Vol.24 No.2, pp.265-318
#endif // STATICRTREE_H
+1 -3
View File
@@ -54,9 +54,7 @@ template <class DataFacadeT> class BaseDescriptor
BaseDescriptor() {}
// Maybe someone can explain the pure virtual destructor thing to me (dennis)
virtual ~BaseDescriptor() {}
virtual void Run(const RawRouteData &raw_route,
const PhantomNodes &phantom_nodes,
http::Reply &reply) = 0;
virtual void Run(const RawRouteData &raw_route, http::Reply &reply) = 0;
virtual void SetConfig(const DescriptorConfig &config) = 0;
};
+23 -10
View File
@@ -27,19 +27,37 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "DescriptionFactory.h"
DescriptionFactory::DescriptionFactory() : entireLength(0) {}
#include <osrm/Coordinate.h>
void DescriptionFactory::SetStartSegment(const PhantomNode &source)
#include "../typedefs.h"
#include "../Algorithms/PolylineCompressor.h"
#include "../DataStructures/PhantomNodes.h"
#include "../DataStructures/RawRouteData.h"
#include "../DataStructures/SegmentInformation.h"
#include "../DataStructures/TurnInstructions.h"
DescriptionFactory::DescriptionFactory() : entireLength(0) { via_indices.push_back(0); }
std::vector<unsigned> const &DescriptionFactory::GetViaIndices() const { return via_indices; }
void DescriptionFactory::SetStartSegment(const PhantomNode &source, const bool traversed_in_reverse)
{
start_phantom = source;
AppendSegment(source.location, PathData(0, source.name_id, TurnInstruction::HeadOn, source.forward_weight));
const EdgeWeight segment_duration =
(traversed_in_reverse ? source.reverse_weight : source.forward_weight);
AppendSegment(source.location,
PathData(0, source.name_id, TurnInstruction::HeadOn, segment_duration));
BOOST_ASSERT(path_description.back().duration == segment_duration);
}
void DescriptionFactory::SetEndSegment(const PhantomNode &target)
void DescriptionFactory::SetEndSegment(const PhantomNode &target, const bool traversed_in_reverse)
{
target_phantom = target;
const EdgeWeight segment_duration =
(traversed_in_reverse ? target.reverse_weight : target.forward_weight);
path_description.emplace_back(
target.location, target.name_id, 0, target.reverse_weight, TurnInstruction::NoTurn, true);
target.location, target.name_id, segment_duration, 0.f, TurnInstruction::NoTurn, true, true);
BOOST_ASSERT(path_description.back().duration == segment_duration);
}
void DescriptionFactory::AppendSegment(const FixedPointCoordinate &coordinate,
@@ -67,11 +85,6 @@ JSON::Value DescriptionFactory::AppendEncodedPolylineString(const bool return_en
return polyline_compressor.printUnencodedString(path_description);
}
JSON::Value DescriptionFactory::AppendUnencodedPolylineString() const
{
return polyline_compressor.printUnencodedString(path_description);
}
void DescriptionFactory::BuildRouteSummary(const double distance, const unsigned time)
{
summary.source_name_id = start_phantom.name_id;
+19 -9
View File
@@ -31,10 +31,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../Algorithms/DouglasPeucker.h"
#include "../Algorithms/PolylineCompressor.h"
#include "../DataStructures/PhantomNodes.h"
#include "../DataStructures/RawRouteData.h"
#include "../DataStructures/SegmentInformation.h"
#include "../DataStructures/TurnInstructions.h"
#include "../Util/SimpleLogger.h"
#include "../typedefs.h"
#include <osrm/Coordinate.h>
@@ -42,6 +40,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <limits>
#include <vector>
struct PathData;
/* This class is fed with all way segments in consecutive order
* and produces the description plus the encoded polyline */
@@ -54,6 +53,8 @@ class DescriptionFactory
double DegreeToRadian(const double degree) const;
double RadianToDegree(const double degree) const;
std::vector<unsigned> via_indices;
public:
struct RouteSummary
{
@@ -66,8 +67,8 @@ class DescriptionFactory
void BuildDurationAndLengthStrings(const double raw_distance, const unsigned raw_duration)
{
// compute distance/duration for route summary
distance = round(raw_distance);
duration = round(raw_duration / 10.);
distance = static_cast<unsigned>(round(raw_distance));
duration = static_cast<unsigned>(round(raw_duration / 10.));
}
} summary;
@@ -76,12 +77,12 @@ class DescriptionFactory
// I know, declaring this public is considered bad. I'm lazy
std::vector<SegmentInformation> path_description;
DescriptionFactory();
JSON::Value AppendUnencodedPolylineString() const;
void AppendSegment(const FixedPointCoordinate &coordinate, const PathData &data);
void BuildRouteSummary(const double distance, const unsigned time);
void SetStartSegment(const PhantomNode &start_phantom);
void SetEndSegment(const PhantomNode &start_phantom);
void SetStartSegment(const PhantomNode &start_phantom, const bool traversed_in_reverse);
void SetEndSegment(const PhantomNode &start_phantom, const bool traversed_in_reverse);
JSON::Value AppendEncodedPolylineString(const bool return_encoded);
std::vector<unsigned> const & GetViaIndices() const;
template <class DataFacadeT> void Run(const DataFacadeT *facade, const unsigned zoomLevel)
{
@@ -143,7 +144,7 @@ class DescriptionFactory
// string0 = string1;
// }
double segment_length = 0.;
float segment_length = 0.;
unsigned segment_duration = 0;
unsigned segment_start_index = 0;
@@ -190,14 +191,23 @@ class DescriptionFactory
polyline_generalizer.Run(path_description, zoomLevel);
// fix what needs to be fixed else
unsigned necessary_pieces = 0; // a running index that counts the necessary pieces
for (unsigned i = 0; i < path_description.size() - 1 && path_description.size() >= 2; ++i)
{
if (path_description[i].necessary)
{
++necessary_pieces;
if (path_description[i].is_via_location)
{ //mark the end of a leg
via_indices.push_back(necessary_pieces);
}
const double angle = path_description[i+1].location.GetBearing(path_description[i].location);
path_description[i].bearing = angle * 10;
path_description[i].bearing = static_cast<unsigned>(angle * 10);
}
}
via_indices.push_back(necessary_pieces+1);
BOOST_ASSERT(via_indices.size() >= 2);
// BOOST_ASSERT(0 != necessary_pieces || path_description.empty());
return;
}
};
+3 -5
View File
@@ -62,9 +62,7 @@ template <class DataFacadeT> class GPXDescriptor : public BaseDescriptor<DataFac
void SetConfig(const DescriptorConfig &c) { config = c; }
// TODO: reorder parameters
void Run(const RawRouteData &raw_route,
const PhantomNodes &phantom_node_list,
http::Reply &reply)
void Run(const RawRouteData &raw_route, http::Reply &reply)
{
std::string header("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<gpx creator=\"OSRM Routing Engine\" version=\"1.1\" "
@@ -81,7 +79,7 @@ template <class DataFacadeT> class GPXDescriptor : public BaseDescriptor<DataFac
(!raw_route.unpacked_path_segments.front().empty());
if (found_route)
{
AddRoutePoint(phantom_node_list.source_phantom.location, reply.content);
AddRoutePoint(raw_route.segment_end_coordinates.front().source_phantom.location, reply.content);
for (const std::vector<PathData> &path_data_vector : raw_route.unpacked_path_segments)
{
@@ -92,7 +90,7 @@ template <class DataFacadeT> class GPXDescriptor : public BaseDescriptor<DataFac
AddRoutePoint(current_coordinate, reply.content);
}
}
AddRoutePoint(phantom_node_list.target_phantom.location, reply.content);
AddRoutePoint(raw_route.segment_end_coordinates.back().target_phantom.location, reply.content);
}
std::string footer("</rte></gpx>");
+79 -50
View File
@@ -51,35 +51,31 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
unsigned entered_restricted_area_count;
struct RoundAbout
{
RoundAbout() : start_index(INT_MAX), name_id(INT_MAX), leave_at_exit(INT_MAX) {}
RoundAbout() : start_index(INT_MAX), name_id(INVALID_NAMEID), leave_at_exit(INT_MAX) {}
int start_index;
int name_id;
unsigned name_id;
int leave_at_exit;
} round_about;
struct Segment
{
Segment() : name_id(-1), length(-1), position(-1) {}
Segment(int n, int l, int p) : name_id(n), length(l), position(p) {}
int name_id;
Segment() : name_id(INVALID_NAMEID), length(-1), position(0) {}
Segment(unsigned n, int l, unsigned p) : name_id(n), length(l), position(p) {}
unsigned name_id;
int length;
int position;
unsigned position;
};
std::vector<Segment> shortest_path_segments, alternative_path_segments;
std::vector<unsigned> shortest_leg_end_indices, alternative_leg_end_indices;
ExtractRouteNames<DataFacadeT, Segment> GenerateRouteNames;
public:
JSONDescriptor(DataFacadeT *facade) : facade(facade), entered_restricted_area_count(0)
{
shortest_leg_end_indices.emplace_back(0);
alternative_leg_end_indices.emplace_back(0);
}
JSONDescriptor(DataFacadeT *facade) : facade(facade), entered_restricted_area_count(0) {}
void SetConfig(const DescriptorConfig &c) { config = c; }
unsigned DescribeLeg(const std::vector<PathData> route_leg, const PhantomNodes &leg_phantoms)
unsigned DescribeLeg(const std::vector<PathData> route_leg,
const PhantomNodes &leg_phantoms,
const bool target_traversed_in_reverse)
{
unsigned added_element_count = 0;
// Get all the coordinates for the computed route
@@ -90,17 +86,15 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
description_factory.AppendSegment(current_coordinate, path_data);
++added_element_count;
}
description_factory.SetEndSegment(leg_phantoms.target_phantom, target_traversed_in_reverse);
++added_element_count;
BOOST_ASSERT((route_leg.size() + 1) == added_element_count);
return added_element_count;
}
void Run(const RawRouteData &raw_route,
const PhantomNodes &phantom_nodes,
http::Reply &reply)
void Run(const RawRouteData &raw_route, http::Reply &reply)
{
JSON::Object json_result;
if (INVALID_EDGE_WEIGHT == raw_route.shortest_path_length)
{
// We do not need to do much, if there is no route ;-)
@@ -111,30 +105,35 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
}
// check if first segment is non-zero
std::string road_name =
facade->GetEscapedNameForNameID(phantom_nodes.source_phantom.name_id);
std::string road_name = facade->GetEscapedNameForNameID(
raw_route.segment_end_coordinates.front().source_phantom.name_id);
BOOST_ASSERT(raw_route.unpacked_path_segments.size() ==
raw_route.segment_end_coordinates.size());
description_factory.SetStartSegment(phantom_nodes.source_phantom);
description_factory.SetStartSegment(
raw_route.segment_end_coordinates.front().source_phantom,
raw_route.source_traversed_in_reverse.front());
json_result.values["status"] = 0;
json_result.values["status_message"] = "Found route between points";
// for each unpacked segment add the leg to the description
for (unsigned i = 0; i < raw_route.unpacked_path_segments.size(); ++i)
{
const int added_segments = DescribeLeg(raw_route.unpacked_path_segments[i],
raw_route.segment_end_coordinates[i]);
#ifndef NDEBUG
const int added_segments =
#endif
DescribeLeg(raw_route.unpacked_path_segments[i],
raw_route.segment_end_coordinates[i],
raw_route.target_traversed_in_reverse[i]);
BOOST_ASSERT(0 < added_segments);
shortest_leg_end_indices.emplace_back(added_segments + shortest_leg_end_indices.back());
}
description_factory.SetEndSegment(phantom_nodes.target_phantom);
description_factory.Run(facade, config.zoom_level);
if (config.geometry)
{
JSON::Value route_geometry = description_factory.AppendEncodedPolylineString(config.encode_geometry);
JSON::Value route_geometry =
description_factory.AppendEncodedPolylineString(config.encode_geometry);
json_result.values["route_geometry"] = route_geometry;
}
if (config.instructions)
@@ -151,36 +150,51 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
JSON::Object json_route_summary;
json_route_summary.values["total_distance"] = description_factory.summary.distance;
json_route_summary.values["total_time"] = description_factory.summary.duration;
json_route_summary.values["start_point"] = facade->GetEscapedNameForNameID(description_factory.summary.source_name_id);
json_route_summary.values["end_point"] = facade->GetEscapedNameForNameID(description_factory.summary.target_name_id);
json_route_summary.values["start_point"] =
facade->GetEscapedNameForNameID(description_factory.summary.source_name_id);
json_route_summary.values["end_point"] =
facade->GetEscapedNameForNameID(description_factory.summary.target_name_id);
json_result.values["route_summary"] = json_route_summary;
BOOST_ASSERT(!raw_route.segment_end_coordinates.empty());
JSON::Array json_via_points_array;
JSON::Array json_first_coordinate;
json_first_coordinate.values.push_back(raw_route.segment_end_coordinates.front().source_phantom.location.lat/COORDINATE_PRECISION);
json_first_coordinate.values.push_back(raw_route.segment_end_coordinates.front().source_phantom.location.lon/COORDINATE_PRECISION);
json_first_coordinate.values.push_back(
raw_route.segment_end_coordinates.front().source_phantom.location.lat /
COORDINATE_PRECISION);
json_first_coordinate.values.push_back(
raw_route.segment_end_coordinates.front().source_phantom.location.lon /
COORDINATE_PRECISION);
json_via_points_array.values.push_back(json_first_coordinate);
for (const PhantomNodes &nodes : raw_route.segment_end_coordinates)
{
std::string tmp;
JSON::Array json_coordinate;
json_coordinate.values.push_back(nodes.target_phantom.location.lat/COORDINATE_PRECISION);
json_coordinate.values.push_back(nodes.target_phantom.location.lon/COORDINATE_PRECISION);
json_coordinate.values.push_back(nodes.target_phantom.location.lat /
COORDINATE_PRECISION);
json_coordinate.values.push_back(nodes.target_phantom.location.lon /
COORDINATE_PRECISION);
json_via_points_array.values.push_back(json_coordinate);
}
json_result.values["via_points"] = json_via_points_array;
JSON::Array json_via_indices_array;
json_via_indices_array.values.insert(json_via_indices_array.values.end(), shortest_leg_end_indices.begin(), shortest_leg_end_indices.end());
std::vector<unsigned> const &shortest_leg_end_indices = description_factory.GetViaIndices();
json_via_indices_array.values.insert(json_via_indices_array.values.end(),
shortest_leg_end_indices.begin(),
shortest_leg_end_indices.end());
json_result.values["via_indices"] = json_via_indices_array;
// only one alternative route is computed at this time, so this is hardcoded
if (INVALID_EDGE_WEIGHT != raw_route.alternative_path_length)
{
json_result.values["found_alternative"] = JSON::True();
alternate_description_factory.SetStartSegment(phantom_nodes.source_phantom);
BOOST_ASSERT(!raw_route.alt_source_traversed_in_reverse.empty());
alternate_description_factory.SetStartSegment(
raw_route.segment_end_coordinates.front().source_phantom,
raw_route.alt_source_traversed_in_reverse.front());
// Get all the coordinates for the computed route
for (const PathData &path_data : raw_route.unpacked_alternative)
{
@@ -191,7 +205,9 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
if (config.geometry)
{
JSON::Value alternate_geometry_string = alternate_description_factory.AppendEncodedPolylineString(config.encode_geometry);
JSON::Value alternate_geometry_string =
alternate_description_factory.AppendEncodedPolylineString(
config.encode_geometry);
JSON::Array json_alternate_geometries_array;
json_alternate_geometries_array.values.push_back(alternate_geometry_string);
json_result.values["alternative_geometries"] = json_alternate_geometries_array;
@@ -213,23 +229,33 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
JSON::Object json_alternate_route_summary;
JSON::Array json_alternate_route_summary_array;
json_alternate_route_summary.values["total_distance"] = alternate_description_factory.summary.distance;
json_alternate_route_summary.values["total_time"] = alternate_description_factory.summary.duration;
json_alternate_route_summary.values["start_point"] = facade->GetEscapedNameForNameID(alternate_description_factory.summary.source_name_id);
json_alternate_route_summary.values["end_point"] = facade->GetEscapedNameForNameID(alternate_description_factory.summary.target_name_id);
json_alternate_route_summary.values["total_distance"] =
alternate_description_factory.summary.distance;
json_alternate_route_summary.values["total_time"] =
alternate_description_factory.summary.duration;
json_alternate_route_summary.values["start_point"] = facade->GetEscapedNameForNameID(
alternate_description_factory.summary.source_name_id);
json_alternate_route_summary.values["end_point"] = facade->GetEscapedNameForNameID(
alternate_description_factory.summary.target_name_id);
json_alternate_route_summary_array.values.push_back(json_alternate_route_summary);
json_result.values["alternative_summaries"] = json_alternate_route_summary_array;
std::vector<unsigned> const &alternate_leg_end_indices =
alternate_description_factory.GetViaIndices();
JSON::Array json_altenative_indices_array;
json_altenative_indices_array.values.push_back(0);
json_altenative_indices_array.values.push_back(alternate_description_factory.path_description.size());
json_altenative_indices_array.values.insert(json_altenative_indices_array.values.end(),
alternate_leg_end_indices.begin(),
alternate_leg_end_indices.end());
json_result.values["alternative_indices"] = json_altenative_indices_array;
} else {
}
else
{
json_result.values["found_alternative"] = JSON::False();
}
// Get Names for both routes
RouteNames route_names = GenerateRouteNames(shortest_path_segments, alternative_path_segments, facade);
RouteNames route_names =
GenerateRouteNames(shortest_path_segments, alternative_path_segments, facade);
JSON::Array json_route_names;
json_route_names.values.push_back(route_names.shortest_path_name_1);
json_route_names.values.push_back(route_names.shortest_path_name_2);
@@ -268,7 +294,7 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
// TODO: reorder parameters
inline void BuildTextualDescription(DescriptionFactory &description_factory,
JSON::Array & json_instruction_array,
JSON::Array &json_instruction_array,
const int route_length,
std::vector<Segment> &route_segments_list)
{
@@ -297,7 +323,8 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
std::string current_turn_instruction;
if (TurnInstruction::LeaveRoundAbout == current_instruction)
{
temp_instruction = IntToString(as_integer(TurnInstruction::EnterRoundAbout));
temp_instruction =
IntToString(as_integer(TurnInstruction::EnterRoundAbout));
current_turn_instruction += temp_instruction;
current_turn_instruction += "-";
temp_instruction = IntToString(round_about.leave_at_exit + 1);
@@ -311,14 +338,16 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
}
json_instruction_row.values.push_back(current_turn_instruction);
json_instruction_row.values.push_back(facade->GetEscapedNameForNameID(segment.name_id));
json_instruction_row.values.push_back(
facade->GetEscapedNameForNameID(segment.name_id));
json_instruction_row.values.push_back(std::round(segment.length));
json_instruction_row.values.push_back(necessary_segments_running_index);
json_instruction_row.values.push_back(round(segment.duration / 10));
json_instruction_row.values.push_back(IntToString(segment.length)+"m");
int bearing_value = round(segment.bearing / 10.);
json_instruction_row.values.push_back(
UintToString(static_cast<unsigned>(segment.length)) + "m");
const double bearing_value = (segment.bearing / 10.) ;
json_instruction_row.values.push_back(Azimuth::Get(bearing_value));
json_instruction_row.values.push_back(bearing_value);
json_instruction_row.values.push_back(static_cast<unsigned>(round(bearing_value)));
route_segments_list.emplace_back(
segment.name_id, segment.length, route_segments_list.size());
@@ -335,7 +364,7 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
}
}
//TODO: check if this in an invariant
// TODO: check if this in an invariant
if (INVALID_EDGE_WEIGHT != route_length)
{
JSON::Array json_last_instruction_row;
+1 -1
View File
@@ -42,7 +42,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
BaseParser::BaseParser(ExtractorCallbacks *extractor_callbacks,
ScriptingEnvironment &scripting_environment)
: extractor_callbacks(extractor_callbacks),
lua_state(scripting_environment.getLuaStateForThreadID(0)),
lua_state(scripting_environment.getLuaState()),
scripting_environment(scripting_environment), use_turn_restrictions(true)
{
ReadUseRestrictionsSetting();
+67 -90
View File
@@ -29,6 +29,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "ExtractionWay.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../Util/TimingUtil.h"
#include "../DataStructures/RangeTable.h"
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>
@@ -63,49 +65,46 @@ void ExtractionContainers::PrepareData(const std::string &output_file_name,
{
unsigned number_of_used_nodes = 0;
unsigned number_of_used_edges = 0;
std::chrono::time_point<std::chrono::steady_clock> time1 = std::chrono::steady_clock::now();
std::cout << "[extractor] Sorting used nodes ... " << std::flush;
TIMER_START(sorting_used_nodes);
stxxl::sort(used_node_id_list.begin(), used_node_id_list.end(), Cmp(), stxxl_memory);
std::chrono::time_point<std::chrono::steady_clock> time2 = std::chrono::steady_clock::now();
std::chrono::duration<double> elapsed_seconds = time2 - time1;
std::cout << "ok, after " << elapsed_seconds.count() << "s" << std::endl;
TIMER_STOP(sorting_used_nodes);
std::cout << "ok, after " << TIMER_SEC(sorting_used_nodes) << "s" << std::endl;
time1 = std::chrono::steady_clock::now();
std::cout << "[extractor] Erasing duplicate nodes ... " << std::flush;
TIMER_START(erasing_dups);
auto new_end = std::unique(used_node_id_list.begin(), used_node_id_list.end());
used_node_id_list.resize(new_end - used_node_id_list.begin());
time2 = std::chrono::steady_clock::now();
elapsed_seconds = time2 - time1;
std::cout << "ok, after " << elapsed_seconds.count() << "s" << std::endl;
TIMER_STOP(erasing_dups);
std::cout << "ok, after " << TIMER_SEC(erasing_dups) << "s" << std::endl;
time1 = std::chrono::steady_clock::now();
std::cout << "[extractor] Sorting all nodes ... " << std::flush;
TIMER_START(sorting_nodes);
stxxl::sort(all_nodes_list.begin(), all_nodes_list.end(), CmpNodeByID(), stxxl_memory);
time2 = std::chrono::steady_clock::now();
elapsed_seconds = time2 - time1;
std::cout << "ok, after " << elapsed_seconds.count() << "s" << std::endl;
TIMER_STOP(sorting_nodes);
std::cout << "ok, after " << TIMER_SEC(sorting_nodes) << "s" << std::endl;
time1 = std::chrono::steady_clock::now();
std::cout << "[extractor] Sorting used ways ... " << std::flush;
TIMER_START(sort_ways);
stxxl::sort(
way_start_end_id_list.begin(), way_start_end_id_list.end(), CmpWayByID(), stxxl_memory);
time2 = std::chrono::steady_clock::now();
elapsed_seconds = time2 - time1;
std::cout << "ok, after " << elapsed_seconds.count() << "s" << std::endl;
TIMER_STOP(sort_ways);
std::cout << "ok, after " << TIMER_SEC(sort_ways) << "s" << std::endl;
std::cout << "[extractor] Sorting restrictions. by from... " << std::flush;
TIMER_START(sort_restrictions);
stxxl::sort(restrictions_list.begin(),
restrictions_list.end(),
CmpRestrictionContainerByFrom(),
stxxl_memory);
time2 = std::chrono::steady_clock::now();
elapsed_seconds = time2 - time1;
std::cout << "ok, after " << elapsed_seconds.count() << "s" << std::endl;
TIMER_STOP(sort_restrictions);
std::cout << "ok, after " << TIMER_SEC(sort_restrictions) << "s" << std::endl;
std::cout << "[extractor] Fixing restriction starts ... " << std::flush;
TIMER_START(fix_restriction_starts);
auto restrictions_iterator = restrictions_list.begin();
auto way_start_and_end_iterator = way_start_end_id_list.begin();
@@ -149,24 +148,21 @@ void ExtractionContainers::PrepareData(const std::string &output_file_name,
++restrictions_iterator;
}
time2 = std::chrono::steady_clock::now();
elapsed_seconds = time2 - time1;
std::cout << "ok, after " << elapsed_seconds.count() << "s" << std::endl;
time1 = std::chrono::steady_clock::now();
TIMER_STOP(fix_restriction_starts);
std::cout << "ok, after " << TIMER_SEC(fix_restriction_starts) << "s" << std::endl;
std::cout << "[extractor] Sorting restrictions. by to ... " << std::flush;
TIMER_START(sort_restrictions_to);
stxxl::sort(restrictions_list.begin(),
restrictions_list.end(),
CmpRestrictionContainerByTo(),
stxxl_memory);
time2 = std::chrono::steady_clock::now();
elapsed_seconds = time2 - time1;
std::cout << "ok, after " << elapsed_seconds.count() << "s" << std::endl;
TIMER_STOP(sort_restrictions_to);
std::cout << "ok, after " << TIMER_SEC(sort_restrictions_to) << "s" << std::endl;
time1 = std::chrono::steady_clock::now();
unsigned number_of_useable_restrictions = 0;
std::cout << "[extractor] Fixing restriction ends ... " << std::flush;
TIMER_START(fix_restriction_ends);
restrictions_iterator = restrictions_list.begin();
way_start_and_end_iterator = way_start_end_id_list.begin();
while (way_start_and_end_iterator != way_start_end_id_list.end() &&
@@ -207,19 +203,16 @@ void ExtractionContainers::PrepareData(const std::string &output_file_name,
}
++restrictions_iterator;
}
time2 = std::chrono::steady_clock::now();
elapsed_seconds = time2 - time1;
std::cout << "ok, after " << elapsed_seconds.count() << "s" << std::endl;
TIMER_STOP(fix_restriction_ends);
std::cout << "ok, after " << TIMER_SEC(fix_restriction_ends) << "s" << std::endl;
SimpleLogger().Write() << "usable restrictions: " << number_of_useable_restrictions;
// serialize restrictions
std::ofstream restrictions_out_stream;
restrictions_out_stream.open(restrictions_file_name.c_str(), std::ios::binary);
restrictions_out_stream.write((char *)&uuid, sizeof(UUID));
restrictions_out_stream.write((char *)&fingerprint, sizeof(FingerPrint));
restrictions_out_stream.write((char *)&number_of_useable_restrictions, sizeof(unsigned));
// for (restrictions_iterator = restrictions_list.begin();
// restrictions_iterator != restrictions_list.end();
// ++restrictions_iterator)
for(const auto & restriction_container : restrictions_list)
{
if (std::numeric_limits<unsigned>::max() != restriction_container.restriction.fromNode &&
@@ -233,27 +226,26 @@ void ExtractionContainers::PrepareData(const std::string &output_file_name,
std::ofstream file_out_stream;
file_out_stream.open(output_file_name.c_str(), std::ios::binary);
file_out_stream.write((char *)&uuid, sizeof(UUID));
file_out_stream.write((char *)&fingerprint, sizeof(FingerPrint));
file_out_stream.write((char *)&number_of_used_nodes, sizeof(unsigned));
time1 = std::chrono::steady_clock::now();
std::cout << "[extractor] Confirming/Writing used nodes ... " << std::flush;
TIMER_START(write_nodes);
// identify all used nodes by a merging step of two sorted lists
auto node_iterator = all_nodes_list.begin();
auto node_id_iterator = used_node_id_list.begin();
while (node_id_iterator != used_node_id_list.end() && node_iterator != all_nodes_list.end())
{
if (*node_id_iterator < node_iterator->id)
if (*node_id_iterator < node_iterator->node_id)
{
++node_id_iterator;
continue;
}
if (*node_id_iterator > node_iterator->id)
if (*node_id_iterator > node_iterator->node_id)
{
++node_iterator;
continue;
}
BOOST_ASSERT(*node_id_iterator == node_iterator->id);
BOOST_ASSERT(*node_id_iterator == node_iterator->node_id);
file_out_stream.write((char *)&(*node_iterator), sizeof(ExternalMemoryNode));
@@ -262,82 +254,78 @@ void ExtractionContainers::PrepareData(const std::string &output_file_name,
++node_iterator;
}
time2 = std::chrono::steady_clock::now();
elapsed_seconds = time2 - time1;
std::cout << "ok, after " << elapsed_seconds.count() << "s" << std::endl;
TIMER_STOP(write_nodes);
std::cout << "ok, after " << TIMER_SEC(write_nodes) << "s" << std::endl;
std::cout << "[extractor] setting number of nodes ... " << std::flush;
std::ios::pos_type previous_file_position = file_out_stream.tellp();
file_out_stream.seekp(std::ios::beg + sizeof(UUID));
file_out_stream.seekp(std::ios::beg + sizeof(FingerPrint));
file_out_stream.write((char *)&number_of_used_nodes, sizeof(unsigned));
file_out_stream.seekp(previous_file_position);
std::cout << "ok" << std::endl;
time1 = std::chrono::steady_clock::now();
// Sort edges by start.
std::cout << "[extractor] Sorting edges by start ... " << std::flush;
TIMER_START(sort_edges_by_start);
stxxl::sort(all_edges_list.begin(), all_edges_list.end(), CmpEdgeByStartID(), stxxl_memory);
time2 = std::chrono::steady_clock::now();
elapsed_seconds = time2 - time1;
std::cout << "ok, after " << elapsed_seconds.count() << "s" << std::endl;
TIMER_STOP(sort_edges_by_start);
std::cout << "ok, after " << TIMER_SEC(sort_edges_by_start) << "s" << std::endl;
time1 = std::chrono::steady_clock::now();
std::cout << "[extractor] Setting start coords ... " << std::flush;
TIMER_START(set_start_coords);
file_out_stream.write((char *)&number_of_used_edges, sizeof(unsigned));
// Traverse list of edges and nodes in parallel and set start coord
node_iterator = all_nodes_list.begin();
auto edge_iterator = all_edges_list.begin();
while (edge_iterator != all_edges_list.end() && node_iterator != all_nodes_list.end())
{
if (edge_iterator->start < node_iterator->id)
if (edge_iterator->start < node_iterator->node_id)
{
++edge_iterator;
continue;
}
if (edge_iterator->start > node_iterator->id)
if (edge_iterator->start > node_iterator->node_id)
{
node_iterator++;
continue;
}
BOOST_ASSERT(edge_iterator->start == node_iterator->id);
BOOST_ASSERT(edge_iterator->start == node_iterator->node_id);
edge_iterator->source_coordinate.lat = node_iterator->lat;
edge_iterator->source_coordinate.lon = node_iterator->lon;
++edge_iterator;
}
time2 = std::chrono::steady_clock::now();
elapsed_seconds = time2 - time1;
std::cout << "ok, after " << elapsed_seconds.count() << "s" << std::endl;
TIMER_STOP(set_start_coords);
std::cout << "ok, after " << TIMER_SEC(set_start_coords) << "s" << std::endl;
time1 = std::chrono::steady_clock::now();
// Sort Edges by target
std::cout << "[extractor] Sorting edges by target ... " << std::flush;
TIMER_START(sort_edges_by_target);
stxxl::sort(all_edges_list.begin(), all_edges_list.end(), CmpEdgeByTargetID(), stxxl_memory);
time2 = std::chrono::steady_clock::now();
elapsed_seconds = time2 - time1;
std::cout << "ok, after " << elapsed_seconds.count() << "s" << std::endl;
TIMER_STOP(sort_edges_by_target);
std::cout << "ok, after " << TIMER_SEC(sort_edges_by_target) << "s" << std::endl;
time1 = std::chrono::steady_clock::now();
std::cout << "[extractor] Setting target coords ... " << std::flush;
TIMER_START(set_target_coords);
// Traverse list of edges and nodes in parallel and set target coord
node_iterator = all_nodes_list.begin();
edge_iterator = all_edges_list.begin();
while (edge_iterator != all_edges_list.end() && node_iterator != all_nodes_list.end())
{
if (edge_iterator->target < node_iterator->id)
if (edge_iterator->target < node_iterator->node_id)
{
++edge_iterator;
continue;
}
if (edge_iterator->target > node_iterator->id)
if (edge_iterator->target > node_iterator->node_id)
{
++node_iterator;
continue;
}
BOOST_ASSERT(edge_iterator->target == node_iterator->id);
BOOST_ASSERT(edge_iterator->target == node_iterator->node_id);
if (edge_iterator->source_coordinate.lat != std::numeric_limits<int>::min() &&
edge_iterator->source_coordinate.lon != std::numeric_limits<int>::min())
{
@@ -394,9 +382,8 @@ void ExtractionContainers::PrepareData(const std::string &output_file_name,
}
++edge_iterator;
}
time2 = std::chrono::steady_clock::now();
elapsed_seconds = time2 - time1;
std::cout << "ok, after " << elapsed_seconds.count() << "s" << std::endl;
TIMER_STOP(set_target_coords);
std::cout << "ok, after " << TIMER_SEC(set_target_coords) << "s" << std::endl;
std::cout << "[extractor] setting number of edges ... " << std::flush;
@@ -404,45 +391,35 @@ void ExtractionContainers::PrepareData(const std::string &output_file_name,
file_out_stream.write((char *)&number_of_used_edges, sizeof(unsigned));
file_out_stream.close();
std::cout << "ok" << std::endl;
time1 = std::chrono::steady_clock::now();
std::cout << "[extractor] writing street name index ... " << std::flush;
TIMER_START(write_name_index);
std::string name_file_streamName = (output_file_name + ".names");
boost::filesystem::ofstream name_file_stream(name_file_streamName, std::ios::binary);
// write number of names
const unsigned number_of_names = name_list.size() + 1;
name_file_stream.write((char *)&(number_of_names), sizeof(unsigned));
// compute total number of chars
unsigned total_number_of_chars = 0;
unsigned total_length = 0;
std::vector<unsigned> name_lengths;
for (const std::string &temp_string : name_list)
{
total_number_of_chars += temp_string.length();
const unsigned string_length = std::min(static_cast<unsigned>(temp_string.length()), 255u);
name_lengths.push_back(string_length);
total_length += string_length;
}
// write total number of chars
name_file_stream.write((char *)&(total_number_of_chars), sizeof(unsigned));
// write prefixe sums
unsigned name_lengths_prefix_sum = 0;
for (const std::string &temp_string : name_list)
{
name_file_stream.write((char *)&(name_lengths_prefix_sum), sizeof(unsigned));
name_lengths_prefix_sum += temp_string.length();
}
// duplicate on purpose!
name_file_stream.write((char *)&(name_lengths_prefix_sum), sizeof(unsigned));
RangeTable<> table(name_lengths);
name_file_stream << table;
name_file_stream.write((char*) &total_length, sizeof(unsigned));
// write all chars consecutively
for (const std::string &temp_string : name_list)
{
const unsigned string_length = temp_string.length();
const unsigned string_length = std::min(static_cast<unsigned>(temp_string.length()), 255u);
name_file_stream.write(temp_string.c_str(), string_length);
}
name_file_stream.close();
time2 = std::chrono::steady_clock::now();
elapsed_seconds = time2 - time1;
std::cout << "ok, after " << elapsed_seconds.count() << "s" << std::endl;
TIMER_STOP(write_name_index);
std::cout << "ok, after " << TIMER_SEC(write_name_index) << "s" << std::endl;
SimpleLogger().Write() << "Processed " << number_of_used_nodes << " nodes and "
<< number_of_used_edges << " edges";
+6 -2
View File
@@ -31,13 +31,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "InternalExtractorEdge.h"
#include "ExtractorStructs.h"
#include "../DataStructures/Restriction.h"
#include "../Util/UUID.h"
#include "../Util/FingerPrint.h"
#include <stxxl/vector>
class ExtractionContainers
{
#ifndef _MSC_VER
constexpr static unsigned stxxl_memory = ((sizeof(std::size_t) == 4) ? std::numeric_limits<int>::max() : std::numeric_limits<unsigned>::max());
#else
const static unsigned stxxl_memory = ((sizeof(std::size_t) == 4) ? INT_MAX : UINT_MAX);
#endif
public:
typedef stxxl::vector<NodeID> STXXLNodeIDVector;
typedef stxxl::vector<ExternalMemoryNode> STXXLNodeVector;
@@ -52,7 +56,7 @@ class ExtractionContainers
STXXLStringVector name_list;
STXXLRestrictionsVector restrictions_list;
STXXLWayIDStartEndVector way_start_end_id_list;
const UUID uuid;
const FingerPrint fingerprint;
ExtractionContainers();
+8 -8
View File
@@ -48,7 +48,7 @@ inline bool durationIsValid(const std::string &s)
std::vector<std::string> result;
boost::algorithm::split_regex(result, s, boost::regex(":"));
bool matched = regex_match(s, e);
const bool matched = regex_match(s, e);
return matched;
}
@@ -63,23 +63,23 @@ inline unsigned parseDuration(const std::string &s)
std::vector<std::string> result;
boost::algorithm::split_regex(result, s, boost::regex(":"));
bool matched = regex_match(s, e);
const bool matched = regex_match(s, e);
if (matched)
{
if (1 == result.size())
{
minutes = stringToInt(result[0]);
minutes = StringToUint(result[0]);
}
if (2 == result.size())
{
minutes = stringToInt(result[1]);
hours = stringToInt(result[0]);
minutes = StringToUint(result[1]);
hours = StringToUint(result[0]);
}
if (3 == result.size())
{
seconds = stringToInt(result[2]);
minutes = stringToInt(result[1]);
hours = stringToInt(result[0]);
seconds = StringToUint(result[2]);
minutes = StringToUint(result[1]);
hours = StringToUint(result[0]);
}
return 10 * (3600 * hours + 60 * minutes + seconds);
}
+1 -1
View File
@@ -43,7 +43,7 @@ struct ExtractionWay
id = SPECIAL_NODEID;
nameID = INVALID_NAMEID;
path.clear();
keyVals.clear();
keyVals.Clear();
direction = ExtractionWay::notSure;
speed = -1;
backward_speed = -1;
+11 -6
View File
@@ -68,6 +68,11 @@ void ExtractorCallbacks::ProcessWay(ExtractionWay &parsed_way)
return;
}
if (parsed_way.path.size() <= 1)
{ // safe-guard against broken data
return;
}
if (std::numeric_limits<unsigned>::max() == parsed_way.id)
{
SimpleLogger().Write(logDEBUG) << "found bogus way with id: " << parsed_way.id
@@ -107,16 +112,16 @@ void ExtractorCallbacks::ProcessWay(ExtractionWay &parsed_way)
parsed_way.direction = ExtractionWay::oneway;
}
const bool split_bidirectional_edge =
const bool split_edge =
(parsed_way.backward_speed > 0) && (parsed_way.speed != parsed_way.backward_speed);
for (unsigned n = 0; n < parsed_way.path.size() - 1; ++n)
for (unsigned n = 0; n < (parsed_way.path.size() - 1); ++n)
{
external_memory.all_edges_list.push_back(InternalExtractorEdge(
parsed_way.path[n],
parsed_way.path[n + 1],
parsed_way.type,
(split_bidirectional_edge ? ExtractionWay::oneway : parsed_way.direction),
(split_edge ? ExtractionWay::oneway : parsed_way.direction),
parsed_way.speed,
parsed_way.nameID,
parsed_way.roundabout,
@@ -124,7 +129,7 @@ void ExtractorCallbacks::ProcessWay(ExtractionWay &parsed_way)
(0 < parsed_way.duration),
parsed_way.isAccessRestricted,
false,
split_bidirectional_edge));
split_edge));
external_memory.used_node_id_list.push_back(parsed_way.path[n]);
}
external_memory.used_node_id_list.push_back(parsed_way.path.back());
@@ -137,7 +142,7 @@ void ExtractorCallbacks::ProcessWay(ExtractionWay &parsed_way)
parsed_way.path[parsed_way.path.size() - 2],
parsed_way.path.back()));
if (split_bidirectional_edge)
if (split_edge)
{ // Only true if the way should be split
std::reverse(parsed_way.path.begin(), parsed_way.path.end());
for (std::vector<NodeID>::size_type n = 0; n < parsed_way.path.size() - 1; ++n)
@@ -154,7 +159,7 @@ void ExtractorCallbacks::ProcessWay(ExtractionWay &parsed_way)
(0 < parsed_way.duration),
parsed_way.isAccessRestricted,
(ExtractionWay::oneway == parsed_way.direction),
split_bidirectional_edge));
split_edge));
}
external_memory.way_start_end_id_list.push_back(
WayIDStartAndEndEdge(parsed_way.id,
+3 -3
View File
@@ -95,7 +95,7 @@ struct CmpWayByID
struct Cmp
{
typedef NodeID value_type;
bool operator()(const NodeID a, const NodeID b) const { return a < b; }
bool operator()(const NodeID left, const NodeID right) const { return left < right; }
value_type max_value() { return 0xffffffff; }
value_type min_value() { return 0x0; }
};
@@ -103,9 +103,9 @@ struct Cmp
struct CmpNodeByID
{
typedef ExternalMemoryNode value_type;
bool operator()(const ExternalMemoryNode &a, const ExternalMemoryNode &b) const
bool operator()(const ExternalMemoryNode &left, const ExternalMemoryNode &right) const
{
return a.id < b.id;
return left.node_id < right.node_id;
}
value_type max_value() { return ExternalMemoryNode::max_value(); }
value_type min_value() { return ExternalMemoryNode::min_value(); }
+115 -89
View File
@@ -35,11 +35,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../DataStructures/ImportNode.h"
#include "../DataStructures/Restriction.h"
#include "../Util/MachineInfo.h"
#include "../Util/OpenMPWrapper.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../typedefs.h"
#include <boost/assert.hpp>
#include <tbb/parallel_for.h>
#include <tbb/task_scheduler_init.h>
#include <osrm/Coordinate.h>
#include <zlib.h>
@@ -50,9 +54,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
PBFParser::PBFParser(const char *fileName,
ExtractorCallbacks *extractor_callbacks,
ScriptingEnvironment &scripting_environment)
ScriptingEnvironment &scripting_environment,
unsigned num_threads)
: BaseParser(extractor_callbacks, scripting_environment)
{
if (0 == num_threads)
{
num_parser_threads = tbb::task_scheduler_init::default_num_threads();
}
else
{
num_parser_threads = num_threads;
}
GOOGLE_PROTOBUF_VERIFY_VERSION;
// TODO: What is the bottleneck here? Filling the queue or reading the stuff from disk?
// NOTE: With Lua scripting, it is parsing the stuff. I/O is virtually for free.
@@ -101,7 +115,7 @@ inline bool PBFParser::ReadHeader()
if (readBlob(input, &init_data))
{
if (!init_data.PBFHeaderBlock.ParseFromArray(&(init_data.charBuffer[0]),
init_data.charBuffer.size()))
static_cast<int>(init_data.charBuffer.size())))
{
std::cerr << "[error] Header not parseable!" << std::endl;
return false;
@@ -159,6 +173,8 @@ inline void PBFParser::ReadData()
inline void PBFParser::ParseData()
{
tbb::task_scheduler_init init(num_parser_threads);
while (true)
{
ParserThreadData *thread_data;
@@ -231,17 +247,17 @@ inline void PBFParser::parseDenseNode(ParserThreadData *thread_data)
m_lastDenseID += dense.id(i);
m_lastDenseLatitude += dense.lat(i);
m_lastDenseLongitude += dense.lon(i);
extracted_nodes_vector[i].id = m_lastDenseID;
extracted_nodes_vector[i].lat =
extracted_nodes_vector[i].node_id = static_cast<NodeID>(m_lastDenseID);
extracted_nodes_vector[i].lat = static_cast<int>(
COORDINATE_PRECISION *
((double)m_lastDenseLatitude * thread_data->PBFprimitiveBlock.granularity() +
thread_data->PBFprimitiveBlock.lat_offset()) /
NANO;
extracted_nodes_vector[i].lon =
NANO);
extracted_nodes_vector[i].lon = static_cast<int>(
COORDINATE_PRECISION *
((double)m_lastDenseLongitude * thread_data->PBFprimitiveBlock.granularity() +
thread_data->PBFprimitiveBlock.lon_offset()) /
NANO;
NANO);
while (denseTagIndex < dense.keys_vals_size())
{
const int tagValue = dense.keys_vals(denseTagIndex);
@@ -253,20 +269,21 @@ inline void PBFParser::parseDenseNode(ParserThreadData *thread_data)
const int keyValue = dense.keys_vals(denseTagIndex + 1);
const std::string &key = thread_data->PBFprimitiveBlock.stringtable().s(tagValue);
const std::string &value = thread_data->PBFprimitiveBlock.stringtable().s(keyValue);
extracted_nodes_vector[i].keyVals.emplace(key, value);
extracted_nodes_vector[i].keyVals.Add(std::move(key), std::move(value));
denseTagIndex += 2;
}
}
#pragma omp parallel
{
const int thread_num = omp_get_thread_num();
#pragma omp parallel for schedule(guided)
for (int i = 0; i < number_of_nodes; ++i)
tbb::parallel_for(tbb::blocked_range<size_t>(0, extracted_nodes_vector.size()),
[this, &extracted_nodes_vector](const tbb::blocked_range<size_t> &range)
{
lua_State *lua_state = this->scripting_environment.getLuaState();
for (size_t i = range.begin(); i != range.end(); ++i)
{
ImportNode &import_node = extracted_nodes_vector[i];
ParseNodeInLua(import_node, scripting_environment.getLuaStateForThreadID(thread_num));
ParseNodeInLua(import_node, lua_state);
}
}
});
for (const ImportNode &import_node : extracted_nodes_vector)
{
@@ -295,8 +312,8 @@ inline void PBFParser::parseRelation(ParserThreadData *thread_data)
std::string except_tag_string;
const OSMPBF::Relation &inputRelation =
thread_data->PBFprimitiveBlock.primitivegroup(thread_data->currentGroupID).relations(i);
bool isRestriction = false;
bool isOnlyRestriction = false;
bool is_restriction = false;
bool is_only_restriction = false;
for (int k = 0, endOfKeys = inputRelation.keys_size(); k < endOfKeys; ++k)
{
const std::string &key =
@@ -307,7 +324,7 @@ inline void PBFParser::parseRelation(ParserThreadData *thread_data)
{
if ("restriction" == val)
{
isRestriction = true;
is_restriction = true;
}
else
{
@@ -316,7 +333,7 @@ inline void PBFParser::parseRelation(ParserThreadData *thread_data)
}
if (("restriction" == key) && (val.find("only_") == 0))
{
isOnlyRestriction = true;
is_only_restriction = true;
}
if ("except" == key)
{
@@ -324,22 +341,22 @@ inline void PBFParser::parseRelation(ParserThreadData *thread_data)
}
}
if (isRestriction && ShouldIgnoreRestriction(except_tag_string))
if (is_restriction && ShouldIgnoreRestriction(except_tag_string))
{
continue;
}
if (isRestriction)
if (is_restriction)
{
int64_t lastRef = 0;
InputRestrictionContainer currentRestrictionContainer(isOnlyRestriction);
int64_t last_ref = 0;
InputRestrictionContainer current_restriction_container(is_only_restriction);
for (int rolesIndex = 0, last_role = inputRelation.roles_sid_size();
rolesIndex < last_role;
++rolesIndex)
{
const std::string &role = thread_data->PBFprimitiveBlock.stringtable().s(
inputRelation.roles_sid(rolesIndex));
lastRef += inputRelation.memids(rolesIndex);
last_ref += inputRelation.memids(rolesIndex);
if (!("from" == role || "to" == role || "via" == role))
{
@@ -353,41 +370,46 @@ inline void PBFParser::parseRelation(ParserThreadData *thread_data)
{ // Only via should be a node
continue;
}
assert("via" == role);
if (std::numeric_limits<unsigned>::max() != currentRestrictionContainer.viaNode)
BOOST_ASSERT("via" == role);
if (std::numeric_limits<unsigned>::max() !=
current_restriction_container.viaNode)
{
currentRestrictionContainer.viaNode = std::numeric_limits<unsigned>::max();
current_restriction_container.viaNode =
std::numeric_limits<unsigned>::max();
}
assert(std::numeric_limits<unsigned>::max() == currentRestrictionContainer.viaNode);
currentRestrictionContainer.restriction.viaNode = lastRef;
BOOST_ASSERT(std::numeric_limits<unsigned>::max() ==
current_restriction_container.viaNode);
current_restriction_container.restriction.viaNode =
static_cast<NodeID>(last_ref);
break;
case 1: // way
assert("from" == role || "to" == role || "via" == role);
BOOST_ASSERT("from" == role || "to" == role || "via" == role);
if ("from" == role)
{
currentRestrictionContainer.fromWay = lastRef;
current_restriction_container.fromWay = static_cast<EdgeID>(last_ref);
}
if ("to" == role)
{
currentRestrictionContainer.toWay = lastRef;
current_restriction_container.toWay = static_cast<EdgeID>(last_ref);
}
if ("via" == role)
{
assert(currentRestrictionContainer.restriction.toNode == std::numeric_limits<unsigned>::max());
currentRestrictionContainer.viaNode = lastRef;
BOOST_ASSERT(current_restriction_container.restriction.toNode ==
std::numeric_limits<unsigned>::max());
current_restriction_container.viaNode = static_cast<NodeID>(last_ref);
}
break;
case 2: // relation, not used. relations relating to relations are evil.
continue;
assert(false);
BOOST_ASSERT(false);
break;
default: // should not happen
assert(false);
BOOST_ASSERT(false);
break;
}
}
if (!extractor_callbacks->ProcessRestriction(currentRestrictionContainer))
if (!extractor_callbacks->ProcessRestriction(current_restriction_container))
{
std::cerr << "[PBFParser] relation not parsed" << std::endl;
}
@@ -402,38 +424,42 @@ inline void PBFParser::parseWay(ParserThreadData *thread_data)
std::vector<ExtractionWay> parsed_way_vector(number_of_ways);
for (int i = 0; i < number_of_ways; ++i)
{
const OSMPBF::Way &inputWay =
const OSMPBF::Way &input_way =
thread_data->PBFprimitiveBlock.primitivegroup(thread_data->currentGroupID).ways(i);
parsed_way_vector[i].id = inputWay.id();
unsigned pathNode(0);
const int number_of_referenced_nodes = inputWay.refs_size();
for (int j = 0; j < number_of_referenced_nodes; ++j)
parsed_way_vector[i].id = static_cast<EdgeID>(input_way.id());
unsigned node_id_in_path = 0;
const auto number_of_referenced_nodes = input_way.refs_size();
for (auto j = 0; j < number_of_referenced_nodes; ++j)
{
pathNode += inputWay.refs(j);
parsed_way_vector[i].path.push_back(pathNode);
node_id_in_path += static_cast<NodeID>(input_way.refs(j));
parsed_way_vector[i].path.push_back(node_id_in_path);
}
assert(inputWay.keys_size() == inputWay.vals_size());
const int number_of_keys = inputWay.keys_size();
for (int j = 0; j < number_of_keys; ++j)
BOOST_ASSERT(input_way.keys_size() == input_way.vals_size());
const auto number_of_keys = input_way.keys_size();
for (auto j = 0; j < number_of_keys; ++j)
{
const std::string &key =
thread_data->PBFprimitiveBlock.stringtable().s(inputWay.keys(j));
thread_data->PBFprimitiveBlock.stringtable().s(input_way.keys(j));
const std::string &val =
thread_data->PBFprimitiveBlock.stringtable().s(inputWay.vals(j));
parsed_way_vector[i].keyVals.emplace(key, val);
thread_data->PBFprimitiveBlock.stringtable().s(input_way.vals(j));
parsed_way_vector[i].keyVals.Add(std::move(key), std::move(val));
}
}
#pragma omp parallel for schedule(guided)
for (int i = 0; i < number_of_ways; ++i)
{
ExtractionWay &extraction_way = parsed_way_vector[i];
if (2 <= extraction_way.path.size())
// TODO: investigate if schedule guided will be handled by tbb automatically
tbb::parallel_for(tbb::blocked_range<size_t>(0, parsed_way_vector.size()),
[this, &parsed_way_vector](const tbb::blocked_range<size_t> &range)
{
lua_State *lua_state = this->scripting_environment.getLuaState();
for (size_t i = range.begin(); i != range.end(); i++)
{
ParseWayInLua(extraction_way,
scripting_environment.getLuaStateForThreadID(omp_get_thread_num()));
ExtractionWay &extraction_way = parsed_way_vector[i];
if (2 <= extraction_way.path.size())
{
ParseWayInLua(extraction_way, lua_state);
}
}
}
});
for (ExtractionWay &extraction_way : parsed_way_vector)
{
@@ -468,9 +494,9 @@ inline void PBFParser::loadGroup(ParserThreadData *thread_data)
if (group.has_dense())
{
thread_data->entityTypeIndicator = TypeDenseNode;
assert(0 != group.dense().id_size());
BOOST_ASSERT(0 != group.dense().id_size());
}
assert(thread_data->entityTypeIndicator != TypeDummy);
BOOST_ASSERT(thread_data->entityTypeIndicator != TypeDummy);
}
inline void PBFParser::loadBlock(ParserThreadData *thread_data)
@@ -501,51 +527,51 @@ inline bool PBFParser::readPBFBlobHeader(std::fstream &stream, ParserThreadData
return dataSuccessfullyParsed;
}
inline bool PBFParser::unpackZLIB(std::fstream &, ParserThreadData *thread_data)
inline bool PBFParser::unpackZLIB(ParserThreadData *thread_data)
{
unsigned rawSize = thread_data->PBFBlob.raw_size();
char *unpackedDataArray = new char[rawSize];
z_stream compressedDataStream;
compressedDataStream.next_in = (unsigned char *)thread_data->PBFBlob.zlib_data().data();
compressedDataStream.avail_in = thread_data->PBFBlob.zlib_data().size();
compressedDataStream.next_out = (unsigned char *)unpackedDataArray;
compressedDataStream.avail_out = rawSize;
compressedDataStream.zalloc = Z_NULL;
compressedDataStream.zfree = Z_NULL;
compressedDataStream.opaque = Z_NULL;
int ret = inflateInit(&compressedDataStream);
if (ret != Z_OK)
auto raw_size = thread_data->PBFBlob.raw_size();
char *unpacked_data_array = new char[raw_size];
z_stream compressed_data_stream;
compressed_data_stream.next_in = (unsigned char *)thread_data->PBFBlob.zlib_data().data();
compressed_data_stream.avail_in = thread_data->PBFBlob.zlib_data().size();
compressed_data_stream.next_out = (unsigned char *)unpacked_data_array;
compressed_data_stream.avail_out = raw_size;
compressed_data_stream.zalloc = Z_NULL;
compressed_data_stream.zfree = Z_NULL;
compressed_data_stream.opaque = Z_NULL;
int return_code = inflateInit(&compressed_data_stream);
if (return_code != Z_OK)
{
std::cerr << "[error] failed to init zlib stream" << std::endl;
delete[] unpackedDataArray;
delete[] unpacked_data_array;
return false;
}
ret = inflate(&compressedDataStream, Z_FINISH);
if (ret != Z_STREAM_END)
return_code = inflate(&compressed_data_stream, Z_FINISH);
if (return_code != Z_STREAM_END)
{
std::cerr << "[error] failed to inflate zlib stream" << std::endl;
std::cerr << "[error] Error type: " << ret << std::endl;
delete[] unpackedDataArray;
std::cerr << "[error] Error type: " << return_code << std::endl;
delete[] unpacked_data_array;
return false;
}
ret = inflateEnd(&compressedDataStream);
if (ret != Z_OK)
return_code = inflateEnd(&compressed_data_stream);
if (return_code != Z_OK)
{
std::cerr << "[error] failed to deinit zlib stream" << std::endl;
delete[] unpackedDataArray;
delete[] unpacked_data_array;
return false;
}
thread_data->charBuffer.clear();
thread_data->charBuffer.resize(rawSize);
std::copy(unpackedDataArray, unpackedDataArray + rawSize, thread_data->charBuffer.begin());
delete[] unpackedDataArray;
thread_data->charBuffer.resize(raw_size);
std::copy(unpacked_data_array, unpacked_data_array + raw_size, thread_data->charBuffer.begin());
delete[] unpacked_data_array;
return true;
}
inline bool PBFParser::unpackLZMA(std::fstream &, ParserThreadData *) { return false; }
inline bool PBFParser::unpackLZMA(ParserThreadData *) { return false; }
inline bool PBFParser::readBlob(std::fstream &stream, ParserThreadData *thread_data)
{
@@ -580,7 +606,7 @@ inline bool PBFParser::readBlob(std::fstream &stream, ParserThreadData *thread_d
}
else if (thread_data->PBFBlob.has_zlib_data())
{
if (!unpackZLIB(stream, thread_data))
if (!unpackZLIB(thread_data))
{
std::cerr << "[error] zlib data encountered that could not be unpacked" << std::endl;
delete[] data;
@@ -589,7 +615,7 @@ inline bool PBFParser::readBlob(std::fstream &stream, ParserThreadData *thread_d
}
else if (thread_data->PBFBlob.has_lzma_data())
{
if (!unpackLZMA(stream, thread_data))
if (!unpackLZMA(thread_data))
{
std::cerr << "[error] lzma data encountered that could not be unpacked" << std::endl;
}
@@ -629,7 +655,7 @@ bool PBFParser::readNextBlock(std::fstream &stream, ParserThreadData *thread_dat
}
if (!thread_data->PBFprimitiveBlock.ParseFromArray(&(thread_data->charBuffer[0]),
thread_data->charBuffer.size()))
thread_data->charBuffer.size()))
{
std::cerr << "failed to parse PrimitiveBlock" << std::endl;
return false;
+7 -3
View File
@@ -63,7 +63,10 @@ class PBFParser : public BaseParser
};
public:
PBFParser(const char *file_name, ExtractorCallbacks *extractor_callbacks, ScriptingEnvironment &scripting_environment);
PBFParser(const char *file_name,
ExtractorCallbacks *extractor_callbacks,
ScriptingEnvironment &scripting_environment,
unsigned num_parser_threads = 0);
virtual ~PBFParser();
inline bool ReadHeader();
@@ -80,8 +83,8 @@ class PBFParser : public BaseParser
inline void loadGroup(ParserThreadData *thread_data);
inline void loadBlock(ParserThreadData *thread_data);
inline bool readPBFBlobHeader(std::fstream &stream, ParserThreadData *thread_data);
inline bool unpackZLIB(std::fstream &stream, ParserThreadData *thread_data);
inline bool unpackLZMA(std::fstream &stream, ParserThreadData *thread_data);
inline bool unpackZLIB(ParserThreadData *thread_data);
inline bool unpackLZMA(ParserThreadData *thread_data);
inline bool readBlob(std::fstream &stream, ParserThreadData *thread_data);
inline bool readNextBlock(std::fstream &stream, ParserThreadData *thread_data);
@@ -94,6 +97,7 @@ class PBFParser : public BaseParser
std::fstream input; // the input stream to parse
std::shared_ptr<ConcurrentQueue<ParserThreadData *>> thread_data_queue;
unsigned num_parser_threads;
};
#endif /* PBFPARSER_H_ */
+73 -76
View File
@@ -31,94 +31,91 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "ExtractionWay.h"
#include "../DataStructures/ImportNode.h"
#include "../Util/LuaUtil.h"
#include "../Util/OpenMPWrapper.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../typedefs.h"
ScriptingEnvironment::ScriptingEnvironment() {}
ScriptingEnvironment::ScriptingEnvironment(const char *file_name)
: file_name(file_name)
{
SimpleLogger().Write() << "Using script " << file_name;
// Create a new lua state
for (int i = 0; i < omp_get_max_threads(); ++i)
{
lua_state_vector.push_back(luaL_newstate());
}
// Connect LuaBind to this lua state for all threads
#pragma omp parallel
{
lua_State *lua_state = getLuaStateForThreadID(omp_get_thread_num());
luabind::open(lua_state);
// open utility libraries string library;
luaL_openlibs(lua_state);
luaAddScriptFolderToLoadPath(lua_state, file_name);
// Add our function to the state's global scope
luabind::module(lua_state)[
luabind::def("print", LUA_print<std::string>),
luabind::def("durationIsValid", durationIsValid),
luabind::def("parseDuration", parseDuration)
];
luabind::module(lua_state)[luabind::class_<HashTable<std::string, std::string>>("keyVals")
.def("Add", &HashTable<std::string, std::string>::Add)
.def("Find", &HashTable<std::string, std::string>::Find)
.def("Holds", &HashTable<std::string, std::string>::Holds)];
luabind::module(lua_state)[luabind::class_<ImportNode>("Node")
.def(luabind::constructor<>())
.def_readwrite("lat", &ImportNode::lat)
.def_readwrite("lon", &ImportNode::lon)
.def_readonly("id", &ImportNode::id)
.def_readwrite("bollard", &ImportNode::bollard)
.def_readwrite("traffic_light", &ImportNode::trafficLight)
.def_readwrite("tags", &ImportNode::keyVals)];
luabind::module(lua_state)
[luabind::class_<ExtractionWay>("Way")
.def(luabind::constructor<>())
.def_readonly("id", &ExtractionWay::id)
.def_readwrite("name", &ExtractionWay::name)
.def_readwrite("speed", &ExtractionWay::speed)
.def_readwrite("backward_speed", &ExtractionWay::backward_speed)
.def_readwrite("duration", &ExtractionWay::duration)
.def_readwrite("type", &ExtractionWay::type)
.def_readwrite("access", &ExtractionWay::access)
.def_readwrite("roundabout", &ExtractionWay::roundabout)
.def_readwrite("is_access_restricted", &ExtractionWay::isAccessRestricted)
.def_readwrite("ignore_in_grid", &ExtractionWay::ignoreInGrid)
.def_readwrite("tags", &ExtractionWay::keyVals)
.def_readwrite("direction", &ExtractionWay::direction)
.enum_("constants")[
luabind::value("notSure", 0),
luabind::value("oneway", 1),
luabind::value("bidirectional", 2),
luabind::value("opposite", 3)
]];
// fails on c++11/OS X 10.9
luabind::module(lua_state)[luabind::class_<std::vector<std::string>>("vector").def(
"Add",
static_cast<void (std::vector<std::string>::*)(const std::string &)>(
&std::vector<std::string>::push_back))];
if (0 != luaL_dofile(lua_state, file_name))
{
throw OSRMException("ERROR occured in scripting block");
}
}
}
ScriptingEnvironment::~ScriptingEnvironment()
void ScriptingEnvironment::initLuaState(lua_State* lua_state)
{
for (unsigned i = 0; i < lua_state_vector.size(); ++i)
luabind::open(lua_state);
// open utility libraries string library;
luaL_openlibs(lua_state);
luaAddScriptFolderToLoadPath(lua_state, file_name.c_str());
// Add our function to the state's global scope
luabind::module(lua_state)[
luabind::def("print", LUA_print<std::string>),
luabind::def("durationIsValid", durationIsValid),
luabind::def("parseDuration", parseDuration)
];
luabind::module(lua_state)[luabind::class_<HashTable<std::string, std::string>>("keyVals")
.def("Add", &HashTable<std::string, std::string>::Add)
.def("Find", &HashTable<std::string, std::string>::Find)
.def("Holds", &HashTable<std::string, std::string>::Holds)];
luabind::module(lua_state)[luabind::class_<ImportNode>("Node")
.def(luabind::constructor<>())
.def_readwrite("lat", &ImportNode::lat)
.def_readwrite("lon", &ImportNode::lon)
.def_readonly("id", &ImportNode::node_id)
.def_readwrite("bollard", &ImportNode::bollard)
.def_readwrite("traffic_light", &ImportNode::trafficLight)
.def_readwrite("tags", &ImportNode::keyVals)];
luabind::module(lua_state)
[luabind::class_<ExtractionWay>("Way")
.def(luabind::constructor<>())
.def_readonly("id", &ExtractionWay::id)
.def_readwrite("name", &ExtractionWay::name)
.def_readwrite("speed", &ExtractionWay::speed)
.def_readwrite("backward_speed", &ExtractionWay::backward_speed)
.def_readwrite("duration", &ExtractionWay::duration)
.def_readwrite("type", &ExtractionWay::type)
.def_readwrite("access", &ExtractionWay::access)
.def_readwrite("roundabout", &ExtractionWay::roundabout)
.def_readwrite("is_access_restricted", &ExtractionWay::isAccessRestricted)
.def_readwrite("ignore_in_grid", &ExtractionWay::ignoreInGrid)
.def_readwrite("tags", &ExtractionWay::keyVals)
.def_readwrite("direction", &ExtractionWay::direction)
.enum_("constants")[
luabind::value("notSure", 0),
luabind::value("oneway", 1),
luabind::value("bidirectional", 2),
luabind::value("opposite", 3)
]];
// fails on c++11/OS X 10.9
luabind::module(lua_state)[luabind::class_<std::vector<std::string>>("vector").def(
"Add",
static_cast<void (std::vector<std::string>::*)(const std::string &)>(
&std::vector<std::string>::push_back))];
if (0 != luaL_dofile(lua_state, file_name.c_str()))
{
// lua_state_vector[i];
throw OSRMException("ERROR occured in scripting block");
}
}
lua_State *ScriptingEnvironment::getLuaStateForThreadID(const int id) { return lua_state_vector[id]; }
lua_State *ScriptingEnvironment::getLuaState()
{
bool initialized = false;
auto& ref = script_contexts.local(initialized);
if (!initialized)
{
std::shared_ptr<lua_State> state(luaL_newstate(), lua_close);
ref = state;
initLuaState(ref.get());
}
return ref.get();
}
+9 -4
View File
@@ -28,7 +28,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef SCRIPTINGENVIRONMENT_H_
#define SCRIPTINGENVIRONMENT_H_
#include <vector>
#include <string>
#include <memory>
#include <tbb/enumerable_thread_specific.h>
struct lua_State;
@@ -37,11 +39,14 @@ class ScriptingEnvironment
public:
ScriptingEnvironment();
explicit ScriptingEnvironment(const char *file_name);
virtual ~ScriptingEnvironment();
lua_State *getLuaStateForThreadID(const int);
lua_State *getLuaState();
std::vector<lua_State *> lua_state_vector;
private:
void initLuaState(lua_State* lua_state);
std::string file_name;
tbb::enumerable_thread_specific<std::shared_ptr<lua_State>> script_contexts;
};
#endif /* SCRIPTINGENVIRONMENT_H_ */
+149 -143
View File
@@ -40,13 +40,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <osrm/Coordinate.h>
XMLParser::XMLParser(const char *filename, ExtractorCallbacks *ec, ScriptingEnvironment &se)
: BaseParser(ec, se)
XMLParser::XMLParser(const char *filename,
ExtractorCallbacks *extractor_callbacks,
ScriptingEnvironment &scripting_environment)
: BaseParser(extractor_callbacks, scripting_environment)
{
inputReader = inputReaderFactory(filename);
}
bool XMLParser::ReadHeader() { return (xmlTextReaderRead(inputReader) == 1); }
bool XMLParser::ReadHeader() { return xmlTextReaderRead(inputReader) == 1; }
bool XMLParser::Parse()
{
while (xmlTextReaderRead(inputReader) == 1)
@@ -60,16 +62,16 @@ bool XMLParser::Parse()
}
xmlChar *currentName = xmlTextReaderName(inputReader);
if (currentName == NULL)
if (currentName == nullptr)
{
continue;
}
if (xmlStrEqual(currentName, (const xmlChar *)"node") == 1)
{
ImportNode n = ReadXMLNode();
ParseNodeInLua(n, lua_state);
extractor_callbacks->ProcessNode(n);
ImportNode current_node = ReadXMLNode();
ParseNodeInLua(current_node, lua_state);
extractor_callbacks->ProcessNode(current_node);
}
if (xmlStrEqual(currentName, (const xmlChar *)"way") == 1)
@@ -80,8 +82,9 @@ bool XMLParser::Parse()
}
if (use_turn_restrictions && xmlStrEqual(currentName, (const xmlChar *)"relation") == 1)
{
InputRestrictionContainer r = ReadXMLRestriction();
if ((UINT_MAX != r.fromWay) && !extractor_callbacks->ProcessRestriction(r))
InputRestrictionContainer current_restriction = ReadXMLRestriction();
if ((UINT_MAX != current_restriction.fromWay) &&
!extractor_callbacks->ProcessRestriction(current_restriction))
{
std::cerr << "[XMLParser] restriction not parsed" << std::endl;
}
@@ -93,103 +96,106 @@ bool XMLParser::Parse()
InputRestrictionContainer XMLParser::ReadXMLRestriction()
{
InputRestrictionContainer restriction;
std::string except_tag_string;
if (xmlTextReaderIsEmptyElement(inputReader) != 1)
if (xmlTextReaderIsEmptyElement(inputReader) == 1)
{
const int depth = xmlTextReaderDepth(inputReader);
while (xmlTextReaderRead(inputReader) == 1)
return restriction;
}
std::string except_tag_string;
const int depth = xmlTextReaderDepth(inputReader);
while (xmlTextReaderRead(inputReader) == 1)
{
const int child_type = xmlTextReaderNodeType(inputReader);
if (child_type != 1 && child_type != 15)
{
const int child_type = xmlTextReaderNodeType(inputReader);
if (child_type != 1 && child_type != 15)
{
continue;
}
const int childDepth = xmlTextReaderDepth(inputReader);
xmlChar *childName = xmlTextReaderName(inputReader);
if (childName == NULL)
{
continue;
}
if (depth == childDepth && child_type == 15 &&
xmlStrEqual(childName, (const xmlChar *)"relation") == 1)
{
xmlFree(childName);
break;
}
if (child_type != 1)
{
xmlFree(childName);
continue;
}
if (xmlStrEqual(childName, (const xmlChar *)"tag") == 1)
{
xmlChar *k = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"k");
xmlChar *value = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"v");
if (k != NULL && value != NULL)
{
if (xmlStrEqual(k, (const xmlChar *)"restriction") &&
(0 == std::string((const char *)value).find("only_")))
{
restriction.restriction.flags.isOnly = true;
}
if (xmlStrEqual(k, (const xmlChar *)"except"))
{
except_tag_string = (const char *)value;
}
}
if (k != NULL)
{
xmlFree(k);
}
if (value != NULL)
{
xmlFree(value);
}
}
else if (xmlStrEqual(childName, (const xmlChar *)"member") == 1)
{
xmlChar *ref = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"ref");
if (ref != NULL)
{
xmlChar *role = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"role");
xmlChar *type = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"type");
if (xmlStrEqual(role, (const xmlChar *)"to") &&
xmlStrEqual(type, (const xmlChar *)"way"))
{
restriction.toWay = stringToUint((const char *)ref);
}
if (xmlStrEqual(role, (const xmlChar *)"from") &&
xmlStrEqual(type, (const xmlChar *)"way"))
{
restriction.fromWay = stringToUint((const char *)ref);
}
if (xmlStrEqual(role, (const xmlChar *)"via") &&
xmlStrEqual(type, (const xmlChar *)"node"))
{
restriction.restriction.viaNode = stringToUint((const char *)ref);
}
if (NULL != type)
{
xmlFree(type);
}
if (NULL != role)
{
xmlFree(role);
}
if (NULL != ref)
{
xmlFree(ref);
}
}
}
xmlFree(childName);
continue;
}
const int child_depth = xmlTextReaderDepth(inputReader);
xmlChar *child_name = xmlTextReaderName(inputReader);
if (child_name == nullptr)
{
continue;
}
if (depth == child_depth && child_type == 15 &&
xmlStrEqual(child_name, (const xmlChar *)"relation") == 1)
{
xmlFree(child_name);
break;
}
if (child_type != 1)
{
xmlFree(child_name);
continue;
}
if (xmlStrEqual(child_name, (const xmlChar *)"tag") == 1)
{
xmlChar *key = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"k");
xmlChar *value = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"v");
if (key != nullptr && value != nullptr)
{
if (xmlStrEqual(key, (const xmlChar *)"restriction") &&
StringStartsWith((const char *)value, "only_"))
{
restriction.restriction.flags.isOnly = true;
}
if (xmlStrEqual(key, (const xmlChar *)"except"))
{
except_tag_string = (const char *)value;
}
}
if (key != nullptr)
{
xmlFree(key);
}
if (value != nullptr)
{
xmlFree(value);
}
}
else if (xmlStrEqual(child_name, (const xmlChar *)"member") == 1)
{
xmlChar *ref = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"ref");
if (ref != nullptr)
{
xmlChar *role = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"role");
xmlChar *type = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"type");
if (xmlStrEqual(role, (const xmlChar *)"to") &&
xmlStrEqual(type, (const xmlChar *)"way"))
{
restriction.toWay = StringToUint((const char *)ref);
}
if (xmlStrEqual(role, (const xmlChar *)"from") &&
xmlStrEqual(type, (const xmlChar *)"way"))
{
restriction.fromWay = StringToUint((const char *)ref);
}
if (xmlStrEqual(role, (const xmlChar *)"via") &&
xmlStrEqual(type, (const xmlChar *)"node"))
{
restriction.restriction.viaNode = StringToUint((const char *)ref);
}
if (nullptr != type)
{
xmlFree(type);
}
if (nullptr != role)
{
xmlFree(role);
}
if (nullptr != ref)
{
xmlFree(ref);
}
}
}
xmlFree(child_name);
}
if (ShouldIgnoreRestriction(except_tag_string))
@@ -214,56 +220,56 @@ ExtractionWay XMLParser::ReadXMLWay()
{
continue;
}
const int childDepth = xmlTextReaderDepth(inputReader);
xmlChar *childName = xmlTextReaderName(inputReader);
if (childName == NULL)
const int child_depth = xmlTextReaderDepth(inputReader);
xmlChar *child_name = xmlTextReaderName(inputReader);
if (child_name == nullptr)
{
continue;
}
if (depth == childDepth && child_type == 15 &&
xmlStrEqual(childName, (const xmlChar *)"way") == 1)
if (depth == child_depth && child_type == 15 &&
xmlStrEqual(child_name, (const xmlChar *)"way") == 1)
{
xmlChar *id = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"id");
way.id = stringToUint((char *)id);
xmlFree(id);
xmlFree(childName);
xmlChar *node_id = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"id");
way.id = StringToUint((char *)node_id);
xmlFree(node_id);
xmlFree(child_name);
break;
}
if (child_type != 1)
{
xmlFree(childName);
xmlFree(child_name);
continue;
}
if (xmlStrEqual(childName, (const xmlChar *)"tag") == 1)
if (xmlStrEqual(child_name, (const xmlChar *)"tag") == 1)
{
xmlChar *k = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"k");
xmlChar *key = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"k");
xmlChar *value = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"v");
if (k != NULL && value != NULL)
if (key != nullptr && value != nullptr)
{
way.keyVals.Add(std::string((char *)k), std::string((char *)value));
way.keyVals.Add(std::string((char *)key), std::string((char *)value));
}
if (k != NULL)
if (key != nullptr)
{
xmlFree(k);
xmlFree(key);
}
if (value != NULL)
if (value != nullptr)
{
xmlFree(value);
}
}
else if (xmlStrEqual(childName, (const xmlChar *)"nd") == 1)
else if (xmlStrEqual(child_name, (const xmlChar *)"nd") == 1)
{
xmlChar *ref = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"ref");
if (ref != NULL)
if (ref != nullptr)
{
way.path.push_back(stringToUint((const char *)ref));
way.path.push_back(StringToUint((const char *)ref));
xmlFree(ref);
}
}
xmlFree(childName);
xmlFree(child_name);
}
return way;
}
@@ -273,21 +279,21 @@ ImportNode XMLParser::ReadXMLNode()
ImportNode node;
xmlChar *attribute = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"lat");
if (attribute != NULL)
if (attribute != nullptr)
{
node.lat = COORDINATE_PRECISION * StringToDouble((const char *)attribute);
node.lat = static_cast<int>(COORDINATE_PRECISION * StringToDouble((const char *)attribute));
xmlFree(attribute);
}
attribute = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"lon");
if (attribute != NULL)
if (attribute != nullptr)
{
node.lon = COORDINATE_PRECISION * StringToDouble((const char *)attribute);
node.lon = static_cast<int>(COORDINATE_PRECISION * StringToDouble((const char *)attribute));
xmlFree(attribute);
}
attribute = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"id");
if (attribute != NULL)
if (attribute != nullptr)
{
node.id = stringToUint((const char *)attribute);
node.node_id = StringToUint((const char *)attribute);
xmlFree(attribute);
}
@@ -304,44 +310,44 @@ ImportNode XMLParser::ReadXMLNode()
{
continue;
}
const int childDepth = xmlTextReaderDepth(inputReader);
xmlChar *childName = xmlTextReaderName(inputReader);
if (childName == NULL)
const int child_depth = xmlTextReaderDepth(inputReader);
xmlChar *child_name = xmlTextReaderName(inputReader);
if (child_name == nullptr)
{
continue;
}
if (depth == childDepth && child_type == 15 &&
xmlStrEqual(childName, (const xmlChar *)"node") == 1)
if (depth == child_depth && child_type == 15 &&
xmlStrEqual(child_name, (const xmlChar *)"node") == 1)
{
xmlFree(childName);
xmlFree(child_name);
break;
}
if (child_type != 1)
{
xmlFree(childName);
xmlFree(child_name);
continue;
}
if (xmlStrEqual(childName, (const xmlChar *)"tag") == 1)
if (xmlStrEqual(child_name, (const xmlChar *)"tag") == 1)
{
xmlChar *k = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"k");
xmlChar *key = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"k");
xmlChar *value = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"v");
if (k != NULL && value != NULL)
if (key != nullptr && value != nullptr)
{
node.keyVals.emplace(std::string((char *)(k)), std::string((char *)(value)));
node.keyVals.Add(std::string((char *)(key)), std::string((char *)(value)));
}
if (k != NULL)
if (key != nullptr)
{
xmlFree(k);
xmlFree(key);
}
if (value != NULL)
if (value != nullptr)
{
xmlFree(value);
}
}
xmlFree(childName);
xmlFree(child_name);
}
return node;
}
+6 -2
View File
@@ -28,15 +28,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef XMLPARSER_H_
#define XMLPARSER_H_
#include "ExtractorCallbacks.h"
#include "BaseParser.h"
#include "../DataStructures/Restriction.h"
#include <libxml/xmlreader.h>
class ExtractorCallbacks;
class XMLParser : public BaseParser
{
public:
XMLParser(const char *filename, ExtractorCallbacks *ec, ScriptingEnvironment &se);
XMLParser(const char *filename,
ExtractorCallbacks *extractor_callbacks,
ScriptingEnvironment &scripting_environment);
bool ReadHeader();
bool Parse();
+30 -21
View File
@@ -30,8 +30,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <functional>
#include <iosfwd> //for std::ostream
#include <string>
constexpr float COORDINATE_PRECISION = 1000000.;
const float COORDINATE_PRECISION = 1000000.f;
struct FixedPointCoordinate
{
@@ -48,34 +49,42 @@ struct FixedPointCoordinate
static double
ApproximateDistance(const int lat1, const int lon1, const int lat2, const int lon2);
static double ApproximateDistance(const FixedPointCoordinate &c1,
const FixedPointCoordinate &c2);
static double ApproximateDistance(const FixedPointCoordinate &first_coordinate,
const FixedPointCoordinate &second_coordinate);
static float ApproximateEuclideanDistance(const FixedPointCoordinate &c1,
const FixedPointCoordinate &c2);
static float ApproximateEuclideanDistance(const FixedPointCoordinate &first_coordinate,
const FixedPointCoordinate &second_coordinate);
static float ApproximateEuclideanDistance(const int lat1, const int lon1, const int lat2, const int lon2);
static float ApproximateEuclideanDistance(const int lat1,
const int lon1,
const int lat2,
const int lon2);
static float ApproximateSquaredEuclideanDistance(const FixedPointCoordinate &c1,
const FixedPointCoordinate &c2);
static float ApproximateSquaredEuclideanDistance(const FixedPointCoordinate &first_coordinate,
const FixedPointCoordinate &second_coordinate);
static void convertInternalLatLonToString(const int value, std::string &output);
static void convertInternalCoordinateToString(const FixedPointCoordinate &coord,
static void convertInternalCoordinateToString(const FixedPointCoordinate &coordinate,
std::string &output);
static void convertInternalReversedCoordinateToString(const FixedPointCoordinate &coord,
static void convertInternalReversedCoordinateToString(const FixedPointCoordinate &coordinate,
std::string &output);
static float ComputePerpendicularDistance(const FixedPointCoordinate &point,
const FixedPointCoordinate &segA,
const FixedPointCoordinate &segB);
static float ComputePerpendicularDistance(const FixedPointCoordinate &segment_source,
const FixedPointCoordinate &segment_target,
const FixedPointCoordinate &query_location);
static float ComputePerpendicularDistance(const FixedPointCoordinate &segment_source,
const FixedPointCoordinate &segment_target,
const FixedPointCoordinate &query_location,
FixedPointCoordinate &nearest_location,
float &ratio);
static int OrderedPerpendicularDistanceApproximation(const FixedPointCoordinate& segment_source,
const FixedPointCoordinate& segment_target,
const FixedPointCoordinate& query_location);
static float ComputePerpendicularDistance(const FixedPointCoordinate &coord_a,
const FixedPointCoordinate &coord_b,
const FixedPointCoordinate &query_location,
FixedPointCoordinate &nearest_location,
float &r);
static float GetBearing(const FixedPointCoordinate &A, const FixedPointCoordinate &B);
@@ -87,10 +96,10 @@ struct FixedPointCoordinate
static float RadianToDegree(const float radian);
};
inline std::ostream &operator<<(std::ostream &o, FixedPointCoordinate const &c)
inline std::ostream &operator<<(std::ostream &out_stream, FixedPointCoordinate const &coordinate)
{
c.Output(o);
return o;
coordinate.Output(out_stream);
return out_stream;
}
#endif /* FIXED_POINT_COORDINATE_H_ */
+8 -2
View File
@@ -29,18 +29,24 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define HTTP_HEADER_H
#include <string>
#include <algorithm>
namespace http
{
struct Header
{
std::string name;
std::string value;
Header& operator=(const Header& other) = default;
Header(const std::string & name, const std::string & value) : name(name), value(value) {}
Header(const Header && other) : name(std::move(other.name)), value(std::move(other.value)) {}
void Clear()
{
name.clear();
value.clear();
}
std::string name;
std::string value;
};
}
+2 -2
View File
@@ -56,11 +56,11 @@ class Reply
internalServerError = 500 } status;
std::vector<Header> headers;
std::vector<boost::asio::const_buffer> toBuffers();
std::vector<boost::asio::const_buffer> ToBuffers();
std::vector<boost::asio::const_buffer> HeaderstoBuffers();
std::vector<char> content;
static Reply StockReply(status_type status);
void setSize(const unsigned size);
void SetSize(const unsigned size);
void SetUncompressedSize();
Reply();
+16 -1
View File
@@ -25,22 +25,36 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
namespace boost { namespace interprocess { class named_mutex; } }
#include "OSRM_impl.h"
#include "OSRM.h"
#include <osrm/Reply.h>
#include <osrm/RouteParameters.h>
#include <osrm/ServerPaths.h>
#include "../Plugins/BasePlugin.h"
#include "../Plugins/DistanceTablePlugin.h"
#include "../Plugins/HelloWorldPlugin.h"
#include "../Plugins/LocatePlugin.h"
#include "../Plugins/NearestPlugin.h"
#include "../Plugins/TimestampPlugin.h"
#include "../Plugins/ViaRoutePlugin.h"
#include "../Server/DataStructures/BaseDataFacade.h"
#include "../Server/DataStructures/InternalDataFacade.h"
#include "../Server/DataStructures/SharedBarriers.h"
#include "../Server/DataStructures/SharedDataFacade.h"
#include "../Util/SimpleLogger.h"
#include <boost/assert.hpp>
#include <boost/interprocess/sync/named_condition.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <algorithm>
#include <fstream>
#include <utility>
#include <vector>
OSRM_impl::OSRM_impl(const ServerPaths &server_paths, const bool use_shared_memory)
: use_shared_memory(use_shared_memory)
@@ -66,6 +80,7 @@ OSRM_impl::OSRM_impl(const ServerPaths &server_paths, const bool use_shared_memo
OSRM_impl::~OSRM_impl()
{
delete query_data_facade;
for (PluginMap::value_type &plugin_pointer : plugin_map)
{
delete plugin_pointer.second;
+4 -4
View File
@@ -28,13 +28,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef OSRM_IMPL_H
#define OSRM_IMPL_H
#include <osrm/Reply.h>
#include <osrm/RouteParameters.h>
class BasePlugin;
namespace http { class Reply; }
struct RouteParameters;
#include <osrm/ServerPaths.h>
#include "../DataStructures/QueryEdge.h"
#include "../Plugins/BasePlugin.h"
#include "../Util/ProgramOptions.h"
#include <unordered_map>
#include <string>
+22 -17
View File
@@ -85,33 +85,38 @@ template <class DataFacadeT> class DistanceTablePlugin : public BasePlugin
for (const FixedPointCoordinate &coordinate : route_parameters.coordinates)
{
raw_route.raw_via_node_coordinates.emplace_back(coordinate);
raw_route.raw_via_node_coordinates.emplace_back(std::move(coordinate));
}
std::vector<PhantomNode> phantom_node_vector(raw_route.raw_via_node_coordinates.size());
const bool checksum_OK = (route_parameters.check_sum == raw_route.check_sum);
unsigned max_locations = std::min((std::size_t)100, raw_route.raw_via_node_coordinates.size());
unsigned max_locations =
std::min(100u, static_cast<unsigned>(raw_route.raw_via_node_coordinates.size()));
PhantomNodeArray phantom_node_vector(max_locations);
for (unsigned i = 0; i < max_locations; ++i)
{
if (checksum_OK && i < route_parameters.hints.size() &&
!route_parameters.hints[i].empty())
{
DecodeObjectFromBase64(route_parameters.hints[i], phantom_node_vector[i]);
if (phantom_node_vector[i].isValid(facade->GetNumberOfNodes()))
PhantomNode current_phantom_node;
DecodeObjectFromBase64(route_parameters.hints[i], current_phantom_node);
if (current_phantom_node.isValid(facade->GetNumberOfNodes()))
{
phantom_node_vector[i].emplace_back(std::move(current_phantom_node));
continue;
}
}
facade->FindPhantomNodeForCoordinate(raw_route.raw_via_node_coordinates[i],
phantom_node_vector[i],
route_parameters.zoom_level);
BOOST_ASSERT(phantom_node_vector[i].isValid(facade->GetNumberOfNodes()));
facade->IncrementalFindPhantomNodeForCoordinate(raw_route.raw_via_node_coordinates[i],
phantom_node_vector[i],
route_parameters.zoom_level,
1);
BOOST_ASSERT(phantom_node_vector[i].front().isValid(facade->GetNumberOfNodes()));
}
TIMER_START(distance_table);
std::shared_ptr<std::vector<EdgeWeight>> result_table = search_engine_ptr->distance_table(phantom_node_vector);
TIMER_STOP(distance_table);
// TIMER_START(distance_table);
std::shared_ptr<std::vector<EdgeWeight>> result_table =
search_engine_ptr->distance_table(phantom_node_vector);
// TIMER_STOP(distance_table);
if (!result_table)
{
@@ -120,12 +125,12 @@ template <class DataFacadeT> class DistanceTablePlugin : public BasePlugin
}
JSON::Object json_object;
JSON::Array json_array;
const unsigned number_of_locations = phantom_node_vector.size();
for(unsigned row = 0; row < number_of_locations; ++row)
const unsigned number_of_locations = static_cast<unsigned>(phantom_node_vector.size());
for (unsigned row = 0; row < number_of_locations; ++row)
{
JSON::Array json_row;
auto row_begin_iterator = result_table->begin() + (row*number_of_locations);
auto row_end_iterator = result_table->begin() + ((row+1)*number_of_locations);
auto row_begin_iterator = result_table->begin() + (row * number_of_locations);
auto row_end_iterator = result_table->begin() + ((row + 1) * number_of_locations);
json_row.values.insert(json_row.values.end(), row_begin_iterator, row_end_iterator);
json_array.values.push_back(json_row);
}
+3 -4
View File
@@ -55,7 +55,7 @@ class HelloWorldPlugin : public BasePlugin
temp_string = IntToString(routeParameters.zoom_level);
json_result.values["zoom_level"] = temp_string;
temp_string = IntToString(routeParameters.check_sum);
temp_string = UintToString(routeParameters.check_sum);
json_result.values["check_sum"] = temp_string;
json_result.values["instructions"] = (routeParameters.print_instructions ? "yes" : "no");
json_result.values["geometry"] = (routeParameters.geometry ? "yes" : "no");
@@ -65,7 +65,7 @@ class HelloWorldPlugin : public BasePlugin
json_result.values["jsonp_parameter"] = (!routeParameters.jsonp_parameter.empty() ? "yes" : "no");
json_result.values["language"] = (!routeParameters.language.empty() ? "yes" : "no");
temp_string = IntToString(routeParameters.coordinates.size());
temp_string = UintToString(static_cast<unsigned>(routeParameters.coordinates.size()));
json_result.values["location_count"] = temp_string;
JSON::Array json_locations;
@@ -77,7 +77,7 @@ class HelloWorldPlugin : public BasePlugin
json_coordinates.values.push_back(coordinate.lat / COORDINATE_PRECISION);
json_coordinates.values.push_back(coordinate.lon / COORDINATE_PRECISION);
json_location.values[IntToString(counter)] = json_coordinates;
json_location.values[UintToString(counter)] = json_coordinates;
json_locations.values.push_back(json_location);
++counter;
}
@@ -88,7 +88,6 @@ class HelloWorldPlugin : public BasePlugin
counter = 0;
for (const std::string &current_hint : routeParameters.hints)
{
// JSON::String json_hint_string = current_hint;
json_hints.values.push_back(current_hint);
++counter;
}
+14 -14
View File
@@ -31,7 +31,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "BasePlugin.h"
#include "../DataStructures/JSONContainer.h"
#include "../DataStructures/PhantomNodes.h"
#include "../Util/StringUtil.h"
#include <string>
@@ -42,28 +41,27 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
template <class DataFacadeT> class NearestPlugin : public BasePlugin
{
public:
explicit NearestPlugin(DataFacadeT *facade) : facade(facade), descriptor_string("nearest")
{
}
explicit NearestPlugin(DataFacadeT *facade) : facade(facade), descriptor_string("nearest") {}
const std::string GetDescriptor() const { return descriptor_string; }
void HandleRequest(const RouteParameters &route_parameters, http::Reply &reply)
{
// check number of parameters
if (route_parameters.coordinates.empty() ||
!route_parameters.coordinates.front().isValid())
if (route_parameters.coordinates.empty() || !route_parameters.coordinates.front().isValid())
{
reply = http::Reply::StockReply(http::Reply::badRequest);
return;
}
PhantomNode phantom_node;
facade->FindPhantomNodeForCoordinate(
route_parameters.coordinates.front(), phantom_node, route_parameters.zoom_level);
std::vector<PhantomNode> phantom_node_vector;
facade->IncrementalFindPhantomNodeForCoordinate(route_parameters.coordinates.front(),
phantom_node_vector,
route_parameters.zoom_level,
1);
JSON::Object json_result;
if (!phantom_node.isValid())
if (phantom_node_vector.empty() || !phantom_node_vector.front().isValid())
{
json_result.values["status"] = 207;
}
@@ -71,12 +69,14 @@ template <class DataFacadeT> class NearestPlugin : public BasePlugin
{
reply.status = http::Reply::ok;
json_result.values["status"] = 0;
JSON::Array json_coordinate;
json_coordinate.values.push_back(phantom_node.location.lat/COORDINATE_PRECISION);
json_coordinate.values.push_back(phantom_node.location.lon/COORDINATE_PRECISION);
JSON::Array json_coordinate;
json_coordinate.values.push_back(phantom_node_vector.front().location.lat /
COORDINATE_PRECISION);
json_coordinate.values.push_back(phantom_node_vector.front().location.lon /
COORDINATE_PRECISION);
json_result.values["mapped_coordinate"] = json_coordinate;
std::string temp_string;
facade->GetName(phantom_node.name_id, temp_string);
facade->GetName(phantom_node_vector.front().name_id, temp_string);
json_result.values["name"] = temp_string;
}
+1 -10
View File
@@ -118,7 +118,6 @@ template <class DataFacadeT> class ViaRoutePlugin : public BasePlugin
const bool is_alternate_requested = route_parameters.alternate_route;
const bool is_only_one_segment = (1 == raw_route.segment_end_coordinates.size());
TIMER_START(routing);
if (is_alternate_requested && is_only_one_segment)
{
search_engine_ptr->alternative_path(raw_route.segment_end_coordinates.front(),
@@ -128,8 +127,6 @@ template <class DataFacadeT> class ViaRoutePlugin : public BasePlugin
{
search_engine_ptr->shortest_path(raw_route.segment_end_coordinates, raw_route);
}
TIMER_STOP(routing);
SimpleLogger().Write() << "routing took " << TIMER_MSEC(routing) << "ms";
if (INVALID_EDGE_WEIGHT == raw_route.shortest_path_length)
{
@@ -164,14 +161,8 @@ template <class DataFacadeT> class ViaRoutePlugin : public BasePlugin
break;
}
PhantomNodes phantom_nodes;
phantom_nodes.source_phantom = raw_route.segment_end_coordinates.front().source_phantom;
phantom_nodes.target_phantom = raw_route.segment_end_coordinates.back().target_phantom;
descriptor->SetConfig(descriptor_config);
TIMER_START(descriptor);
descriptor->Run(raw_route, phantom_nodes, reply);
TIMER_STOP(descriptor);
SimpleLogger().Write() << "descriptor took " << TIMER_MSEC(descriptor) << "ms";
descriptor->Run(raw_route, reply);
}
private:
+20 -23
View File
@@ -76,12 +76,6 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
void operator()(const PhantomNodes &phantom_node_pair, RawRouteData &raw_route_data)
{
if (phantom_node_pair.PhantomNodesHaveEqualLocation())
{
BOOST_ASSERT(false);
return;
}
std::vector<NodeID> alternative_path;
std::vector<NodeID> via_node_candidate_list;
std::vector<SearchSpaceEdge> forward_search_space;
@@ -272,8 +266,8 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
int length_of_via_path = 0, sharing_of_via_path = 0;
ComputeLengthAndSharingOfViaPath(
node, &length_of_via_path, &sharing_of_via_path, packed_shortest_path);
const int maximum_allowed_sharing =
upper_bound_to_shortest_path_distance * VIAPATH_GAMMA;
const int maximum_allowed_sharing = static_cast<int>(
upper_bound_to_shortest_path_distance * VIAPATH_GAMMA);
if (sharing_of_via_path <= maximum_allowed_sharing &&
length_of_via_path <= upper_bound_to_shortest_path_distance * (1 + VIAPATH_EPSILON))
{
@@ -308,10 +302,10 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
{
BOOST_ASSERT(!packed_shortest_path.empty());
raw_route_data.unpacked_path_segments.resize(1);
raw_route_data.source_traversed_in_reverse =
(packed_shortest_path.front() != phantom_node_pair.source_phantom.forward_node_id);
raw_route_data.target_traversed_in_reverse =
(packed_shortest_path.back() != phantom_node_pair.target_phantom.forward_node_id);
raw_route_data.source_traversed_in_reverse.push_back(
(packed_shortest_path.front() != phantom_node_pair.source_phantom.forward_node_id));
raw_route_data.target_traversed_in_reverse.push_back(
(packed_shortest_path.back() != phantom_node_pair.target_phantom.forward_node_id));
super::UnpackPath(
// -- packed input
@@ -335,16 +329,18 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
v_t_middle,
packed_alternate_path);
raw_route_data.source_traversed_in_reverse =
(packed_alternate_path.front() != phantom_node_pair.source_phantom.forward_node_id);
raw_route_data.target_traversed_in_reverse =
(packed_alternate_path.back() != phantom_node_pair.target_phantom.forward_node_id);
raw_route_data.alt_source_traversed_in_reverse.push_back(
(packed_alternate_path.front() != phantom_node_pair.source_phantom.forward_node_id));
raw_route_data.alt_target_traversed_in_reverse.push_back(
(packed_alternate_path.back() != phantom_node_pair.target_phantom.forward_node_id));
// unpack the alternate path
super::UnpackPath(
packed_alternate_path, phantom_node_pair, raw_route_data.unpacked_alternative);
raw_route_data.alternative_path_length = length_of_via_path;
} else {
BOOST_ASSERT(raw_route_data.alternative_path_length == INVALID_EDGE_WEIGHT);
}
}
@@ -580,7 +576,7 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
{
const NodeID node = forward_heap.DeleteMin();
const int distance = forward_heap.GetKey(node);
const int scaled_distance = distance / (1. + VIAPATH_EPSILON);
const int scaled_distance = static_cast<int>(distance / (1. + VIAPATH_EPSILON));
if ((INVALID_EDGE_WEIGHT != *upper_bound_to_shortest_path_distance) &&
(scaled_distance > *upper_bound_to_shortest_path_distance))
{
@@ -642,7 +638,7 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
QueryHeap &new_forward_heap,
QueryHeap &new_reverse_heap,
const RankedCandidateNode &candidate,
const int lengthOfShortestPath,
const int length_of_shortest_path,
int *length_of_via_path,
NodeID *s_v_middle,
NodeID *v_t_middle) const
@@ -707,12 +703,12 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
{
return false;
}
const int T_threshold = VIAPATH_EPSILON * lengthOfShortestPath;
const int T_threshold = static_cast<int>(VIAPATH_EPSILON * length_of_shortest_path);
int unpacked_until_distance = 0;
std::stack<SearchSpaceEdge> unpack_stack;
// Traverse path s-->v
for (unsigned i = packed_s_v_path.size() - 1; (i > 0) && unpack_stack.empty(); --i)
for (std::size_t i = packed_s_v_path.size() - 1; (i > 0) && unpack_stack.empty(); --i)
{
const EdgeID current_edge_id =
facade->FindEdgeInEitherDirection(packed_s_v_path[i - 1], packed_s_v_path[i]);
@@ -773,11 +769,12 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
int t_test_path_length = unpacked_until_distance;
unpacked_until_distance = 0;
// Traverse path s-->v
for (unsigned i = 0, packed_path_length = packed_v_t_path.size() - 1;
BOOST_ASSERT(!packed_v_t_path.empty());
for (unsigned i = 0, packed_path_length = static_cast<unsigned>(packed_v_t_path.size() - 1);
(i < packed_path_length) && unpack_stack.empty();
++i)
{
EdgeID edgeID =
const EdgeID edgeID =
facade->FindEdgeInEitherDirection(packed_v_t_path[i], packed_v_t_path[i + 1]);
int length_of_current_edge = facade->GetEdgeData(edgeID).distance;
if (length_of_current_edge + unpacked_until_distance >= T_threshold)
@@ -842,7 +839,7 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
forward_heap3.Insert(s_P, 0, s_P);
reverse_heap3.Insert(t_P, 0, t_P);
// exploration from s and t until deletemin/(1+epsilon) > _lengthOfShortestPath
// exploration from s and t until deletemin/(1+epsilon) > _lengt_oO_sShortest_path
while ((forward_heap3.Size() + reverse_heap3.Size()) > 0)
{
if (!forward_heap3.Empty())
+17 -3
View File
@@ -146,7 +146,7 @@ template <class DataFacadeT> class BasicRoutingInterface
const bool target_traversed_in_reverse =
(packed_path.back() != phantom_node_pair.target_phantom.forward_node_id);
const unsigned packed_path_size = packed_path.size();
const unsigned packed_path_size = static_cast<unsigned>(packed_path.size());
std::stack<std::pair<NodeID, NodeID>> recursion_stack;
// We have to push the path in reverse order onto the stack because it's LIFO.
@@ -158,6 +158,13 @@ template <class DataFacadeT> class BasicRoutingInterface
std::pair<NodeID, NodeID> edge;
while (!recursion_stack.empty())
{
/*
Graphical representation of variables:
edge.first edge.second
*------------------>*
edge_id
*/
edge = recursion_stack.top();
recursion_stack.pop();
@@ -175,6 +182,14 @@ template <class DataFacadeT> class BasicRoutingInterface
edge_weight = weight;
}
}
/*
Graphical representation of variables:
edge.first edge.second
*<------------------*
edge_id
*/
if (SPECIAL_EDGEID == smaller_edge_id)
{
for (auto edge_id : facade->GetAdjacentEdgeRange(edge.second))
@@ -231,8 +246,7 @@ template <class DataFacadeT> class BasicRoutingInterface
BOOST_ASSERT(start_index <= end_index);
for (int i = start_index; i < end_index; ++i)
{
unpacked_path.emplace_back(PathData{
id_vector[i], name_index, TurnInstruction::NoTurn, 0});
unpacked_path.emplace_back(id_vector[i], name_index, TurnInstruction::NoTurn, 0);
}
unpacked_path.back().turn_instruction = turn_instruction;
unpacked_path.back().segment_duration = ed.distance;
+40 -22
View File
@@ -64,12 +64,13 @@ template <class DataFacadeT> class ManyToManyRouting : public BasicRoutingInterf
~ManyToManyRouting() {}
std::shared_ptr<std::vector<EdgeWeight>>
operator()(const std::vector<PhantomNode> &phantom_nodes_vector) const
std::shared_ptr<std::vector<EdgeWeight>> operator()(const PhantomNodeArray &phantom_nodes_array)
const
{
const unsigned number_of_locations = phantom_nodes_vector.size();
std::shared_ptr<std::vector<EdgeWeight>> result_table = std::make_shared<std::vector<EdgeWeight>>(
number_of_locations * number_of_locations, std::numeric_limits<EdgeWeight>::max());
const unsigned number_of_locations = static_cast<unsigned>(phantom_nodes_array.size());
std::shared_ptr<std::vector<EdgeWeight>> result_table =
std::make_shared<std::vector<EdgeWeight>>(number_of_locations * number_of_locations,
std::numeric_limits<EdgeWeight>::max());
engine_working_data.InitializeOrClearFirstThreadLocalStorage(
super::facade->GetNumberOfNodes());
@@ -79,17 +80,25 @@ template <class DataFacadeT> class ManyToManyRouting : public BasicRoutingInterf
SearchSpaceWithBuckets search_space_with_buckets;
unsigned target_id = 0;
for (const PhantomNode &phantom_node : phantom_nodes_vector)
for (const std::vector<PhantomNode> &phantom_node_vector : phantom_nodes_array)
{
query_heap.Clear();
// insert target(s) at distance 0
if (SPECIAL_NODEID != phantom_node.forward_node_id)
for (const PhantomNode &phantom_node : phantom_node_vector)
{
query_heap.Insert(phantom_node.forward_node_id, phantom_node.GetForwardWeightPlusOffset(), phantom_node.forward_node_id);
}
if (SPECIAL_NODEID != phantom_node.reverse_node_id)
{
query_heap.Insert(phantom_node.reverse_node_id, phantom_node.GetReverseWeightPlusOffset(), phantom_node.reverse_node_id);
if (SPECIAL_NODEID != phantom_node.forward_node_id)
{
query_heap.Insert(phantom_node.forward_node_id,
phantom_node.GetForwardWeightPlusOffset(),
phantom_node.forward_node_id);
}
if (SPECIAL_NODEID != phantom_node.reverse_node_id)
{
query_heap.Insert(phantom_node.reverse_node_id,
phantom_node.GetReverseWeightPlusOffset(),
phantom_node.reverse_node_id);
}
}
// explore search space
@@ -102,17 +111,24 @@ template <class DataFacadeT> class ManyToManyRouting : public BasicRoutingInterf
// for each source do forward search
unsigned source_id = 0;
for (const PhantomNode &phantom_node : phantom_nodes_vector)
for (const std::vector<PhantomNode> &phantom_node_vector : phantom_nodes_array)
{
query_heap.Clear();
// insert sources at distance 0
if (SPECIAL_NODEID != phantom_node.forward_node_id)
for (const PhantomNode &phantom_node : phantom_node_vector)
{
query_heap.Insert(phantom_node.forward_node_id, -phantom_node.GetForwardWeightPlusOffset(), phantom_node.forward_node_id);
}
if (SPECIAL_NODEID != phantom_node.reverse_node_id)
{
query_heap.Insert(phantom_node.reverse_node_id, -phantom_node.GetReverseWeightPlusOffset(), phantom_node.reverse_node_id);
// insert sources at distance 0
if (SPECIAL_NODEID != phantom_node.forward_node_id)
{
query_heap.Insert(phantom_node.forward_node_id,
-phantom_node.GetForwardWeightPlusOffset(),
phantom_node.forward_node_id);
}
if (SPECIAL_NODEID != phantom_node.reverse_node_id)
{
query_heap.Insert(phantom_node.reverse_node_id,
-phantom_node.GetReverseWeightPlusOffset(),
phantom_node.reverse_node_id);
}
}
// explore search space
@@ -154,7 +170,8 @@ template <class DataFacadeT> class ManyToManyRouting : public BasicRoutingInterf
const EdgeWeight current_distance =
(*result_table)[source_id * number_of_locations + target_id];
// check if new distance is better
if ((source_distance + target_distance) < current_distance)
const EdgeWeight new_distance = source_distance + target_distance;
if (new_distance >= 0 && new_distance < current_distance)
{
(*result_table)[source_id * number_of_locations + target_id] =
(source_distance + target_distance);
@@ -220,7 +237,8 @@ template <class DataFacadeT> class ManyToManyRouting : public BasicRoutingInterf
// Stalling
template <bool forward_direction>
inline bool StallAtNode(const NodeID node, const EdgeWeight distance, QueryHeap &query_heap) const
inline bool StallAtNode(const NodeID node, const EdgeWeight distance, QueryHeap &query_heap)
const
{
for (auto edge : super::facade->GetAdjacentEdgeRange(node))
{
+9 -17
View File
@@ -51,15 +51,6 @@ template <class DataFacadeT> class ShortestPathRouting : public BasicRoutingInte
void operator()(const std::vector<PhantomNodes> &phantom_nodes_vector,
RawRouteData &raw_route_data) const
{
if(std::any_of(begin(phantom_nodes_vector),
end(phantom_nodes_vector),
[](PhantomNodes phantom_node_pair)
{ return phantom_node_pair.AtLeastOnePhantomNodeIsInvalid(); }))
{
BOOST_ASSERT(false);
return;
}
int distance1 = 0;
int distance2 = 0;
bool search_from_1st_node = true;
@@ -176,6 +167,9 @@ template <class DataFacadeT> class ShortestPathRouting : public BasicRoutingInte
raw_route_data.alternative_path_length = INVALID_EDGE_WEIGHT;
return;
}
search_from_1st_node = true;
search_from_2nd_node = true;
if (SPECIAL_NODEID == middle1)
{
search_from_1st_node = false;
@@ -244,7 +238,7 @@ template <class DataFacadeT> class ShortestPathRouting : public BasicRoutingInte
}
}
// remove one path if both legs end at the same segment
// remove the shorter path if both legs end at the same segment
if (0 < current_leg)
{
const NodeID start_id_of_leg1 = temporary_packed_leg1.front();
@@ -298,13 +292,6 @@ template <class DataFacadeT> class ShortestPathRouting : public BasicRoutingInte
}
raw_route_data.unpacked_path_segments.resize(packed_legs1.size());
raw_route_data.source_traversed_in_reverse =
(packed_legs1.front().front() !=
phantom_nodes_vector.front().source_phantom.forward_node_id);
raw_route_data.target_traversed_in_reverse =
(packed_legs1.back().back() !=
phantom_nodes_vector.back().target_phantom.forward_node_id);
for (unsigned i = 0; i < packed_legs1.size(); ++i)
{
BOOST_ASSERT(!phantom_nodes_vector.empty());
@@ -318,6 +305,11 @@ template <class DataFacadeT> class ShortestPathRouting : public BasicRoutingInte
unpack_phantom_node_pair,
// -- unpacked output
raw_route_data.unpacked_path_segments[i]);
raw_route_data.source_traversed_in_reverse.push_back(
(packed_legs1[i].front() != phantom_nodes_vector[i].source_phantom.forward_node_id));
raw_route_data.target_traversed_in_reverse.push_back(
(packed_legs1[i].back() != phantom_nodes_vector[i].target_phantom.forward_node_id));
}
raw_route_data.shortest_path_length = std::min(distance1, distance2);
}
+80 -87
View File
@@ -41,13 +41,10 @@ namespace http
{
Connection::Connection(boost::asio::io_service &io_service, RequestHandler &handler)
: strand(io_service), TCP_socket(io_service), request_handler(handler),
request_parser(new RequestParser())
: strand(io_service), TCP_socket(io_service), request_handler(handler)
{
}
Connection::~Connection() { delete request_parser; }
boost::asio::ip::tcp::socket &Connection::socket() { return TCP_socket; }
/// Start the first asynchronous operation for the connection.
@@ -61,117 +58,113 @@ void Connection::start()
boost::asio::placeholders::bytes_transferred)));
}
void Connection::handle_read(const boost::system::error_code &e, std::size_t bytes_transferred)
void Connection::handle_read(const boost::system::error_code &error, std::size_t bytes_transferred)
{
if (!e)
if (error)
{
CompressionType compression_type(noCompression);
boost::tribool result;
boost::tie(result, boost::tuples::ignore) =
request_parser->Parse(request,
incoming_data_buffer.data(),
incoming_data_buffer.data() + bytes_transferred,
&compression_type);
return;
}
if (result)
// no error detected, let's parse the request
CompressionType compression_type(noCompression);
boost::tribool result;
boost::tie(result, boost::tuples::ignore) =
request_parser.Parse(request,
incoming_data_buffer.data(),
incoming_data_buffer.data() + bytes_transferred,
&compression_type);
// the request has been parsed
if (result)
{
request.endpoint = TCP_socket.remote_endpoint().address();
request_handler.handle_request(request, reply);
// Header compression_header;
std::vector<char> compressed_output;
std::vector<boost::asio::const_buffer> output_buffer;
// compress the result w/ gzip/deflate if requested
switch (compression_type)
{
request.endpoint = TCP_socket.remote_endpoint().address();
request_handler.handle_request(request, reply);
Header compression_header;
std::vector<char> compressed_output;
std::vector<boost::asio::const_buffer> output_buffer;
switch (compression_type)
{
case deflateRFC1951:
compression_header.name = "Content-Encoding";
compression_header.value = "deflate";
reply.headers.insert(reply.headers.begin(), compression_header);
compressBufferCollection(reply.content, compression_type, compressed_output);
reply.setSize(compressed_output.size());
output_buffer = reply.HeaderstoBuffers();
output_buffer.push_back(boost::asio::buffer(compressed_output));
boost::asio::async_write(
TCP_socket,
output_buffer,
strand.wrap(boost::bind(&Connection::handle_write,
this->shared_from_this(),
boost::asio::placeholders::error)));
break;
case gzipRFC1952:
compression_header.name = "Content-Encoding";
compression_header.value = "gzip";
reply.headers.insert(reply.headers.begin(), compression_header);
compressBufferCollection(reply.content, compression_type, compressed_output);
reply.setSize(compressed_output.size());
output_buffer = reply.HeaderstoBuffers();
output_buffer.push_back(boost::asio::buffer(compressed_output));
boost::asio::async_write(
TCP_socket,
output_buffer,
strand.wrap(boost::bind(&Connection::handle_write,
this->shared_from_this(),
boost::asio::placeholders::error)));
break;
case noCompression:
reply.SetUncompressedSize();
output_buffer = reply.toBuffers();
boost::asio::async_write(
TCP_socket,
output_buffer,
strand.wrap(boost::bind(&Connection::handle_write,
this->shared_from_this(),
boost::asio::placeholders::error)));
break;
}
case deflateRFC1951:
// use deflate for compression
reply.headers.insert(reply.headers.begin(), {"Content-Encoding", "deflate"});
CompressBufferCollection(reply.content, compression_type, compressed_output);
reply.SetSize(static_cast<unsigned>(compressed_output.size()));
output_buffer = reply.HeaderstoBuffers();
output_buffer.push_back(boost::asio::buffer(compressed_output));
break;
case gzipRFC1952:
// use gzip for compression
reply.headers.insert(reply.headers.begin(), {"Content-Encoding", "gzip"});
CompressBufferCollection(reply.content, compression_type, compressed_output);
reply.SetSize(static_cast<unsigned>(compressed_output.size()));
output_buffer = reply.HeaderstoBuffers();
output_buffer.push_back(boost::asio::buffer(compressed_output));
break;
case noCompression:
// don't use any compression
reply.SetUncompressedSize();
output_buffer = reply.ToBuffers();
break;
}
else if (!result)
{
reply = Reply::StockReply(Reply::badRequest);
// write result to stream
boost::asio::async_write(TCP_socket,
output_buffer,
strand.wrap(boost::bind(&Connection::handle_write,
this->shared_from_this(),
boost::asio::placeholders::error)));
}
else if (!result)
{ // request is not parseable
reply = Reply::StockReply(Reply::badRequest);
boost::asio::async_write(TCP_socket,
reply.toBuffers(),
strand.wrap(boost::bind(&Connection::handle_write,
this->shared_from_this(),
boost::asio::placeholders::error)));
}
else
{
TCP_socket.async_read_some(
boost::asio::buffer(incoming_data_buffer),
strand.wrap(boost::bind(&Connection::handle_read,
this->shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred)));
}
boost::asio::async_write(TCP_socket,
reply.ToBuffers(),
strand.wrap(boost::bind(&Connection::handle_write,
this->shared_from_this(),
boost::asio::placeholders::error)));
}
else
{
// we don't have a result yet, so continue reading
TCP_socket.async_read_some(
boost::asio::buffer(incoming_data_buffer),
strand.wrap(boost::bind(&Connection::handle_read,
this->shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred)));
}
}
/// Handle completion of a write operation.
void Connection::handle_write(const boost::system::error_code &e)
void Connection::handle_write(const boost::system::error_code &error)
{
if (!e)
if (!error)
{
// Initiate graceful connection closure.
boost::system::error_code ignoredEC;
TCP_socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignoredEC);
boost::system::error_code ignore_error;
TCP_socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignore_error);
}
}
void Connection::compressBufferCollection(std::vector<char> uncompressed_data,
void Connection::CompressBufferCollection(std::vector<char> uncompressed_data,
CompressionType compression_type,
std::vector<char> &compressed_data)
{
boost::iostreams::gzip_params compression_parameters;
// there's a trade-off between speed and size. speed wins
compression_parameters.level = boost::iostreams::zlib::best_speed;
// check which compression flavor is used
if (deflateRFC1951 == compression_type)
{
compression_parameters.noheader = true;
}
BOOST_ASSERT(compressed_data.empty());
// plug data into boost's compression stream
boost::iostreams::filtering_ostream gzip_stream;
gzip_stream.push(boost::iostreams::gzip_compressor(compression_parameters));
gzip_stream.push(boost::iostreams::back_inserter(compressed_data));
+4 -5
View File
@@ -28,6 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef CONNECTION_H
#define CONNECTION_H
#include "RequestParser.h"
#include "Http/CompressionType.h"
#include "Http/Request.h"
@@ -68,15 +69,13 @@ class RequestHandler;
namespace http
{
class RequestParser;
/// Represents a single connection from a client.
class Connection : public std::enable_shared_from_this<Connection>
{
public:
explicit Connection(boost::asio::io_service &io_service, RequestHandler &handler);
Connection(const Connection &) = delete;
~Connection();
Connection() = delete;
boost::asio::ip::tcp::socket &socket();
@@ -89,7 +88,7 @@ class Connection : public std::enable_shared_from_this<Connection>
/// Handle completion of a write operation.
void handle_write(const boost::system::error_code &e);
void compressBufferCollection(std::vector<char> uncompressed_data,
void CompressBufferCollection(std::vector<char> uncompressed_data,
CompressionType compression_type,
std::vector<char> &compressed_data);
@@ -98,7 +97,7 @@ class Connection : public std::enable_shared_from_this<Connection>
RequestHandler &request_handler;
boost::array<char, 8192> incoming_data_buffer;
Request request;
RequestParser *request_parser;
RequestParser request_parser;
Reply reply;
};
+5
View File
@@ -101,6 +101,11 @@ template <class EdgeDataT> class BaseDataFacade
PhantomNode &resulting_phantom_node,
const unsigned zoom_level) const = 0;
virtual bool IncrementalFindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
std::vector<PhantomNode> &resulting_phantom_node_vector,
const unsigned zoom_level,
const unsigned number_of_results) const = 0;
virtual unsigned GetCheckSum() const = 0;
virtual unsigned GetNameIndexFromEdgeID(const unsigned id) const = 0;
+43 -27
View File
@@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../../DataStructures/SharedMemoryVectorWrapper.h"
#include "../../DataStructures/StaticGraph.h"
#include "../../DataStructures/StaticRTree.h"
#include "../../DataStructures/RangeTable.h"
#include "../../Util/BoostFileSystemFix.h"
#include "../../Util/GraphLoader.h"
#include "../../Util/ProgramOptions.h"
@@ -66,13 +67,13 @@ template <class EdgeDataT> class InternalDataFacade : public BaseDataFacade<Edge
ShM<unsigned, false>::vector m_name_ID_list;
ShM<TurnInstruction, false>::vector m_turn_instruction_list;
ShM<char, false>::vector m_names_char_list;
ShM<unsigned, false>::vector m_name_begin_indices;
ShM<bool, false>::vector m_egde_is_compressed;
ShM<unsigned, false>::vector m_geometry_indices;
ShM<unsigned, false>::vector m_geometry_list;
std::shared_ptr<StaticRTree<RTreeLeaf, ShM<FixedPointCoordinate, false>::vector, false>>
m_static_rtree;
RangeTable<16, false> m_name_table;
void LoadTimestamp(const boost::filesystem::path &timestamp_path)
{
@@ -165,23 +166,29 @@ template <class EdgeDataT> class InternalDataFacade : public BaseDataFacade<Edge
void LoadGeometries(const boost::filesystem::path &geometry_file)
{
std::ifstream geometry_stream(geometry_file.c_str(), std::ios::binary);
std::ifstream geometry_stream(geometry_file.string().c_str(), std::ios::binary);
unsigned number_of_indices = 0;
unsigned number_of_compressed_geometries = 0;
geometry_stream.read((char *)&number_of_indices, sizeof(unsigned));
m_geometry_indices.resize(number_of_indices);
geometry_stream.read((char *)&(m_geometry_indices[0]),
number_of_indices * sizeof(unsigned));
if (number_of_indices > 0)
{
geometry_stream.read((char *)&(m_geometry_indices[0]),
number_of_indices * sizeof(unsigned));
}
geometry_stream.read((char *)&number_of_compressed_geometries, sizeof(unsigned));
BOOST_ASSERT(m_geometry_indices.back() == number_of_compressed_geometries);
m_geometry_list.resize(number_of_compressed_geometries);
geometry_stream.read((char *)&(m_geometry_list[0]),
number_of_compressed_geometries * sizeof(unsigned));
if (number_of_compressed_geometries > 0)
{
geometry_stream.read((char *)&(m_geometry_list[0]),
number_of_compressed_geometries * sizeof(unsigned));
}
geometry_stream.close();
}
@@ -197,19 +204,18 @@ template <class EdgeDataT> class InternalDataFacade : public BaseDataFacade<Edge
void LoadStreetNames(const boost::filesystem::path &names_file)
{
boost::filesystem::ifstream name_stream(names_file, std::ios::binary);
unsigned number_of_names = 0;
name_stream >> m_name_table;
unsigned number_of_chars = 0;
name_stream.read((char *)&number_of_names, sizeof(unsigned));
name_stream.read((char *)&number_of_chars, sizeof(unsigned));
BOOST_ASSERT_MSG(0 != number_of_names, "name file broken");
BOOST_ASSERT_MSG(0 != number_of_chars, "name file broken");
m_name_begin_indices.resize(number_of_names);
name_stream.read((char *)&m_name_begin_indices[0], number_of_names * sizeof(unsigned));
m_names_char_list.resize(number_of_chars + 1); //+1 gives sentinel element
name_stream.read((char *)&m_names_char_list[0], number_of_chars * sizeof(char));
BOOST_ASSERT_MSG(0 != m_names_char_list.size(), "could not load any names");
if (0 == m_names_char_list.size())
{
SimpleLogger().Write(logWARNING) << "list of street names is empty";
}
name_stream.close();
}
@@ -316,7 +322,10 @@ template <class EdgeDataT> class InternalDataFacade : public BaseDataFacade<Edge
EdgeID EndEdges(const NodeID n) const { return m_query_graph->EndEdges(n); }
EdgeRange GetAdjacentEdgeRange(const NodeID node) const { return m_query_graph->GetAdjacentEdgeRange(node); };
EdgeRange GetAdjacentEdgeRange(const NodeID node) const
{
return m_query_graph->GetAdjacentEdgeRange(node);
};
// searches for a specific edge
EdgeID FindEdge(const NodeID from, const NodeID to) const
@@ -359,9 +368,18 @@ template <class EdgeDataT> class InternalDataFacade : public BaseDataFacade<Edge
PhantomNode &resulting_phantom_node,
const unsigned zoom_level) const
{
const bool found = m_static_rtree->FindPhantomNodeForCoordinate(
return m_static_rtree->FindPhantomNodeForCoordinate(
input_coordinate, resulting_phantom_node, zoom_level);
return found;
}
bool
IncrementalFindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
std::vector<PhantomNode> &resulting_phantom_node_vector,
const unsigned zoom_level,
const unsigned number_of_results) const
{
return m_static_rtree->IncrementalFindPhantomNodeForCoordinate(
input_coordinate, resulting_phantom_node_vector, zoom_level, number_of_results);
}
unsigned GetCheckSum() const { return m_check_sum; }
@@ -378,18 +396,16 @@ template <class EdgeDataT> class InternalDataFacade : public BaseDataFacade<Edge
result = "";
return;
}
BOOST_ASSERT_MSG(name_id < m_name_begin_indices.size(), "name id too high");
const unsigned begin_index = m_name_begin_indices[name_id];
const unsigned end_index = m_name_begin_indices[name_id + 1];
BOOST_ASSERT_MSG(begin_index < m_names_char_list.size(), "begin index of name too high");
BOOST_ASSERT_MSG(end_index < m_names_char_list.size(), "end index of name too high");
auto range = m_name_table.GetRange(name_id);
BOOST_ASSERT_MSG(begin_index <= end_index, "string ends before begin");
result.clear();
result.resize(end_index - begin_index);
std::copy(m_names_char_list.begin() + begin_index,
m_names_char_list.begin() + end_index,
result.begin());
if (range.begin() != range.end())
{
result.resize(range.back() - range.front() + 1);
std::copy(m_names_char_list.begin() + range.front(),
m_names_char_list.begin() + range.back() + 1,
result.begin());
}
}
virtual unsigned GetGeometryIndexForEdgeID(const unsigned id) const
+108 -62
View File
@@ -33,6 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "BaseDataFacade.h"
#include "SharedDataType.h"
#include "../../DataStructures/RangeTable.h"
#include "../../DataStructures/StaticGraph.h"
#include "../../DataStructures/StaticRTree.h"
#include "../../Util/BoostFileSystemFix.h"
@@ -51,6 +52,7 @@ template <class EdgeDataT> class SharedDataFacade : public BaseDataFacade<EdgeDa
typedef StaticGraph<EdgeData, true> QueryGraph;
typedef typename StaticGraph<EdgeData, true>::NodeArrayEntry GraphNode;
typedef typename StaticGraph<EdgeData, true>::EdgeArrayEntry GraphEdge;
typedef typename RangeTable<16, true>::BlockT NameIndexBlock;
typedef typename QueryGraph::InputEdge InputEdge;
typedef typename super::RTreeLeaf RTreeLeaf;
typedef typename StaticRTree<RTreeLeaf, ShM<FixedPointCoordinate, true>::vector, true>::TreeNode
@@ -84,101 +86,126 @@ template <class EdgeDataT> class SharedDataFacade : public BaseDataFacade<EdgeDa
std::shared_ptr<StaticRTree<RTreeLeaf, ShM<FixedPointCoordinate, true>::vector, true>>
m_static_rtree;
std::shared_ptr<RangeTable<16, true>> m_name_table;
void LoadChecksum()
{
m_check_sum =
*data_layout->GetBlockPtr<unsigned>(shared_memory, SharedDataLayout::HSGR_CHECKSUM);
SimpleLogger().Write() << "set checksum: " << m_check_sum;
}
void LoadTimestamp()
{
char *timestamp_ptr = shared_memory + data_layout->GetTimeStampOffset();
m_timestamp.resize(data_layout->timestamp_length);
std::copy(
timestamp_ptr, timestamp_ptr + data_layout->timestamp_length, m_timestamp.begin());
char *timestamp_ptr =
data_layout->GetBlockPtr<char>(shared_memory, SharedDataLayout::TIMESTAMP);
m_timestamp.resize(data_layout->GetBlockSize(SharedDataLayout::TIMESTAMP));
std::copy(timestamp_ptr,
timestamp_ptr + data_layout->GetBlockSize(SharedDataLayout::TIMESTAMP),
m_timestamp.begin());
}
void LoadRTree(const boost::filesystem::path &file_index_path)
{
BOOST_ASSERT_MSG(!m_coordinate_list->empty(), "coordinates must be loaded before r-tree");
RTreeNode *tree_ptr = (RTreeNode *)(shared_memory + data_layout->GetRSearchTreeOffset());
RTreeNode *tree_ptr =
data_layout->GetBlockPtr<RTreeNode>(shared_memory, SharedDataLayout::R_SEARCH_TREE);
m_static_rtree =
std::make_shared<StaticRTree<RTreeLeaf, ShM<FixedPointCoordinate, true>::vector, true>>(
tree_ptr, data_layout->r_search_tree_size, file_index_path, m_coordinate_list);
tree_ptr,
data_layout->num_entries[SharedDataLayout::R_SEARCH_TREE],
file_index_path,
m_coordinate_list);
}
void LoadGraph()
{
m_number_of_nodes = data_layout->graph_node_list_size;
m_number_of_nodes = data_layout->num_entries[SharedDataLayout::GRAPH_NODE_LIST];
GraphNode *graph_nodes_ptr =
(GraphNode *)(shared_memory + data_layout->GetGraphNodeListOffset());
data_layout->GetBlockPtr<GraphNode>(shared_memory, SharedDataLayout::GRAPH_NODE_LIST);
GraphEdge *graph_edges_ptr =
(GraphEdge *)(shared_memory + data_layout->GetGraphEdgeListOffset());
data_layout->GetBlockPtr<GraphEdge>(shared_memory, SharedDataLayout::GRAPH_EDGE_LIST);
typename ShM<GraphNode, true>::vector node_list(graph_nodes_ptr,
data_layout->graph_node_list_size);
typename ShM<GraphEdge, true>::vector edge_list(graph_edges_ptr,
data_layout->graph_edge_list_size);
typename ShM<GraphNode, true>::vector node_list(
graph_nodes_ptr, data_layout->num_entries[SharedDataLayout::GRAPH_NODE_LIST]);
typename ShM<GraphEdge, true>::vector edge_list(
graph_edges_ptr, data_layout->num_entries[SharedDataLayout::GRAPH_EDGE_LIST]);
m_query_graph.reset(new QueryGraph(node_list, edge_list));
}
void LoadNodeAndEdgeInformation()
{
FixedPointCoordinate *coordinate_list_ptr =
(FixedPointCoordinate *)(shared_memory + data_layout->GetCoordinateListOffset());
FixedPointCoordinate *coordinate_list_ptr = data_layout->GetBlockPtr<FixedPointCoordinate>(
shared_memory, SharedDataLayout::COORDINATE_LIST);
m_coordinate_list = std::make_shared<ShM<FixedPointCoordinate, true>::vector>(
coordinate_list_ptr, data_layout->coordinate_list_size);
coordinate_list_ptr, data_layout->num_entries[SharedDataLayout::COORDINATE_LIST]);
TurnInstruction *turn_instruction_list_ptr =
(TurnInstruction *)(shared_memory + data_layout->GetTurnInstructionListOffset());
TurnInstruction *turn_instruction_list_ptr = data_layout->GetBlockPtr<TurnInstruction>(
shared_memory, SharedDataLayout::TURN_INSTRUCTION);
typename ShM<TurnInstruction, true>::vector turn_instruction_list(
turn_instruction_list_ptr, data_layout->turn_instruction_list_size);
turn_instruction_list_ptr,
data_layout->num_entries[SharedDataLayout::TURN_INSTRUCTION]);
m_turn_instruction_list.swap(turn_instruction_list);
unsigned *name_id_list_ptr =
(unsigned *)(shared_memory + data_layout->GetNameIDListOffset());
typename ShM<unsigned, true>::vector name_id_list(name_id_list_ptr,
data_layout->name_id_list_size);
data_layout->GetBlockPtr<unsigned>(shared_memory, SharedDataLayout::NAME_ID_LIST);
typename ShM<unsigned, true>::vector name_id_list(
name_id_list_ptr, data_layout->num_entries[SharedDataLayout::NAME_ID_LIST]);
m_name_ID_list.swap(name_id_list);
}
void LoadViaNodeList()
{
NodeID *via_node_list_ptr = (NodeID *)(shared_memory + data_layout->GetViaNodeListOffset());
typename ShM<NodeID, true>::vector via_node_list(via_node_list_ptr,
data_layout->via_node_list_size);
NodeID *via_node_list_ptr =
data_layout->GetBlockPtr<NodeID>(shared_memory, SharedDataLayout::VIA_NODE_LIST);
typename ShM<NodeID, true>::vector via_node_list(
via_node_list_ptr, data_layout->num_entries[SharedDataLayout::VIA_NODE_LIST]);
m_via_node_list.swap(via_node_list);
}
void LoadNames()
{
unsigned *street_names_index_ptr =
(unsigned *)(shared_memory + data_layout->GetNameIndexOffset());
typename ShM<unsigned, true>::vector name_begin_indices(street_names_index_ptr,
data_layout->name_index_list_size);
m_name_begin_indices.swap(name_begin_indices);
unsigned *offsets_ptr =
data_layout->GetBlockPtr<unsigned>(shared_memory, SharedDataLayout::NAME_OFFSETS);
NameIndexBlock *blocks_ptr =
data_layout->GetBlockPtr<NameIndexBlock>(shared_memory, SharedDataLayout::NAME_BLOCKS);
typename ShM<unsigned, true>::vector name_offsets(
offsets_ptr, data_layout->num_entries[SharedDataLayout::NAME_OFFSETS]);
typename ShM<NameIndexBlock, true>::vector name_blocks(
blocks_ptr, data_layout->num_entries[SharedDataLayout::NAME_BLOCKS]);
char *names_list_ptr =
data_layout->GetBlockPtr<char>(shared_memory, SharedDataLayout::NAME_CHAR_LIST);
typename ShM<char, true>::vector names_char_list(
names_list_ptr, data_layout->num_entries[SharedDataLayout::NAME_CHAR_LIST]);
m_name_table = std::make_shared<RangeTable<16, true>>(
name_offsets, name_blocks, names_char_list.size());
char *names_list_ptr = (char *)(shared_memory + data_layout->GetNameListOffset());
typename ShM<char, true>::vector names_char_list(names_list_ptr,
data_layout->name_char_list_size);
m_names_char_list.swap(names_char_list);
}
void LoadGeometries()
{
unsigned *geometries_compressed_ptr =
(unsigned *)(shared_memory + data_layout->GetGeometriesIndicatorOffset());
typename ShM<bool, true>::vector egde_is_compressed(geometries_compressed_ptr,
data_layout->geometries_indicators);
unsigned *geometries_compressed_ptr = data_layout->GetBlockPtr<unsigned>(
shared_memory, SharedDataLayout::GEOMETRIES_INDICATORS);
typename ShM<bool, true>::vector egde_is_compressed(
geometries_compressed_ptr,
data_layout->num_entries[SharedDataLayout::GEOMETRIES_INDICATORS]);
m_egde_is_compressed.swap(egde_is_compressed);
unsigned *geometries_index_ptr =
(unsigned *)(shared_memory + data_layout->GetGeometriesIndexListOffset());
data_layout->GetBlockPtr<unsigned>(shared_memory, SharedDataLayout::GEOMETRIES_INDEX);
typename ShM<unsigned, true>::vector geometry_begin_indices(
geometries_index_ptr, data_layout->geometries_index_list_size);
geometries_index_ptr, data_layout->num_entries[SharedDataLayout::GEOMETRIES_INDEX]);
m_geometry_indices.swap(geometry_begin_indices);
unsigned *geometries_list_ptr =
(unsigned *)(shared_memory + data_layout->GetGeometryListOffset());
typename ShM<unsigned, true>::vector geometry_list(geometries_list_ptr,
data_layout->geometries_list_size);
data_layout->GetBlockPtr<unsigned>(shared_memory, SharedDataLayout::GEOMETRIES_LIST);
typename ShM<unsigned, true>::vector geometry_list(
geometries_list_ptr, data_layout->num_entries[SharedDataLayout::GEOMETRIES_LIST]);
m_geometry_list.swap(geometry_list);
}
@@ -213,20 +240,29 @@ template <class EdgeDataT> class SharedDataFacade : public BaseDataFacade<EdgeDa
m_layout_memory.reset(SharedMemoryFactory::Get(CURRENT_LAYOUT));
data_layout = (SharedDataLayout *)(m_layout_memory->Ptr());
boost::filesystem::path ram_index_path(data_layout->ram_index_file_name);
if (!boost::filesystem::exists(ram_index_path))
{
throw OSRMException("no leaf index file given. "
"Is any data loaded into shared memory?");
}
m_large_memory.reset(SharedMemoryFactory::Get(CURRENT_DATA));
shared_memory = (char *)(m_large_memory->Ptr());
std::ofstream out("debug.bin");
out.write(shared_memory, data_layout->GetSizeOfLayout());
out.close();
const char *file_index_ptr =
data_layout->GetBlockPtr<char>(shared_memory, SharedDataLayout::FILE_INDEX_PATH);
boost::filesystem::path file_index_path(file_index_ptr);
if (!boost::filesystem::exists(file_index_path))
{
SimpleLogger().Write(logDEBUG) << "Leaf file name " << file_index_path.string();
throw OSRMException("Could not load leaf index file."
"Is any data loaded into shared memory?");
}
LoadGraph();
LoadChecksum();
LoadNodeAndEdgeInformation();
LoadGeometries();
LoadRTree(ram_index_path);
LoadRTree(file_index_path);
LoadTimestamp();
LoadViaNodeList();
LoadNames();
@@ -254,7 +290,10 @@ template <class EdgeDataT> class SharedDataFacade : public BaseDataFacade<EdgeDa
EdgeID EndEdges(const NodeID n) const { return m_query_graph->EndEdges(n); }
EdgeRange GetAdjacentEdgeRange(const NodeID node) const { return m_query_graph->GetAdjacentEdgeRange(node); };
EdgeRange GetAdjacentEdgeRange(const NodeID node) const
{
return m_query_graph->GetAdjacentEdgeRange(node);
};
// searches for a specific edge
EdgeID FindEdge(const NodeID from, const NodeID to) const
@@ -313,9 +352,18 @@ template <class EdgeDataT> class SharedDataFacade : public BaseDataFacade<EdgeDa
PhantomNode &resulting_phantom_node,
const unsigned zoom_level) const
{
const bool found = m_static_rtree->FindPhantomNodeForCoordinate(
return m_static_rtree->FindPhantomNodeForCoordinate(
input_coordinate, resulting_phantom_node, zoom_level);
return found;
}
bool
IncrementalFindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
std::vector<PhantomNode> &resulting_phantom_node_vector,
const unsigned zoom_level,
const unsigned number_of_results) const
{
return m_static_rtree->IncrementalFindPhantomNodeForCoordinate(
input_coordinate, resulting_phantom_node_vector, zoom_level, number_of_results);
}
unsigned GetCheckSum() const { return m_check_sum; }
@@ -332,18 +380,16 @@ template <class EdgeDataT> class SharedDataFacade : public BaseDataFacade<EdgeDa
result = "";
return;
}
BOOST_ASSERT_MSG(name_id < m_name_begin_indices.size(), "name id too high");
const unsigned begin_index = m_name_begin_indices[name_id];
const unsigned end_index = m_name_begin_indices[name_id + 1];
BOOST_ASSERT_MSG(begin_index <= m_names_char_list.size(), "begin index of name too high");
BOOST_ASSERT_MSG(end_index <= m_names_char_list.size(), "end index of name too high");
auto range = m_name_table->GetRange(name_id);
BOOST_ASSERT_MSG(begin_index <= end_index, "string ends before begin");
result.clear();
result.resize(end_index - begin_index);
std::copy(m_names_char_list.begin() + begin_index,
m_names_char_list.begin() + end_index,
result.begin());
if (range.begin() != range.end())
{
result.resize(range.back() - range.front() + 1);
std::copy(m_names_char_list.begin() + range.front(),
m_names_char_list.begin() + range.back() + 1,
result.begin());
}
}
std::string GetTimestamp() const { return m_timestamp; }
+117 -200
View File
@@ -28,229 +28,146 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef SHARED_DATA_TYPE_H_
#define SHARED_DATA_TYPE_H_
#include "BaseDataFacade.h"
#include "../../DataStructures/QueryEdge.h"
#include "../../DataStructures/StaticGraph.h"
#include "../../DataStructures/StaticRTree.h"
#include "../../DataStructures/TurnInstructions.h"
#include "../../typedefs.h"
#include <osrm/Coordinate.h>
#include "../../Util/OSRMException.h"
#include "../../Util/SimpleLogger.h"
#include <cstdint>
typedef BaseDataFacade<QueryEdge::EdgeData>::RTreeLeaf RTreeLeaf;
typedef StaticRTree<RTreeLeaf, ShM<FixedPointCoordinate, true>::vector, true>::TreeNode RTreeNode;
typedef StaticGraph<QueryEdge::EdgeData> QueryGraph;
#include <array>
// Added at the start and end of each block as sanity check
constexpr char CANARY[] = "OSRM";
struct SharedDataLayout
{
uint64_t name_index_list_size;
uint64_t name_char_list_size;
uint64_t name_id_list_size;
uint64_t via_node_list_size;
uint64_t graph_node_list_size;
uint64_t graph_edge_list_size;
uint64_t coordinate_list_size;
uint64_t turn_instruction_list_size;
uint64_t r_search_tree_size;
uint64_t geometries_index_list_size;
uint64_t geometries_list_size;
uint64_t geometries_indicators;
enum BlockID {
NAME_OFFSETS = 0,
NAME_BLOCKS,
NAME_CHAR_LIST,
NAME_ID_LIST,
VIA_NODE_LIST,
GRAPH_NODE_LIST,
GRAPH_EDGE_LIST,
COORDINATE_LIST,
TURN_INSTRUCTION,
R_SEARCH_TREE,
GEOMETRIES_INDEX,
GEOMETRIES_LIST,
GEOMETRIES_INDICATORS,
HSGR_CHECKSUM,
TIMESTAMP,
FILE_INDEX_PATH,
NUM_BLOCKS
};
unsigned checksum;
unsigned timestamp_length;
char ram_index_file_name[1024];
std::array<uint64_t, NUM_BLOCKS> num_entries;
std::array<uint64_t, NUM_BLOCKS> entry_size;
SharedDataLayout()
: name_index_list_size(0), name_char_list_size(0), name_id_list_size(0),
via_node_list_size(0), graph_node_list_size(0), graph_edge_list_size(0),
coordinate_list_size(0), turn_instruction_list_size(0), r_search_tree_size(0),
geometries_index_list_size(0), geometries_list_size(0), geometries_indicators(0),
checksum(0), timestamp_length(0)
: num_entries()
, entry_size()
{
ram_index_file_name[0] = '\0';
}
void PrintInformation() const
{
SimpleLogger().Write(logDEBUG) << "-";
SimpleLogger().Write(logDEBUG) << "name_index_list_size: " << name_index_list_size;
SimpleLogger().Write(logDEBUG) << "name_char_list_size: " << name_char_list_size;
SimpleLogger().Write(logDEBUG) << "name_id_list_size: " << name_id_list_size;
SimpleLogger().Write(logDEBUG) << "via_node_list_size: " << via_node_list_size;
SimpleLogger().Write(logDEBUG) << "graph_node_list_size: " << graph_node_list_size;
SimpleLogger().Write(logDEBUG) << "graph_edge_list_size: " << graph_edge_list_size;
SimpleLogger().Write(logDEBUG) << "timestamp_length: " << timestamp_length;
SimpleLogger().Write(logDEBUG) << "coordinate_list_size: " << coordinate_list_size;
SimpleLogger().Write(logDEBUG)
<< "turn_instruction_list_size: " << turn_instruction_list_size;
SimpleLogger().Write(logDEBUG) << "r_search_tree_size: " << r_search_tree_size;
SimpleLogger().Write(logDEBUG) << "geometries_indicators: " << geometries_indicators
<< "/" << ((geometries_indicators / 8) + 1);
SimpleLogger().Write(logDEBUG)
<< "geometries_index_list_size: " << geometries_index_list_size;
SimpleLogger().Write(logDEBUG) << "geometries_list_size: " << geometries_list_size;
SimpleLogger().Write(logDEBUG) << "sizeof(checksum): " << sizeof(checksum);
SimpleLogger().Write(logDEBUG) << "ram index file name: " << ram_index_file_name;
SimpleLogger().Write(logDEBUG) << "name_offsets_size: " << num_entries[NAME_OFFSETS];
SimpleLogger().Write(logDEBUG) << "name_blocks_size: " << num_entries[NAME_BLOCKS];
SimpleLogger().Write(logDEBUG) << "name_char_list_size: " << num_entries[NAME_CHAR_LIST];
SimpleLogger().Write(logDEBUG) << "name_id_list_size: " << num_entries[NAME_ID_LIST];
SimpleLogger().Write(logDEBUG) << "via_node_list_size: " << num_entries[VIA_NODE_LIST];
SimpleLogger().Write(logDEBUG) << "graph_node_list_size: " << num_entries[GRAPH_NODE_LIST];
SimpleLogger().Write(logDEBUG) << "graph_edge_list_size: " << num_entries[GRAPH_EDGE_LIST];
SimpleLogger().Write(logDEBUG) << "timestamp_length: " << num_entries[TIMESTAMP];
SimpleLogger().Write(logDEBUG) << "coordinate_list_size: " << num_entries[COORDINATE_LIST];
SimpleLogger().Write(logDEBUG) << "turn_instruction_list_size: " << num_entries[TURN_INSTRUCTION];
SimpleLogger().Write(logDEBUG) << "r_search_tree_size: " << num_entries[R_SEARCH_TREE];
SimpleLogger().Write(logDEBUG) << "geometries_indicators: " << num_entries[GEOMETRIES_INDICATORS]
<< "/" << ((num_entries[GEOMETRIES_INDICATORS] / 8) + 1);
SimpleLogger().Write(logDEBUG) << "geometries_index_list_size: " << num_entries[GEOMETRIES_INDEX];
SimpleLogger().Write(logDEBUG) << "geometries_list_size: " << num_entries[GEOMETRIES_LIST];
SimpleLogger().Write(logDEBUG) << "sizeof(checksum): " << entry_size[HSGR_CHECKSUM];
SimpleLogger().Write(logDEBUG) << "NAME_OFFSETS " << ": " << GetBlockSize(NAME_OFFSETS );
SimpleLogger().Write(logDEBUG) << "NAME_BLOCKS " << ": " << GetBlockSize(NAME_BLOCKS );
SimpleLogger().Write(logDEBUG) << "NAME_CHAR_LIST " << ": " << GetBlockSize(NAME_CHAR_LIST );
SimpleLogger().Write(logDEBUG) << "NAME_ID_LIST " << ": " << GetBlockSize(NAME_ID_LIST );
SimpleLogger().Write(logDEBUG) << "VIA_NODE_LIST " << ": " << GetBlockSize(VIA_NODE_LIST );
SimpleLogger().Write(logDEBUG) << "GRAPH_NODE_LIST " << ": " << GetBlockSize(GRAPH_NODE_LIST );
SimpleLogger().Write(logDEBUG) << "GRAPH_EDGE_LIST " << ": " << GetBlockSize(GRAPH_EDGE_LIST );
SimpleLogger().Write(logDEBUG) << "COORDINATE_LIST " << ": " << GetBlockSize(COORDINATE_LIST );
SimpleLogger().Write(logDEBUG) << "TURN_INSTRUCTION " << ": " << GetBlockSize(TURN_INSTRUCTION );
SimpleLogger().Write(logDEBUG) << "R_SEARCH_TREE " << ": " << GetBlockSize(R_SEARCH_TREE );
SimpleLogger().Write(logDEBUG) << "GEOMETRIES_INDEX " << ": " << GetBlockSize(GEOMETRIES_INDEX );
SimpleLogger().Write(logDEBUG) << "GEOMETRIES_LIST " << ": " << GetBlockSize(GEOMETRIES_LIST );
SimpleLogger().Write(logDEBUG) << "GEOMETRIES_INDICATORS" << ": " << GetBlockSize(GEOMETRIES_INDICATORS);
SimpleLogger().Write(logDEBUG) << "HSGR_CHECKSUM " << ": " << GetBlockSize(HSGR_CHECKSUM );
SimpleLogger().Write(logDEBUG) << "TIMESTAMP " << ": " << GetBlockSize(TIMESTAMP );
SimpleLogger().Write(logDEBUG) << "FILE_INDEX_PATH " << ": " << GetBlockSize(FILE_INDEX_PATH );
}
uint64_t GetSizeOfLayout() const
template<typename T>
inline void SetBlockSize(BlockID bid, uint64_t entries)
{
uint64_t result =
(name_index_list_size * sizeof(unsigned)) + (name_char_list_size * sizeof(char)) +
(name_id_list_size * sizeof(unsigned)) + (via_node_list_size * sizeof(NodeID)) +
(graph_node_list_size * sizeof(QueryGraph::NodeArrayEntry)) +
(graph_edge_list_size * sizeof(QueryGraph::EdgeArrayEntry)) +
(timestamp_length * sizeof(char)) +
(coordinate_list_size * sizeof(FixedPointCoordinate)) +
(turn_instruction_list_size * sizeof(TurnInstructionsClass)) +
(r_search_tree_size * sizeof(RTreeNode)) +
(geometries_indicators / 32 + 1) * sizeof(unsigned) +
(geometries_index_list_size * sizeof(unsigned)) +
(geometries_list_size * sizeof(unsigned)) + sizeof(checksum) + 1024 * sizeof(char);
num_entries[bid] = entries;
entry_size[bid] = sizeof(T);
}
inline uint64_t GetBlockSize(BlockID bid) const
{
// special encoding
if (bid == GEOMETRIES_INDICATORS)
{
return (num_entries[GEOMETRIES_INDICATORS]/32 + 1) * entry_size[GEOMETRIES_INDICATORS];
}
return num_entries[bid] * entry_size[bid];
}
inline uint64_t GetSizeOfLayout() const
{
return GetBlockOffset(NUM_BLOCKS) + NUM_BLOCKS*2*sizeof(CANARY);
}
inline uint64_t GetBlockOffset(BlockID bid) const
{
uint64_t result = sizeof(CANARY);
for (auto i = 0; i < bid; i++)
{
result += GetBlockSize((BlockID) i) + 2*sizeof(CANARY);
}
return result;
}
uint64_t GetNameIndexOffset() const { return 0; }
uint64_t GetNameListOffset() const
template<typename T, bool WRITE_CANARY=false>
inline T* GetBlockPtr(char* shared_memory, BlockID bid)
{
uint64_t result = (name_index_list_size * sizeof(unsigned));
return result;
}
uint64_t GetNameIDListOffset() const
{
uint64_t result =
(name_index_list_size * sizeof(unsigned)) + (name_char_list_size * sizeof(char));
return result;
}
uint64_t GetViaNodeListOffset() const
{
uint64_t result = (name_index_list_size * sizeof(unsigned)) +
(name_char_list_size * sizeof(char)) +
(name_id_list_size * sizeof(unsigned));
return result;
}
uint64_t GetGraphNodeListOffset() const
{
uint64_t result =
(name_index_list_size * sizeof(unsigned)) + (name_char_list_size * sizeof(char)) +
(name_id_list_size * sizeof(unsigned)) + (via_node_list_size * sizeof(NodeID));
return result;
}
uint64_t GetGraphEdgeListOffset() const
{
uint64_t result =
(name_index_list_size * sizeof(unsigned)) + (name_char_list_size * sizeof(char)) +
(name_id_list_size * sizeof(unsigned)) + (via_node_list_size * sizeof(NodeID)) +
(graph_node_list_size * sizeof(QueryGraph::NodeArrayEntry));
return result;
}
uint64_t GetTimeStampOffset() const
{
uint64_t result =
(name_index_list_size * sizeof(unsigned)) + (name_char_list_size * sizeof(char)) +
(name_id_list_size * sizeof(unsigned)) + (via_node_list_size * sizeof(NodeID)) +
(graph_node_list_size * sizeof(QueryGraph::NodeArrayEntry)) +
(graph_edge_list_size * sizeof(QueryGraph::EdgeArrayEntry));
return result;
}
uint64_t GetCoordinateListOffset() const
{
uint64_t result =
(name_index_list_size * sizeof(unsigned)) + (name_char_list_size * sizeof(char)) +
(name_id_list_size * sizeof(unsigned)) + (via_node_list_size * sizeof(NodeID)) +
(graph_node_list_size * sizeof(QueryGraph::NodeArrayEntry)) +
(graph_edge_list_size * sizeof(QueryGraph::EdgeArrayEntry)) +
(timestamp_length * sizeof(char));
return result;
}
uint64_t GetTurnInstructionListOffset() const
{
uint64_t result =
(name_index_list_size * sizeof(unsigned)) + (name_char_list_size * sizeof(char)) +
(name_id_list_size * sizeof(unsigned)) + (via_node_list_size * sizeof(NodeID)) +
(graph_node_list_size * sizeof(QueryGraph::NodeArrayEntry)) +
(graph_edge_list_size * sizeof(QueryGraph::EdgeArrayEntry)) +
(timestamp_length * sizeof(char)) +
(coordinate_list_size * sizeof(FixedPointCoordinate));
return result;
}
uint64_t GetRSearchTreeOffset() const
{
uint64_t result =
(name_index_list_size * sizeof(unsigned)) + (name_char_list_size * sizeof(char)) +
(name_id_list_size * sizeof(unsigned)) + (via_node_list_size * sizeof(NodeID)) +
(graph_node_list_size * sizeof(QueryGraph::NodeArrayEntry)) +
(graph_edge_list_size * sizeof(QueryGraph::EdgeArrayEntry)) +
(timestamp_length * sizeof(char)) +
(coordinate_list_size * sizeof(FixedPointCoordinate)) +
(turn_instruction_list_size * sizeof(TurnInstructionsClass));
return result;
}
uint64_t GetGeometriesIndicatorOffset() const
{
uint64_t result =
(name_index_list_size * sizeof(unsigned)) + (name_char_list_size * sizeof(char)) +
(name_id_list_size * sizeof(unsigned)) + (via_node_list_size * sizeof(NodeID)) +
(graph_node_list_size * sizeof(QueryGraph::NodeArrayEntry)) +
(graph_edge_list_size * sizeof(QueryGraph::EdgeArrayEntry)) +
(timestamp_length * sizeof(char)) +
(coordinate_list_size * sizeof(FixedPointCoordinate)) +
(turn_instruction_list_size * sizeof(TurnInstructionsClass)) +
(r_search_tree_size * sizeof(RTreeNode));
return result;
}
T* ptr = (T*)(shared_memory + GetBlockOffset(bid));
if (WRITE_CANARY)
{
char* start_canary_ptr = shared_memory + GetBlockOffset(bid) - sizeof(CANARY);
char* end_canary_ptr = shared_memory + GetBlockOffset(bid) + GetBlockSize(bid);
std::copy(CANARY, CANARY + sizeof(CANARY), start_canary_ptr);
std::copy(CANARY, CANARY + sizeof(CANARY), end_canary_ptr);
}
else
{
char* start_canary_ptr = shared_memory + GetBlockOffset(bid) - sizeof(CANARY);
char* end_canary_ptr = shared_memory + GetBlockOffset(bid) + GetBlockSize(bid);
bool start_canary_alive = std::equal(CANARY, CANARY + sizeof(CANARY), start_canary_ptr);
bool end_canary_alive = std::equal(CANARY, CANARY + sizeof(CANARY), end_canary_ptr);
if (!start_canary_alive)
{
throw OSRMException("Start canary of block corrupted.");
}
if (!end_canary_alive)
{
throw OSRMException("End canary of block corrupted.");
}
}
uint64_t GetGeometriesIndexListOffset() const
{
uint64_t result =
(name_index_list_size * sizeof(unsigned)) + (name_char_list_size * sizeof(char)) +
(name_id_list_size * sizeof(unsigned)) + (via_node_list_size * sizeof(NodeID)) +
(graph_node_list_size * sizeof(QueryGraph::NodeArrayEntry)) +
(graph_edge_list_size * sizeof(QueryGraph::EdgeArrayEntry)) +
(timestamp_length * sizeof(char)) +
(coordinate_list_size * sizeof(FixedPointCoordinate)) +
(turn_instruction_list_size * sizeof(TurnInstructionsClass)) +
(r_search_tree_size * sizeof(RTreeNode)) +
(geometries_indicators / 32 + 1) * sizeof(unsigned);
return result;
}
uint64_t GetGeometryListOffset() const
{
uint64_t result =
(name_index_list_size * sizeof(unsigned)) + (name_char_list_size * sizeof(char)) +
(name_id_list_size * sizeof(unsigned)) + (via_node_list_size * sizeof(NodeID)) +
(graph_node_list_size * sizeof(QueryGraph::NodeArrayEntry)) +
(graph_edge_list_size * sizeof(QueryGraph::EdgeArrayEntry)) +
(timestamp_length * sizeof(char)) +
(coordinate_list_size * sizeof(FixedPointCoordinate)) +
(turn_instruction_list_size * sizeof(TurnInstructionsClass)) +
(r_search_tree_size * sizeof(RTreeNode)) +
(geometries_indicators / 32 + 1) * sizeof(unsigned) +
(geometries_index_list_size * sizeof(unsigned));
return result;
}
uint64_t GetChecksumOffset() const
{
uint64_t result =
(name_index_list_size * sizeof(unsigned)) + (name_char_list_size * sizeof(char)) +
(name_id_list_size * sizeof(unsigned)) + (via_node_list_size * sizeof(NodeID)) +
(graph_node_list_size * sizeof(QueryGraph::NodeArrayEntry)) +
(graph_edge_list_size * sizeof(QueryGraph::EdgeArrayEntry)) +
(timestamp_length * sizeof(char)) +
(coordinate_list_size * sizeof(FixedPointCoordinate)) +
(turn_instruction_list_size * sizeof(TurnInstructionsClass)) +
(r_search_tree_size * sizeof(RTreeNode)) +
(geometries_indicators / 32 + 1) * sizeof(unsigned) +
(geometries_index_list_size * sizeof(unsigned)) +
(geometries_list_size * sizeof(unsigned));
return result;
return ptr;
}
};
+14 -25
View File
@@ -32,26 +32,21 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace http
{
void Reply::setSize(const unsigned size)
void Reply::SetSize(const unsigned size)
{
for (Header &h : headers)
{
if ("Content-Length" == h.name)
{
h.value = IntToString(size);
h.value = UintToString(size);
}
}
}
// Sets the size of the uncompressed output.
void Reply::SetUncompressedSize()
{
unsigned uncompressed_size = 0;
uncompressed_size = content.size();
setSize(uncompressed_size);
}
void Reply::SetUncompressedSize() { SetSize(static_cast<unsigned>(content.size())); }
std::vector<boost::asio::const_buffer> Reply::toBuffers()
std::vector<boost::asio::const_buffer> Reply::ToBuffers()
{
std::vector<boost::asio::const_buffer> buffers;
buffers.push_back(ToBuffer(status));
@@ -85,23 +80,17 @@ std::vector<boost::asio::const_buffer> Reply::HeaderstoBuffers()
Reply Reply::StockReply(Reply::status_type status)
{
Reply rep;
rep.status = status;
rep.content.clear();
Reply reply;
reply.status = status;
reply.content.clear();
const std::string status_string = rep.ToString(status);
rep.content.insert(rep.content.end(), status_string.begin(), status_string.end());
rep.headers.resize(3);
rep.headers[0].name = "Access-Control-Allow-Origin";
rep.headers[0].value = "*";
rep.headers[1].name = "Content-Length";
std::string size_string = IntToString(rep.content.size());
rep.headers[1].value = size_string;
rep.headers[2].name = "Content-Type";
rep.headers[2].value = "text/html";
return rep;
const std::string status_string = reply.ToString(status);
reply.content.insert(reply.content.end(), status_string.begin(), status_string.end());
reply.headers.emplace_back("Access-Control-Allow-Origin", "*");
reply.headers.emplace_back("Content-Length",
UintToString(static_cast<unsigned>(reply.content.size())));
reply.headers.emplace_back("Content-Type", "text/html");
return reply;
}
std::string Reply::ToString(Reply::status_type status)
+40 -44
View File
@@ -66,6 +66,7 @@ void RequestHandler::handle_request(const http::Request &req, http::Reply &reply
ltime = time(nullptr);
Tm = localtime(&ltime);
// log timestamp
SimpleLogger().Write() << (Tm->tm_mday < 10 ? "0" : "") << Tm->tm_mday << "-"
<< (Tm->tm_mon + 1 < 10 ? "0" : "") << (Tm->tm_mon + 1) << "-"
<< 1900 + Tm->tm_year << " " << (Tm->tm_hour < 10 ? "0" : "")
@@ -78,60 +79,55 @@ void RequestHandler::handle_request(const http::Request &req, http::Reply &reply
RouteParameters route_parameters;
APIGrammarParser api_parser(&route_parameters);
auto it = request.begin();
const bool result = boost::spirit::qi::parse(it, request.end(), api_parser);
auto iter = request.begin();
const bool result = boost::spirit::qi::parse(iter, request.end(), api_parser);
if (!result || (it != request.end()))
// check if the was an error with the request
if (!result || (iter != request.end()))
{
reply = http::Reply::StockReply(http::Reply::badRequest);
reply.content.clear();
const int position = std::distance(request.begin(), it);
const unsigned position = static_cast<unsigned>(std::distance(request.begin(), iter));
JSON::Object json_result;
json_result.values["status"] = 400;
std::string tmp_position_string = IntToString(position);
std::string message = ("Query string malformed close to position " + IntToString(position));
std::string message = "Query string malformed close to position ";
message += UintToString(position);
json_result.values["status_message"] = message;
JSON::render(reply.content, json_result);
return;
}
// parsing done, lets call the right plugin to handle the request
BOOST_ASSERT_MSG(routing_machine != nullptr, "pointer not init'ed");
if (!route_parameters.jsonp_parameter.empty())
{ // prepend response with jsonp parameter
const std::string json_p = (route_parameters.jsonp_parameter + "(");
reply.content.insert(reply.content.end(), json_p.begin(), json_p.end());
}
routing_machine->RunQuery(route_parameters, reply);
if (!route_parameters.jsonp_parameter.empty())
{ // append brace to jsonp response
reply.content.push_back(')');
}
// set headers
reply.headers.emplace_back("Content-Length",
UintToString(static_cast<unsigned>(reply.content.size())));
if ("gpx" == route_parameters.output_format)
{ // gpx file
reply.headers.emplace_back("Content-Type", "application/gpx+xml; charset=UTF-8");
reply.headers.emplace_back("Content-Disposition", "attachment; filename=\"route.gpx\"");
}
else if (route_parameters.jsonp_parameter.empty())
{ // json file
reply.headers.emplace_back("Content-Type", "application/json; charset=UTF-8");
reply.headers.emplace_back("Content-Disposition", "inline; filename=\"response.json\"");
}
else
{
// parsing done, lets call the right plugin to handle the request
BOOST_ASSERT_MSG(routing_machine != nullptr, "pointer not init'ed");
if (!route_parameters.jsonp_parameter.empty())
{
const std::string json_p = (route_parameters.jsonp_parameter + "(");
reply.content.insert(reply.content.end(), json_p.begin(), json_p.end());
}
routing_machine->RunQuery(route_parameters, reply);
// set headers, still ugly and should be reworked
reply.headers.resize(3);
if ("gpx" == route_parameters.output_format)
{
reply.headers[1].name = "Content-Type";
reply.headers[1].value = "application/gpx+xml; charset=UTF-8";
reply.headers[2].name = "Content-Disposition";
reply.headers[2].value = "attachment; filename=\"route.gpx\"";
}
else if (!route_parameters.jsonp_parameter.empty())
{
reply.content.push_back(')');
reply.headers[1].name = "Content-Type";
reply.headers[1].value = "text/javascript";
reply.headers[2].name = "Content-Disposition";
reply.headers[2].value = "attachment; filename=\"response.js\"";
}
else
{
reply.headers[1].name = "Content-Type";
reply.headers[1].value = "application/x-javascript";
reply.headers[2].name = "Content-Disposition";
reply.headers[2].value = "attachment; filename=\"response.json\"";
}
reply.headers[0].name = "Content-Length";
reply.headers[0].value = IntToString(reply.content.size());
return;
{ // jsonp
reply.headers.emplace_back("Content-Type", "text/javascript; charset=UTF-8");
reply.headers.emplace_back("Content-Disposition", "inline; filename=\"response.js\"");
}
}
catch (const std::exception &e)
+6 -6
View File
@@ -31,16 +31,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace http
{
RequestParser::RequestParser() : state_(method_start) {}
RequestParser::RequestParser() : state_(method_start), header({"", ""}) {}
void RequestParser::Reset() { state_ = method_start; }
boost::tuple<boost::tribool, char *>
RequestParser::Parse(Request &req, char *begin, char *end, http::CompressionType *compressionType)
RequestParser::Parse(Request &req, char *begin, char *end, http::CompressionType *compression_type)
{
while (begin != end)
{
boost::tribool result = consume(req, *begin++, compressionType);
boost::tribool result = consume(req, *begin++, compression_type);
if (result || !result)
{
return boost::make_tuple(result, begin);
@@ -51,7 +51,7 @@ RequestParser::Parse(Request &req, char *begin, char *end, http::CompressionType
}
boost::tribool
RequestParser::consume(Request &req, char input, http::CompressionType *compressionType)
RequestParser::consume(Request &req, char input, http::CompressionType *compression_type)
{
switch (state_)
{
@@ -177,11 +177,11 @@ RequestParser::consume(Request &req, char input, http::CompressionType *compress
/* giving gzip precedence over deflate */
if (header.value.find("deflate") != std::string::npos)
{
*compressionType = deflateRFC1951;
*compression_type = deflateRFC1951;
}
if (header.value.find("gzip") != std::string::npos)
{
*compressionType = gzipRFC1952;
*compression_type = gzipRFC1952;
}
}
+6 -2
View File
@@ -28,6 +28,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef SERVER_H
#define SERVER_H
#include "../Util/StringUtil.h"
#include "Connection.h"
#include "RequestHandler.h"
@@ -42,12 +44,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
class Server
{
public:
explicit Server(const std::string &address, const std::string &port, unsigned thread_pool_size)
explicit Server(const std::string &address, const int port, const unsigned thread_pool_size)
: thread_pool_size(thread_pool_size), acceptor(io_service),
new_connection(new http::Connection(io_service, request_handler)), request_handler()
{
const std::string port_string = IntToString(port);
boost::asio::ip::tcp::resolver resolver(io_service);
boost::asio::ip::tcp::resolver::query query(address, port);
boost::asio::ip::tcp::resolver::query query(address, port_string);
boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query);
acceptor.open(endpoint.protocol());
+4 -5
View File
@@ -29,9 +29,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define SERVER_FACTORY_H
#include "Server.h"
#include "../Util/OpenMPWrapper.h"
#include "../Util/SimpleLogger.h"
#include "../Util/StringUtil.h"
#include <zlib.h>
@@ -39,11 +37,12 @@ struct ServerFactory
{
ServerFactory() = delete;
ServerFactory(const ServerFactory &) = delete;
static Server *CreateServer(std::string &ip_address, int ip_port, int threads)
static Server *CreateServer(std::string &ip_address, int ip_port, unsigned requested_num_threads)
{
SimpleLogger().Write() << "http 1.1 compression handled by zlib version " << zlibVersion();
std::string port_stream = IntToString(ip_port);
return new Server(ip_address, port_stream, std::min(omp_get_num_procs(), threads));
const unsigned hardware_threads = std::max(1u, std::thread::hardware_concurrency());
const unsigned real_num_threads = std::min(hardware_threads, requested_num_threads);
return new Server(ip_address, ip_port, real_num_threads);
}
};
+10 -7
View File
@@ -33,7 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../Util/GraphLoader.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../Util/UUID.h"
#include "../Util/FingerPrint.h"
#include <fstream>
#include <memory>
@@ -61,11 +61,11 @@ int main(int argc, char *argv[])
{
SimpleLogger().Write() << "Using restrictions from file: " << argv[2];
std::ifstream restriction_ifstream(argv[2], std::ios::binary);
const UUID uuid_orig;
UUID uuid_loaded;
restriction_ifstream.read((char *)&uuid_loaded, sizeof(UUID));
const FingerPrint fingerprint_orig;
FingerPrint fingerprint_loaded;
restriction_ifstream.read((char *)&fingerprint_loaded, sizeof(FingerPrint));
if (!uuid_loaded.TestGraphUtil(uuid_orig))
if (!fingerprint_loaded.TestGraphUtil(fingerprint_orig))
{
SimpleLogger().Write(logWARNING) << argv[2] << " was prepared with a different build. "
"Reprocess to get rid of this warning.";
@@ -79,8 +79,11 @@ int main(int argc, char *argv[])
restriction_ifstream.read((char *)&usable_restriction_count, sizeof(uint32_t));
restrictions_vector.resize(usable_restriction_count);
restriction_ifstream.read((char *)&(restrictions_vector[0]),
usable_restriction_count * sizeof(TurnRestriction));
if (usable_restriction_count>0)
{
restriction_ifstream.read((char *)&(restrictions_vector[0]),
usable_restriction_count * sizeof(TurnRestriction));
}
restriction_ifstream.close();
std::ifstream input_stream;
+25 -23
View File
@@ -28,6 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../Util/GitDescription.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../Util/TimingUtil.h"
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
@@ -78,6 +79,11 @@ int main(int argc, char *argv[])
SimpleLogger().Write() << "Not supported on FreeBSD";
return 0;
#endif
#ifdef WIN32
SimpleLogger().Write() << "Not supported on Windows";
return 0;
#else
if (1 == argc)
{
@@ -100,17 +106,15 @@ int main(int argc, char *argv[])
throw OSRMException("Data file already exists");
}
std::chrono::time_point<std::chrono::steady_clock> time1, time2;
int *random_array = new int[number_of_elements];
std::generate(random_array, random_array + number_of_elements, std::rand);
#ifdef __APPLE__
FILE *fd = fopen(test_path.string().c_str(), "w");
fcntl(fileno(fd), F_NOCACHE, 1);
fcntl(fileno(fd), F_RDAHEAD, 0);
time1 = std::chrono::steady_clock::now();
TIMER_START(write_1gb);
write(fileno(fd), (char *)random_array, number_of_elements * sizeof(unsigned));
time2 = std::chrono::steady_clock::now();
;
TIMER_STOP(write_1gb);
fclose(fd);
#endif
#ifdef __linux__
@@ -120,21 +124,20 @@ int main(int argc, char *argv[])
{
throw OSRMException("Could not open random data file");
}
time1 = std::chrono::steady_clock::now();
TIMER_START(write_1gb);
int ret = write(f, random_array, number_of_elements * sizeof(unsigned));
if (0 > ret)
{
throw OSRMException("could not write random data file");
}
time2 = std::chrono::steady_clock::now();
TIMER_STOP(write_1gb);
close(f);
#endif
std::chrono::duration<double> elapsed_seconds = time2 - time1;
delete[] random_array;
SimpleLogger().Write(logDEBUG) << "writing raw 1GB took " << elapsed_seconds.count()
<< "ms";
SimpleLogger().Write(logDEBUG) << "writing raw 1GB took " << TIMER_SEC(write_1gb)
<< "s";
SimpleLogger().Write() << "raw write performance: " << std::setprecision(5)
<< std::fixed << 1024 * 1024 / (elapsed_seconds.count())
<< std::fixed << 1024 * 1024 / TIMER_SEC(write_1gb)
<< "MB/sec";
SimpleLogger().Write(logDEBUG)
@@ -148,7 +151,6 @@ int main(int argc, char *argv[])
throw OSRMException("data file does not exist");
}
std::chrono::time_point<std::chrono::steady_clock> time1, time2;
// volatiles do not get optimized
Statistics stats;
@@ -170,7 +172,7 @@ int main(int argc, char *argv[])
}
char *raw_array = (char *)memalign(512, number_of_elements * sizeof(unsigned));
#endif
time1 = std::chrono::steady_clock::now();
TIMER_START(read_1gb);
#ifdef __APPLE__
read(fileno(fd), raw_array, number_of_elements * sizeof(unsigned));
close(fileno(fd));
@@ -184,13 +186,12 @@ int main(int argc, char *argv[])
f = open(test_path.string().c_str(), O_RDONLY | O_DIRECT | O_SYNC);
SimpleLogger().Write(logDEBUG) << "opened, error: " << strerror(errno);
#endif
time2 = std::chrono::steady_clock::now();
TIMER_STOP(read_1gb);
std::chrono::duration<double> elapsed_seconds = time2 - time1;
SimpleLogger().Write(logDEBUG) << "reading raw 1GB took " << elapsed_seconds.count()
<< "ms";
SimpleLogger().Write(logDEBUG) << "reading raw 1GB took " << TIMER_SEC(read_1gb)
<< "s";
SimpleLogger().Write() << "raw read performance: " << std::setprecision(5) << std::fixed
<< 1024 * 1024 / (elapsed_seconds.count()) << "MB/sec";
<< 1024 * 1024 / TIMER_SEC(read_1gb) << "MB/sec";
std::vector<double> timing_results_raw_random;
SimpleLogger().Write(logDEBUG) << "running 1000 random I/Os of 4KB";
@@ -207,7 +208,7 @@ int main(int argc, char *argv[])
{
unsigned block_to_read = std::rand() % number_of_blocks;
off_t current_offset = block_to_read * 4096;
time1 = std::chrono::steady_clock::now();
TIMER_START(random_access);
#ifdef __APPLE__
int ret1 = fseek(fd, current_offset, SEEK_SET);
int ret2 = read(fileno(fd), (char *)&single_block[0], 4096);
@@ -222,7 +223,7 @@ int main(int argc, char *argv[])
int ret1 = lseek(f, current_offset, SEEK_SET);
int ret2 = read(f, (char *)single_block, 4096);
#endif
time2 = std::chrono::steady_clock::now();
TIMER_STOP(random_access);
if (((off_t) - 1) == ret1)
{
SimpleLogger().Write(logWARNING) << "offset: " << current_offset;
@@ -235,7 +236,7 @@ int main(int argc, char *argv[])
SimpleLogger().Write(logWARNING) << "read error " << strerror(errno);
throw OSRMException("read error");
}
timing_results_raw_random.push_back(elapsed_seconds.count());
timing_results_raw_random.push_back(TIMER_SEC(random_access));
}
// Do statistics
@@ -267,7 +268,7 @@ int main(int argc, char *argv[])
for (unsigned i = 0; i < 1000; ++i)
{
off_t current_offset = i * 4096;
time1 = std::chrono::steady_clock::now();
TIMER_START(read_every_100);
#ifdef __APPLE__
int ret1 = fseek(fd, current_offset, SEEK_SET);
int ret2 = read(fileno(fd), (char *)&single_block, 4096);
@@ -283,7 +284,7 @@ int main(int argc, char *argv[])
int ret2 = read(f, (char *)single_block, 4096);
#endif
time2 = std::chrono::steady_clock::now();
TIMER_STOP(read_every_100);
if (((off_t) - 1) == ret1)
{
SimpleLogger().Write(logWARNING) << "offset: " << current_offset;
@@ -296,7 +297,7 @@ int main(int argc, char *argv[])
SimpleLogger().Write(logWARNING) << "read error " << strerror(errno);
throw OSRMException("read error");
}
timing_results_raw_seq.push_back(elapsed_seconds.count());
timing_results_raw_seq.push_back(TIMER_SEC(read_every_100));
}
#ifdef __APPLE__
fclose(fd);
@@ -343,4 +344,5 @@ int main(int argc, char *argv[])
return -1;
}
return 0;
#endif
}
+2 -2
View File
@@ -34,7 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
template <typename T> inline void sort_unique_resize(std::vector<T> &vector)
{
std::sort(vector.begin(), vector.end());
unsigned number_of_unique_elements = std::unique(vector.begin(), vector.end()) - vector.begin();
const auto number_of_unique_elements = std::unique(vector.begin(), vector.end()) - vector.begin();
vector.resize(number_of_unique_elements);
}
@@ -46,7 +46,7 @@ template <typename T> inline void sort_unique_resize_shrink_vector(std::vector<T
template <typename T> inline void remove_consecutive_duplicates_from_vector(std::vector<T> &vector)
{
unsigned number_of_unique_elements = std::unique(vector.begin(), vector.end()) - vector.begin();
const auto number_of_unique_elements = std::unique(vector.begin(), vector.end()) - vector.begin();
vector.resize(number_of_unique_elements);
}
+8 -3
View File
@@ -43,12 +43,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
// generate boost::program_options object for the routing part
inline bool GenerateDataStoreOptions(const int argc, const char *argv[], ServerPaths &paths)
inline bool GenerateDataStoreOptions(const int argc, const char *argv[], ServerPaths &paths, bool & springclean)
{
// declare a group of options that will be allowed only on command line
boost::program_options::options_description generic_options("Options");
generic_options.add_options()("version,v", "Show version")("help,h", "Show this help message")(
"config,c",
generic_options.add_options()("version,v", "Show version")("help,h", "Show this help message")
("springclean,s", "Remove all regions in shared memory")("config,c",
boost::program_options::value<boost::filesystem::path>(&paths["config"])
->default_value("server.ini"),
"Path to a configuration file");
@@ -122,6 +122,11 @@ inline bool GenerateDataStoreOptions(const int argc, const char *argv[], ServerP
return false;
}
if (option_variables.count("springclean"))
{
springclean = true;
return true;
}
boost::program_options::notify(option_variables);
const bool parameter_present = (paths.find("hsgrdata") != paths.end() &&
+14 -17
View File
@@ -25,18 +25,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "UUID.h"
#include "FingerPrint.h"
#include "OSRMException.h"
#include "../typedefs.h"
#include <boost/uuid/uuid_generators.hpp> // generators
#include <boost/uuid/uuid_io.hpp> // streaming operators etc.
#include <boost/uuid/name_generator.hpp>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <string>
#cmakedefine01 HAS64BITS
@@ -45,7 +42,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#cmakedefine MD5GRAPH "${MD5GRAPH}"
#cmakedefine MD5OBJECTS "${MD5OBJECTS}"
UUID::UUID() : magic_number(1297240911)
FingerPrint::FingerPrint() : magic_number(1297240911)
{
md5_prepare[32] = md5_tree[32] = md5_graph[32] = md5_objects[32] = '\0';
@@ -53,26 +50,26 @@ UUID::UUID() : magic_number(1297240911)
std::string temp_string(__DATE__);
temp_string += __TIME__;
std::copy(MD5PREPARE, MD5PREPARE + strlen(MD5PREPARE), md5_prepare);
std::memcpy(md5_prepare, MD5PREPARE, strlen(MD5PREPARE));
temp_string += md5_prepare;
std::copy(MD5RTREE, MD5RTREE + 32, md5_tree);
std::memcpy(md5_tree, MD5RTREE, 32);
temp_string += md5_tree;
std::copy(MD5GRAPH, MD5GRAPH + 32, md5_graph);
std::memcpy(md5_graph, MD5GRAPH, 32);
temp_string += md5_graph;
std::copy(MD5OBJECTS, MD5OBJECTS + 32, md5_objects);
std::memcpy(md5_objects, MD5OBJECTS, 32);
temp_string += md5_objects;
named_uuid = gen(temp_string);
has_64_bits = HAS64BITS;
}
UUID::~UUID() {}
FingerPrint::~FingerPrint() {}
const boost::uuids::uuid &UUID::GetUUID() const { return named_uuid; }
const boost::uuids::uuid &FingerPrint::GetFingerPrint() const { return named_uuid; }
bool UUID::IsMagicNumberOK() const { return 1297240911 == magic_number; }
bool FingerPrint::IsMagicNumberOK() const { return 1297240911 == magic_number; }
bool UUID::TestGraphUtil(const UUID &other) const
bool FingerPrint::TestGraphUtil(const FingerPrint &other) const
{
if (!other.IsMagicNumberOK())
{
@@ -81,7 +78,7 @@ bool UUID::TestGraphUtil(const UUID &other) const
return std::equal(md5_graph, md5_graph + 32, other.md5_graph);
}
bool UUID::TestPrepare(const UUID &other) const
bool FingerPrint::TestPrepare(const FingerPrint &other) const
{
if (!other.IsMagicNumberOK())
{
@@ -90,7 +87,7 @@ bool UUID::TestPrepare(const UUID &other) const
return std::equal(md5_prepare, md5_prepare + 32, other.md5_prepare);
}
bool UUID::TestRTree(const UUID &other) const
bool FingerPrint::TestRTree(const FingerPrint &other) const
{
if (!other.IsMagicNumberOK())
{
@@ -99,7 +96,7 @@ bool UUID::TestRTree(const UUID &other) const
return std::equal(md5_tree, md5_tree + 32, other.md5_tree);
}
bool UUID::TestQueryObjects(const UUID &other) const
bool FingerPrint::TestQueryObjects(const FingerPrint &other) const
{
if (!other.IsMagicNumberOK())
{
+13 -13
View File
@@ -25,25 +25,25 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef UUID_H
#define UUID_H
#ifndef FINGERPRINT_H
#define FINGERPRINT_H
#include <boost/uuid/uuid.hpp>
// implements a singleton, i.e. there is one and only one conviguration object
class UUID
class FingerPrint
{
public:
UUID();
UUID(const UUID&) = delete;
~UUID();
const boost::uuids::uuid &GetUUID() const;
FingerPrint();
FingerPrint(const FingerPrint&) = delete;
~FingerPrint();
const boost::uuids::uuid &GetFingerPrint() const;
bool IsMagicNumberOK() const;
bool TestGraphUtil(const UUID &other) const;
bool TestPrepare(const UUID &other) const;
bool TestRTree(const UUID &other) const;
bool TestNodeInfo(const UUID &other) const;
bool TestQueryObjects(const UUID &other) const;
bool TestGraphUtil(const FingerPrint &other) const;
bool TestPrepare(const FingerPrint &other) const;
bool TestRTree(const FingerPrint &other) const;
bool TestNodeInfo(const FingerPrint &other) const;
bool TestQueryObjects(const FingerPrint &other) const;
private:
const unsigned magic_number;
@@ -57,4 +57,4 @@ class UUID
bool has_64_bits;
};
#endif /* UUID_H */
#endif /* FingerPrint_H */
+40 -35
View File
@@ -34,13 +34,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../DataStructures/QueryNode.h"
#include "../DataStructures/Restriction.h"
#include "../Util/SimpleLogger.h"
#include "../Util/UUID.h"
#include "../Util/FingerPrint.h"
#include "../typedefs.h"
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <tbb/parallel_sort.h>
#include <cmath>
#include <algorithm>
@@ -58,11 +60,11 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream,
std::vector<NodeInfo> *int_to_ext_node_id_map,
std::vector<TurnRestriction> &restriction_list)
{
const UUID uuid_orig;
UUID uuid_loaded;
input_stream.read((char *)&uuid_loaded, sizeof(UUID));
const FingerPrint fingerprint_orig;
FingerPrint fingerprint_loaded;
input_stream.read((char *)&fingerprint_loaded, sizeof(FingerPrint));
if (!uuid_loaded.TestGraphUtil(uuid_orig))
if (!fingerprint_loaded.TestGraphUtil(fingerprint_orig))
{
SimpleLogger().Write(logWARNING) << ".osrm was prepared with different build.\n"
"Reprocess to get rid of this warning.";
@@ -74,17 +76,17 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream,
std::unordered_map<NodeID, NodeID> ext_to_int_id_map;
input_stream.read((char *)&n, sizeof(NodeID));
SimpleLogger().Write() << "Importing n = " << n << " nodes ";
ExternalMemoryNode node;
ExternalMemoryNode current_node;
for (NodeID i = 0; i < n; ++i)
{
input_stream.read((char *)&node, sizeof(ExternalMemoryNode));
int_to_ext_node_id_map->emplace_back(node.lat, node.lon, node.id);
ext_to_int_id_map.emplace(node.id, i);
if (node.bollard)
input_stream.read((char *)&current_node, sizeof(ExternalMemoryNode));
int_to_ext_node_id_map->emplace_back(current_node.lat, current_node.lon, current_node.node_id);
ext_to_int_id_map.emplace(current_node.node_id, i);
if (current_node.bollard)
{
barrier_node_list.emplace_back(i);
}
if (node.trafficLight)
if (current_node.trafficLight)
{
traffic_light_node_list.emplace_back(i);
}
@@ -202,55 +204,55 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream,
is_split);
}
std::sort(edge_list.begin(), edge_list.end());
tbb::parallel_sort(edge_list.begin(), edge_list.end());
for (unsigned i = 1; i < edge_list.size(); ++i)
{
if ((edge_list[i - 1].target() == edge_list[i].target()) &&
(edge_list[i - 1].source() == edge_list[i].source()))
if ((edge_list[i - 1].target == edge_list[i].target) &&
(edge_list[i - 1].source == edge_list[i].source))
{
const bool edge_flags_equivalent =
(edge_list[i - 1].isForward() == edge_list[i].isForward()) &&
(edge_list[i - 1].isBackward() == edge_list[i].isBackward());
(edge_list[i - 1].forward == edge_list[i].forward) &&
(edge_list[i - 1].backward == edge_list[i].backward);
const bool edge_flags_are_superset1 =
(edge_list[i - 1].isForward() && edge_list[i - 1].isBackward()) &&
(edge_list[i].isBackward() != edge_list[i].isBackward());
(edge_list[i - 1].forward && edge_list[i - 1].backward) &&
(edge_list[i].backward != edge_list[i].backward);
const bool edge_flags_are_superset_2 =
(edge_list[i].isForward() && edge_list[i].isBackward()) &&
(edge_list[i - 1].isBackward() != edge_list[i - 1].isBackward());
(edge_list[i].forward && edge_list[i].backward) &&
(edge_list[i - 1].backward != edge_list[i - 1].backward);
if (edge_flags_equivalent)
{
edge_list[i]._weight = std::min(edge_list[i - 1].weight(), edge_list[i].weight());
edge_list[i - 1]._source = UINT_MAX;
edge_list[i].weight = std::min(edge_list[i - 1].weight, edge_list[i].weight);
edge_list[i - 1].source = UINT_MAX;
}
else if (edge_flags_are_superset1)
{
if (edge_list[i - 1].weight() <= edge_list[i].weight())
if (edge_list[i - 1].weight <= edge_list[i].weight)
{
// edge i-1 is smaller and goes in both directions. Throw away the other edge
edge_list[i]._source = UINT_MAX;
edge_list[i].source = UINT_MAX;
}
else
{
// edge i-1 is open in both directions, but edge i is smaller in one direction.
// Close edge i-1 in this direction
edge_list[i - 1].forward = !edge_list[i].isForward();
edge_list[i - 1].backward = !edge_list[i].isBackward();
edge_list[i - 1].forward = !edge_list[i].forward;
edge_list[i - 1].backward = !edge_list[i].backward;
}
}
else if (edge_flags_are_superset_2)
{
if (edge_list[i - 1].weight() <= edge_list[i].weight())
if (edge_list[i - 1].weight <= edge_list[i].weight)
{
// edge i-1 is smaller for one direction. edge i is open in both. close edge i
// in the other direction
edge_list[i].forward = !edge_list[i - 1].isForward();
edge_list[i].backward = !edge_list[i - 1].isBackward();
edge_list[i].forward = !edge_list[i - 1].forward;
edge_list[i].backward = !edge_list[i - 1].backward;
}
else
{
// edge i is smaller and goes in both direction. Throw away edge i-1
edge_list[i - 1]._source = UINT_MAX;
edge_list[i - 1].source = UINT_MAX;
}
}
}
@@ -258,7 +260,7 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream,
const auto new_end_iter = std::remove_if(edge_list.begin(),
edge_list.end(),
[](const EdgeT &edge)
{ return edge.source() == UINT_MAX; });
{ return edge.source == SPECIAL_NODEID; });
ext_to_int_id_map.clear();
edge_list.erase(new_end_iter, edge_list.end()); // remove excess candidates.
edge_list.shrink_to_fit();
@@ -283,9 +285,9 @@ unsigned readHSGRFromStream(const boost::filesystem::path &hsgr_file,
boost::filesystem::ifstream hsgr_input_stream(hsgr_file, std::ios::binary);
UUID uuid_loaded, uuid_orig;
hsgr_input_stream.read((char *)&uuid_loaded, sizeof(UUID));
if (!uuid_loaded.TestGraphUtil(uuid_orig))
FingerPrint fingerprint_loaded, fingerprint_orig;
hsgr_input_stream.read((char *)&fingerprint_loaded, sizeof(FingerPrint));
if (!fingerprint_loaded.TestGraphUtil(fingerprint_orig))
{
SimpleLogger().Write(logWARNING) << ".hsgr was prepared with different build.\n"
"Reprocess to get rid of this warning.";
@@ -306,7 +308,10 @@ unsigned readHSGRFromStream(const boost::filesystem::path &hsgr_file,
hsgr_input_stream.read((char *)&(node_list[0]), number_of_nodes * sizeof(NodeT));
edge_list.resize(number_of_edges);
hsgr_input_stream.read((char *)&(edge_list[0]), number_of_edges * sizeof(EdgeT));
if (number_of_edges > 0)
{
hsgr_input_stream.read((char *)&(edge_list[0]), number_of_edges * sizeof(EdgeT));
}
hsgr_input_stream.close();
return number_of_nodes;
-2
View File
@@ -28,8 +28,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef INI_FILE_UTIL_H
#define INI_FILE_UTIL_H
#include "SimpleLogger.h"
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/regex.hpp>
+2 -4
View File
@@ -28,18 +28,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef MERCATOR_UTIL_H
#define MERCATOR_UTIL_H
#include "SimpleLogger.h"
#include <cmath>
inline float y2lat(const float a)
{
return 180.f / M_PI * (2.f * std::atan(std::exp(a * M_PI / 180.f)) - M_PI / 2.f);
return 180.f * static_cast<float>(M_1_PI) * (2.f * std::atan(std::exp(a * static_cast<float>(M_PI) / 180.f)) - static_cast<float>(M_PI_2));
}
inline float lat2y(const float a)
{
return 180.f / M_PI * std::log(std::tan(M_PI / 4.f + a * (M_PI / 180.f) / 2.f));
return 180.f * static_cast<float>(M_1_PI) * std::log(std::tan(static_cast<float>(M_PI_4) + a * (static_cast<float>(M_PI) / 180.f) / 2.f));
}
#endif // MERCATOR_UTIL_H
+8 -1
View File
@@ -31,7 +31,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/assert.hpp>
#include <cstdio>
#ifdef _MSC_VER
#include <io.h>
#define isatty _isatty
#define fileno _fileno
#else
#include <unistd.h>
#endif
#include <ostream>
#include <iostream>
@@ -120,7 +127,7 @@ class SimpleLogger
std::lock_guard<std::mutex> lock(get_mutex());
if (!LogPolicy::GetInstance().IsMute())
{
const bool is_terminal = isatty(fileno(stdout));
const bool is_terminal = ( 0 != isatty(fileno(stdout)) ? true : false);
switch (level)
{
case logINFO:
+32 -5
View File
@@ -28,17 +28,44 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef STD_HASH_EXTENSIONS_H
#define STD_HASH_EXTENSIONS_H
#include "../typedefs.h"
#include <functional>
// this is largely inspired by boost's hash combine as can be found in
// "The C++ Standard Library" 2nd Edition. Nicolai M. Josuttis. 2012.
template<typename T>
inline void hash_combine(std::size_t &seed, const T& val)
{
seed ^= std::hash<T>()(val) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
template<typename T>
inline void hash_val(std::size_t &seed, const T& val)
{
hash_combine(seed, val);
}
template<typename T, typename ... Types>
inline void hash_val(std::size_t &seed, const T& val, const Types& ... args)
{
hash_combine(seed, val);
hash_val(seed, args ...);
}
template<typename ... Types>
inline std::size_t hash_val( const Types&... args)
{
std::size_t seed = 0;
hash_val(seed, args...);
return seed;
}
namespace std
{
template <> struct hash<std::pair<NodeID, NodeID>>
template <typename T1, typename T2> struct hash<std::pair<T1, T2>>
{
size_t operator()(const std::pair<NodeID, NodeID> &pair) const
size_t operator()(const std::pair<T1, T2> &pair) const
{
return std::hash<int>()(pair.first) ^ std::hash<int>()(pair.second);
return hash_val(pair.first, pair.second);
}
};
}
+19 -9
View File
@@ -35,22 +35,24 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <cstdio>
#include <cctype>
#include <string>
#include <type_traits>
#include <vector>
// precision: position after decimal point
// length: maximum number of digits including comma and decimals
// work with negative values to prevent overflowing when taking -value
template <int length, int precision> static inline char *printInt(char *buffer, int value)
{
bool minus = false;
if (value < 0)
bool minus = true;
if (value > 0)
{
minus = true;
minus = false;
value = -value;
}
buffer += length - 1;
for (int i = 0; i < precision; i++)
{
*buffer = '0' + (value % 10);
*buffer = '0' - (value % 10);
value /= 10;
buffer--;
}
@@ -58,7 +60,7 @@ template <int length, int precision> static inline char *printInt(char *buffer,
buffer--;
for (int i = precision + 1; i < length; i++)
{
*buffer = '0' + (value % 10);
*buffer = '0' - (value % 10);
value /= 10;
if (value == 0)
break;
@@ -88,6 +90,14 @@ static inline std::string IntToString(const int value)
return output;
}
static inline std::string UintToString(const unsigned value)
{
std::string output;
std::back_insert_iterator<std::string> sink(output);
boost::spirit::karma::generate(sink, boost::spirit::karma::uint_, value);
return output;
}
static inline void int64ToString(const int64_t value, std::string &output)
{
output.clear();
@@ -95,7 +105,7 @@ static inline void int64ToString(const int64_t value, std::string &output)
boost::spirit::karma::generate(sink, boost::spirit::karma::long_long, value);
}
static inline int stringToInt(const std::string &input)
static inline int StringToInt(const std::string &input)
{
auto first_digit = input.begin();
// Delete any trailing white-spaces
@@ -108,7 +118,7 @@ static inline int stringToInt(const std::string &input)
return value;
}
static inline unsigned stringToUint(const std::string &input)
static inline unsigned StringToUint(const std::string &input)
{
auto first_digit = input.begin();
// Delete any trailing white-spaces
@@ -116,12 +126,12 @@ static inline unsigned stringToUint(const std::string &input)
{
++first_digit;
}
int value = 0;
unsigned value = 0;
boost::spirit::qi::parse(first_digit, input.end(), boost::spirit::uint_, value);
return value;
}
static inline uint64_t stringToInt64(const std::string &input)
static inline uint64_t StringToInt64(const std::string &input)
{
auto first_digit = input.begin();
// Delete any trailing white-spaces
+2 -2
View File
@@ -30,10 +30,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <chrono>
#define TIMER_START(_X) std::chrono::time_point<std::chrono::steady_clock> _X##_start, _X##_stop; _X##_start = std::chrono::steady_clock::now()
#define TIMER_START(_X) auto _X##_start = std::chrono::steady_clock::now(), _X##_stop = _X##_start
#define TIMER_STOP(_X) _X##_stop = std::chrono::steady_clock::now()
#define TIMER_MSEC(_X) std::chrono::duration_cast<std::chrono::milliseconds>(_X##_stop - _X##_start).count()
#define TIMER_SEC(_X) std::chrono::duration_cast<std::chrono::seconds>(_X##_stop - _X##_start).count()
#define TIMER_SEC(_X) (0.001*std::chrono::duration_cast<std::chrono::milliseconds>(_X##_stop - _X##_start).count())
#define TIMER_MIN(_X) std::chrono::duration_cast<std::chrono::minutes>(_X##_stop - _X##_start).count()
#endif // TIMINGUTIL_H
+1
View File
@@ -28,6 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef TRIGONOMETRY_TABLES_H
#define TRIGONOMETRY_TABLES_H
#include "../typedefs.h"
#include <cmath>
#include <limits>

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