Skip to content

Commit d89c932

Browse files
wip
1 parent 11a3e7a commit d89c932

File tree

10 files changed

+209
-100
lines changed

10 files changed

+209
-100
lines changed

CMakeLists.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
255255
set(COLOR_FLAG "")
256256
endif()
257257
# using GCC
258-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 ${COLOR_FLAG} -fPIC -ftemplate-depth=1024")
258+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 ${COLOR_FLAG} -fPIC -ftemplate-depth=1024 -fcompare-debug-second")
259259

260260
if(WIN32) # using mingw
261261
add_dependency_defines(-DWIN32)
@@ -277,6 +277,9 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
277277
target_link_libraries(osrm-extract wsock32 ws2_32)
278278
endif()
279279

280+
message(STATUS "CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}")
281+
message(STATUS "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
282+
280283
if(UNIX AND NOT APPLE)
281284
find_library(RT_LIB rt)
282285
if (RT_LIB)

cmake/warnings.cmake

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,13 @@ macro (target_no_warning target flag)
4646
target_add_warning(${target} no-${flag})
4747
endmacro ()
4848

49-
add_warning(all)
50-
add_warning(extra)
51-
add_warning(pedantic)
49+
if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
50+
add_warning(4)
51+
else()
52+
add_warning(all)
53+
add_warning(extra)
54+
add_warning(pedantic)
55+
endif()
5256
add_warning(error) # treat all warnings as errors
5357
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
5458
add_warning(strict-overflow=1)
@@ -85,4 +89,6 @@ no_warning(restrict)
8589
no_warning(free-nonheap-object)
8690
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
8791
no_warning(stringop-overflow)
88-
endif()
92+
no_warning(uninitialized)
93+
no_warning(array-bounds)
94+
endif()

features/support/data.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ module.exports = function () {
117117
var node = new OSM.Node(id, this.OSM_USER, this.OSM_TIMESTAMP, this.OSM_UID, lon, lat, {name: name});
118118
this.OSMDB.addNode(node);
119119
this.nameNodeHash[name] = node;
120+
this.idNodeHash[id] = node;
120121
};
121122

122123
this.addLocation = (name, lon, lat) => {

include/extractor/area/area_manager.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,17 @@ class AreaManager
3232
/** Mutex to protect relations_manager */
3333
MutexType mutex;
3434

35+
using relation_ids = std::vector<osmium::object_id_type>;
36+
3537
public:
3638
AreaManager() { m_assembler_config.debug_level = 0; };
3739

3840
void way(const osmium::Way &way);
3941
void relation(const osmium::Relation &relation);
4042
void prepare_for_lookup(extractor::NodeLocationsForWays &node_locations_for_ways);
4143
bool is_registered_closed_way(osmium::object_id_type way_id) const;
42-
ExtractionRelationContainer::RelationIDList get_relations_node(const osmium::Node &) const;
43-
ExtractionRelationContainer::RelationIDList get_relations_way(const osmium::Way &) const;
44+
relation_ids get_relations_for_node(const osmium::Node &) const;
45+
relation_ids get_relations_for_way(const osmium::Way &) const;
4446

4547
void complete_relation(const osmium::Relation &relation);
4648
void after_way(const osmium::Way &way);

include/extractor/area/area_mesher.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ class AreaMesher
5959
std::set<OsmiumSegment> &vis_map,
6060
const NodeRefSet &entry_points);
6161

62-
ExtractionRelationContainer::RelationIDList
63-
get_relations(const osmium::Area &area, const ExtractionRelationContainer &relations);
62+
osmium::object_id_type get_relations(const osmium::Area &area,
63+
const ExtractionRelationContainer &relations);
6464

6565
std::unordered_multimap<OSMNodeID, OSMWayID> node_id2way_index;
6666
osmium::object_id_type next_way_id{(1ULL << 34) - 1}; // see: packed_osm_ids.hpp

include/extractor/extraction_relation.hpp

Lines changed: 152 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -5,139 +5,218 @@
55

66
#include <boost/assert.hpp>
77
#include <boost/flyweight.hpp>
8+
#include <boost/flyweight/flyweight.hpp>
9+
#include <boost/flyweight/flyweight_fwd.hpp>
810
#include <boost/flyweight/no_tracking.hpp>
911

12+
#include <oneapi/tbb/concurrent_map.h>
13+
1014
#include <osmium/osm/area.hpp>
1115
#include <osmium/osm/item_type.hpp>
1216
#include <osmium/osm/node.hpp>
1317
#include <osmium/osm/object.hpp>
1418
#include <osmium/osm/relation.hpp>
19+
#include <osmium/osm/tag.hpp>
1520
#include <osmium/osm/types.hpp>
1621
#include <osmium/osm/way.hpp>
1722

18-
#include <oneapi/tbb/concurrent_map.h>
19-
#include <oneapi/tbb/mutex.h>
20-
21-
#include <osmium/storage/item_stash.hpp>
23+
#include <algorithm>
24+
#include <map>
2225
#include <string>
2326
#include <vector>
2427

28+
#include "util/log.hpp"
29+
2530
namespace osrm::extractor
2631
{
2732

33+
namespace
34+
{
35+
using string = boost::flyweights::flyweight<std::string, boost::flyweights::no_tracking>;
36+
}
37+
38+
/**
39+
* @brief A copiable RelationMember
40+
*/
41+
class RelationMember
42+
{
43+
osmium::object_id_type m_ref;
44+
osmium::item_type m_type;
45+
string m_role;
46+
47+
public:
48+
RelationMember(osmium::object_id_type id, osmium::item_type type) : m_ref{id}, m_type{type} {};
49+
RelationMember(const osmium::RelationMember &o)
50+
: m_ref{o.ref()}, m_type{o.type()}, m_role(o.role()){};
51+
osmium::object_id_type ref() const noexcept { return m_ref; }
52+
osmium::item_type type() const noexcept { return m_type; }
53+
const string &role() const noexcept { return m_role; }
54+
55+
friend bool operator==(const RelationMember &m, const RelationMember &o)
56+
{
57+
return m.ref() == o.ref() && m.type() == o.type();
58+
}
59+
friend bool operator<(const RelationMember &m, const RelationMember &o)
60+
{
61+
return m.ref() < o.ref() || (m.ref() == o.ref() && m.type() < m.type());
62+
}
63+
};
64+
65+
/**
66+
* @brief A copiable Relation
67+
*
68+
* Motivation: osmium entities are almost impossible to use with LUA because they have
69+
* no copy constructors. Eg. SOL, some 15 template invocations down, wants to
70+
* copy-construct an entity before giving it to LUA. This implementation duck-types an
71+
* `osmium::Relation` for SOL/LUA.
72+
*
73+
* Care has been taken to minimize memory consumption. The alternative to use an
74+
* `osmium::stash` was found to bee too heavy on memory.
75+
*/
76+
class Relation
77+
{
78+
using members_t = std::vector<RelationMember>;
79+
osmium::object_id_type m_id;
80+
osmium::object_version_type m_version;
81+
std::map<string, string> m_tags;
82+
members_t m_members;
83+
bool sorted{false};
84+
85+
public:
86+
Relation(const osmium::Relation &o) : m_id{o.id()}, m_version(o.version())
87+
{
88+
for (const osmium::Tag &tag : o.tags())
89+
{
90+
m_tags.emplace(tag.key(), tag.value());
91+
}
92+
for (const osmium::RelationMember &member : o.cmembers())
93+
{
94+
m_members.emplace_back(member);
95+
}
96+
};
97+
98+
osmium::object_id_type id() const noexcept { return m_id; };
99+
osmium::item_type type() const noexcept { return osmium::item_type::relation; };
100+
osmium::object_version_type version() const noexcept { return m_version; };
101+
102+
const char *get_value_by_key_default(const char *key, const char *default_value) const
103+
{
104+
// Nitpick: if somebody searches for "higway", it will be added to the flyweights
105+
auto found = m_tags.find(string(key));
106+
if (found != m_tags.end())
107+
return found->second->c_str();
108+
return default_value;
109+
};
110+
111+
const char *get_value_by_key(const char *key) const
112+
{
113+
return get_value_by_key_default(key, nullptr);
114+
}
115+
116+
template <class T> const char *get_member_role(const T &o)
117+
{
118+
return get_member_role(RelationMember(o.id(), o.type()));
119+
}
120+
121+
const char *get_member_role(const RelationMember &m)
122+
{
123+
if (!sorted)
124+
{
125+
std::sort(m_members.begin(), m_members.end());
126+
sorted = true;
127+
}
128+
auto it = std::lower_bound(m_members.begin(), m_members.end(), m);
129+
if (it != m_members.end() && *it == m)
130+
{
131+
return it->role()->c_str();
132+
}
133+
return nullptr;
134+
}
135+
136+
const members_t &members() { return m_members; };
137+
};
138+
28139
// It contains data of all parsed relations for each node/way element
29140
class ExtractionRelationContainer
30141
{
31-
public:
32142
using rel_id_type = osmium::object_id_type;
33-
using handle_type = osmium::ItemStash::handle_type;
34-
using mutex_type = tbb::mutex;
143+
using member_id_type = osmium::object_id_type;
144+
145+
using rel_ids_t = std::vector<rel_id_type>;
146+
using parent_map_t = tbb::concurrent_map<member_id_type, rel_ids_t>;
147+
148+
tbb::concurrent_map<rel_id_type, Relation> relations;
149+
std::vector<parent_map_t> parents;
35150

36-
using RelationIDList = std::vector<rel_id_type>;
37-
using id_and_type = std::pair<osmium::object_id_type, osmium::item_type>;
151+
rel_ids_t empty_rel_list{};
38152

39-
using RelationHandleMap = tbb::concurrent_map<rel_id_type, handle_type>;
40-
using MemberRelationMap = tbb::concurrent_map<id_and_type, RelationIDList>;
153+
parent_map_t &p(osmium::item_type t) { return parents[(size_t)t]; }
154+
const parent_map_t &p(osmium::item_type t) const { return parents[(size_t)t]; }
41155

42-
ExtractionRelationContainer() = default;
156+
public:
43157
ExtractionRelationContainer(ExtractionRelationContainer &&) = delete;
44158
ExtractionRelationContainer(const ExtractionRelationContainer &) = delete;
159+
ExtractionRelationContainer() : parents(4){};
45160

46161
void AddRelation(const osmium::Relation &rel)
47162
{
48-
BOOST_ASSERT(handles.find(rel.id()) == handles.end());
163+
BOOST_ASSERT(!relations.contains(rel.id()));
49164
for (auto const &m : rel.members())
50165
{
51166
AddRelationMember(rel.id(), m.ref(), m.type());
52167
}
53-
54-
handle_type handle;
55-
{
56-
mutex_type::scoped_lock lock(mutex);
57-
handle = stash.add_item(rel);
58-
}
59-
handles.emplace(rel.id(), handle);
168+
relations.emplace(rel.id(), rel);
60169
}
61170

62171
void
63172
AddRelationMember(rel_id_type relation_id, osmium::object_id_type id, osmium::item_type type)
64173
{
65-
parents[id_and_type{id, type}].push_back(relation_id);
174+
p(type)[id].push_back(relation_id);
66175
}
67176

68-
std::size_t GetRelationsNum() const { return handles.size(); }
177+
std::size_t GetRelationsNum() const { return relations.size(); }
69178

70-
const RelationIDList &_GetRelationsFor(osmium::object_id_type id, osmium::item_type type) const
179+
/**
180+
* @brief Returns the relations that the given object is a member of.
181+
*
182+
* @param id The id of the object
183+
* @param type The type of the object
184+
* @return const rel_ids_t& The list of relation ids
185+
*/
186+
const rel_ids_t &_GetRelationsFor(osmium::object_id_type id, osmium::item_type type) const
71187
{
72188
if (type == osmium::item_type::area)
73189
{
74190
type = (id & 1) ? osmium::item_type::relation : osmium::item_type::way;
75191
id /= 2;
76192
}
77-
auto it = parents.find(id_and_type{id, type});
193+
assert(type == osmium::item_type::relation || type == osmium::item_type::way ||
194+
type == osmium::item_type::node);
195+
196+
const parent_map_t &parents = p(type);
197+
198+
util::Log(logINFO) << "size of parents map: " << parents.size();
199+
200+
auto it = parents.find(id);
78201
if (it != parents.end())
79202
return it->second;
80203

81204
return empty_rel_list;
82205
}
83206

84-
const RelationIDList &GetRelationsFor(const osmium::OSMObject &o) const
207+
template <class T> const rel_ids_t &GetRelationsFor(const T &o) const
85208
{
86209
return _GetRelationsFor(o.id(), o.type());
87210
}
88211

89-
// Note: non-const because SOL somehow chokes on const.
90-
osmium::Relation &GetRelation(rel_id_type rel_id) const
212+
const Relation &GetRelation(rel_id_type rel_id) const
91213
{
92-
auto it = handles.find(rel_id);
93-
if (it == handles.end())
214+
auto it = relations.find(rel_id);
215+
if (it == relations.end())
94216
throw osrm::util::exception("Can't find relation data for " + std::to_string(rel_id));
95217

96-
return stash.get<osmium::Relation>(it->second);
218+
return it->second;
97219
}
98-
99-
void reset() { iter = handles.begin(); }
100-
101-
osmium::memory::Buffer read()
102-
{
103-
osmium::memory::Buffer buffer(16 * 1024, osmium::memory::Buffer::auto_grow::yes);
104-
auto end = handles.end();
105-
if (iter == end)
106-
return osmium::memory::Buffer();
107-
while (iter != end && buffer.written() < 12 * 1024)
108-
{
109-
buffer.add_item(stash.get_item(iter->second));
110-
buffer.commit();
111-
++iter;
112-
}
113-
return buffer;
114-
};
115-
116-
private:
117-
osmium::ItemStash stash;
118-
RelationIDList empty_rel_list;
119-
RelationHandleMap handles;
120-
RelationHandleMap::const_iterator iter;
121-
MemberRelationMap parents;
122-
123-
mutex_type mutex;
124-
};
125-
126-
/**
127-
* @brief A copiable RelationMember
128-
*/
129-
class RelationMember
130-
{
131-
osmium::object_id_type m_ref;
132-
osmium::item_type m_type;
133-
std::string m_role;
134-
135-
public:
136-
RelationMember(const osmium::RelationMember &o)
137-
: m_ref{o.ref()}, m_type{o.type()}, m_role(o.role()){};
138-
osmium::object_id_type ref() const noexcept { return m_ref; }
139-
osmium::item_type type() const noexcept { return m_type; }
140-
const std::string &role() const noexcept { return m_role; }
141220
};
142221

143222
} // namespace osrm::extractor

0 commit comments

Comments
 (0)