Skip to content

Commit 83d5070

Browse files
committed
extract: scan way nodes once across all extracts in complete_ways pass 1
1 parent 5f61871 commit 83d5070

2 files changed

Lines changed: 51 additions & 3 deletions

File tree

src/extract/strategy.hpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,7 @@ class Pass {
104104
break;
105105
case osmium::item_type::way:
106106
self().way(static_cast<const osmium::Way&>(object));
107-
for (auto& e : extracts()) {
108-
self().eway(&e, static_cast<const osmium::Way&>(object));
109-
}
107+
self().eway_all(extracts(), static_cast<const osmium::Way&>(object));
110108
break;
111109
case osmium::item_type::relation:
112110
self().relation(static_cast<const osmium::Relation&>(object));
@@ -155,6 +153,15 @@ class Pass {
155153
void erelation(extract_data*, const osmium::Relation&) {
156154
}
157155

156+
// Default implementation: call eway() for each extract separately.
157+
// Subclasses may override this to process all extracts in a single
158+
// pass over way.nodes().
159+
void eway_all(std::vector<extract_data>& exts, const osmium::Way& way) {
160+
for (auto& e : exts) {
161+
self().eway(&e, way);
162+
}
163+
}
164+
158165
public:
159166

160167
explicit Pass(TStrategy* strategy) :

src/extract/strategy_complete_ways.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
2727
#include <osmium/handler/check_order.hpp>
2828
#include <osmium/util/file.hpp>
2929

30+
#include <cstdint>
3031
#include <cstdlib>
3132
#include <memory>
3233
#include <vector>
@@ -100,6 +101,46 @@ namespace strategy_complete_ways {
100101
}
101102
}
102103

104+
// Override that scans way.nodes() at most twice for all extracts
105+
// combined instead of up to twice per extract as the default does.
106+
// Pass A finds which extracts claim this way (bitmask, max 64 extracts).
107+
// Pass B records all node refs into extra_node_ids for matched extracts.
108+
void eway_all(std::vector<extract_data>& exts, const osmium::Way& way) {
109+
const std::size_t n = exts.size();
110+
std::uint64_t found_mask = 0;
111+
std::size_t remaining = n;
112+
113+
for (const auto& nr : way.nodes()) {
114+
const auto node_id = nr.positive_ref();
115+
for (std::size_t i = 0; i < n; ++i) {
116+
if (!(found_mask & (std::uint64_t{1} << i)) &&
117+
exts[i].node_ids.get(node_id)) {
118+
found_mask |= std::uint64_t{1} << i;
119+
exts[i].way_ids.set(way.positive_id());
120+
if (--remaining == 0) {
121+
break;
122+
}
123+
}
124+
}
125+
if (remaining == 0) {
126+
break;
127+
}
128+
}
129+
130+
if (found_mask == 0) {
131+
return;
132+
}
133+
134+
for (const auto& nr : way.nodes()) {
135+
const auto node_ref = nr.ref();
136+
for (std::size_t i = 0; i < n; ++i) {
137+
if (found_mask & (std::uint64_t{1} << i)) {
138+
exts[i].extra_node_ids.set(node_ref);
139+
}
140+
}
141+
}
142+
}
143+
103144
void relation(const osmium::Relation& relation) {
104145
m_check_order.relation(relation);
105146
m_relations_map_stash.add_members(relation);

0 commit comments

Comments
 (0)