1#ifndef OSMIUM_INDEX_RELATIONS_MAP_HPP
2#define OSMIUM_INDEX_RELATIONS_MAP_HPP
56 template <
typename TKey,
typename TKeyInternal,
typename TValue,
typename TValueInternal>
61 using key_type = TKey;
62 using value_type = TValue;
70 explicit kv_pair(
const key_type key_id) :
71 key(static_cast<TKeyInternal>(key_id)),
75 kv_pair(
const key_type key_id,
const value_type value_id) :
76 key(static_cast<TKeyInternal>(key_id)),
77 value(static_cast<TValueInternal>(value_id)) {
80 bool operator<(
const kv_pair& other)
const noexcept {
81 return std::tie(key, value) < std::tie(other.key, other.value);
84 bool operator==(
const kv_pair& other)
const noexcept {
85 return std::tie(key, value) == std::tie(other.key, other.value);
89 std::vector<kv_pair> m_map;
93 using const_iterator =
typename std::vector<kv_pair>::const_iterator;
95 void set(
const key_type key,
const value_type value) {
96 m_map.emplace_back(key, value);
99 std::enable_if_t<std::is_same<TKey, TValue>::value> flip_in_place() {
100 for (
auto& p : m_map) {
102 swap(p.key, p.value);
106 flat_map<TValue, TValueInternal, TKey, TKeyInternal> flip_copy() {
107 flat_map<TValue, TValueInternal, TKey, TKeyInternal> map;
108 map.reserve(m_map.size());
110 for (
const auto& p : m_map) {
111 map.set(p.value, p.key);
118 std::sort(m_map.begin(), m_map.end());
119 const auto last = std::unique(m_map.begin(), m_map.end());
120 m_map.erase(last, m_map.end());
123 std::pair<const_iterator, const_iterator> get(
const key_type key)
const noexcept {
124 return std::equal_range(m_map.begin(), m_map.end(), kv_pair{key}, [](
const kv_pair& lhs,
const kv_pair& rhs) {
125 return lhs.key < rhs.key;
129 bool empty() const noexcept {
130 return m_map.empty();
133 std::size_t size() const noexcept {
137 void reserve(
const std::size_t size) {
143 m_map.shrink_to_fit();
146 typename std::vector<kv_pair>::const_iterator
begin() const noexcept {
147 return m_map.cbegin();
150 typename std::vector<kv_pair>::const_iterator
end() const noexcept {
156 template <
typename VType>
231 template <typename TFunc>
234 const auto parents =
m_map32.get(
id);
235 for (
auto it = parents.first; it != parents.second; ++it) {
236 std::forward<TFunc>(func)(it->value);
239 const auto parents =
m_map64.get(
id);
240 for (
auto it = parents.first; it != parents.second; ++it) {
241 std::forward<TFunc>(func)(it->value);
260 std::size_t
size() const noexcept {
269 inline RelationsMapIndex& RelationsMapIndex::operator=(RelationsMapIndex&&) noexcept = default;
278 RelationsMapIndexes(detail::rel_index_map_type<uint32_t>&& map1, detail::rel_index_map_type<uint32_t>&& map2) :
279 m_member_to_parent(
std::move(map1)),
280 m_parent_to_member(
std::move(map2)) {
283 RelationsMapIndexes(detail::rel_index_map_type<uint64_t>&& map1, detail::rel_index_map_type<uint64_t>&& map2) :
284 m_member_to_parent(
std::move(map1)),
285 m_parent_to_member(
std::move(map2)) {
291 return m_member_to_parent;
295 return m_parent_to_member;
304 return m_member_to_parent.
empty();
312 std::size_t
size() const noexcept {
313 return m_member_to_parent.
size();
332 static void append32to64(detail::rel_index_map_type<uint32_t>& map32, detail::rel_index_map_type<uint64_t>& map64) {
334 map64.reserve(map64.size() + map32.size());
335 for (
const auto& item : map32) {
336 map64.set(item.key, item.value);
358 assert(
m_valid &&
"You can't use the RelationsMap any more after calling build_index()");
360 if (member_id <= max32 && relation_id <= max32) {
361 m_map32.set(member_id, relation_id);
363 m_map64.set(member_id, relation_id);
371 assert(
m_valid &&
"You can't use the RelationsMap any more after calling build_index()");
372 for (
const auto& member : relation.members()) {
374 add(member.positive_ref(), relation.positive_id());
385 assert(
m_valid &&
"You can't use the RelationsMap any more after calling build_index()");
394 std::size_t
size() const noexcept {
395 assert(
m_valid &&
"You can't use the RelationsMap any more after calling build_index()");
405 std::pair<std::size_t, std::size_t>
sizes() const noexcept {
416 assert(
m_valid &&
"You can't use the RelationsMap any more after calling build_member_to_parent_index()");
437 assert(
m_valid &&
"You can't use the RelationsMap any more after calling build_parent_to_member_index()");
460 assert(
m_valid &&
"You can't use the RelationsMap any more after calling build_indexes()");
464 auto reverse_map32 =
m_map32.flip_copy();
465 reverse_map32.sort_unique();
471 auto reverse_map64 =
m_map64.flip_copy();
483 inline RelationsMapStash& RelationsMapStash::operator=(RelationsMapStash&&) noexcept = default;
Definition: relation.hpp:161
Definition: relations_map.hpp:187
RelationsMapIndex(const RelationsMapIndex &)=delete
RelationsMapIndex(detail::rel_index_map_type< uint64_t > &&map)
Definition: relations_map.hpp:201
std::size_t size() const noexcept
Definition: relations_map.hpp:260
detail::rel_index_map_type< uint64_t > m_map64
Definition: relations_map.hpp:193
void for_each(const osmium::unsigned_object_id_type id, TFunc &&func) const
Definition: relations_map.hpp:232
RelationsMapIndex(detail::rel_index_map_type< uint32_t > &&map)
Definition: relations_map.hpp:197
RelationsMapIndex()=delete
RelationsMapIndex & operator=(const RelationsMapIndex &)=delete
RelationsMapIndex(RelationsMapIndex &&) noexcept
bool empty() const noexcept
Definition: relations_map.hpp:251
detail::rel_index_map_type< uint32_t > m_map32
Definition: relations_map.hpp:192
bool m_small
Definition: relations_map.hpp:195
Definition: relations_map.hpp:271
const RelationsMapIndex & parent_to_member() const noexcept
Definition: relations_map.hpp:294
const RelationsMapIndex & member_to_parent() const noexcept
Definition: relations_map.hpp:290
std::size_t size() const noexcept
Definition: relations_map.hpp:312
bool empty() const noexcept
Definition: relations_map.hpp:303
RelationsMapIndex m_member_to_parent
Definition: relations_map.hpp:275
RelationsMapIndexes(detail::rel_index_map_type< uint32_t > &&map1, detail::rel_index_map_type< uint32_t > &&map2)
Definition: relations_map.hpp:278
RelationsMapIndexes(detail::rel_index_map_type< uint64_t > &&map1, detail::rel_index_map_type< uint64_t > &&map2)
Definition: relations_map.hpp:283
RelationsMapIndex m_parent_to_member
Definition: relations_map.hpp:276
Definition: relations_map.hpp:323
detail::rel_index_map_type< uint32_t > m_map32
Definition: relations_map.hpp:325
RelationsMapIndex build_member_to_parent_index()
Definition: relations_map.hpp:415
bool m_valid
Definition: relations_map.hpp:329
std::size_t size() const noexcept
Definition: relations_map.hpp:394
RelationsMapIndexes build_indexes()
Definition: relations_map.hpp:459
RelationsMapIndex build_parent_to_member_index()
Definition: relations_map.hpp:436
static void append32to64(detail::rel_index_map_type< uint32_t > &map32, detail::rel_index_map_type< uint64_t > &map64)
Definition: relations_map.hpp:332
detail::rel_index_map_type< uint64_t > m_map64
Definition: relations_map.hpp:326
void add_members(const osmium::Relation &relation)
Definition: relations_map.hpp:370
RelationsMapStash & operator=(const RelationsMapStash &)=delete
std::pair< std::size_t, std::size_t > sizes() const noexcept
Definition: relations_map.hpp:405
RelationsMapStash(RelationsMapStash &&) noexcept
bool empty() const noexcept
Definition: relations_map.hpp:384
RelationsMapStash(const RelationsMapStash &)=delete
void add(const osmium::unsigned_object_id_type member_id, const osmium::unsigned_object_id_type relation_id)
Definition: relations_map.hpp:357
RelationsMapStash()=default
InputIterator< Reader > end(Reader &)
Definition: reader_iterator.hpp:47
InputIterator< Reader > begin(Reader &reader)
Definition: reader_iterator.hpp:43
Namespace for everything in the Osmium library.
Definition: assembler.hpp:53
bool operator==(const Changeset &lhs, const Changeset &rhs)
Definition: changeset.hpp:440
uint64_t unsigned_object_id_type
Type for OSM object (node, way, or relation) IDs where we only allow positive IDs.
Definition: types.hpp:46
bool operator<(const Changeset &lhs, const Changeset &rhs)
Definition: changeset.hpp:451
Definition: location.hpp:555