Skip to content

Commit 83072b0

Browse files
committed
Re-use temp buffer for area creation
Saves memory allocations.
1 parent ef940c6 commit 83072b0

File tree

8 files changed

+78
-36
lines changed

8 files changed

+78
-36
lines changed

src/geom-from-osm.cpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ geometry_t create_linestring(osmium::Way const &way)
9090
return geom;
9191
}
9292

93-
void create_polygon(geometry_t *geom, osmium::Way const &way)
93+
void create_polygon(geometry_t *geom, osmium::Way const &way,
94+
osmium::memory::Buffer *area_buffer)
9495
{
9596
auto &polygon = geom->set<polygon_t>();
9697

@@ -100,8 +101,7 @@ void create_polygon(geometry_t *geom, osmium::Way const &way)
100101
return;
101102
}
102103

103-
osmium::memory::Buffer area_buffer{1024};
104-
geom::area_assembler_t assembler{&area_buffer};
104+
geom::area_assembler_t assembler{area_buffer};
105105

106106
if (!assembler(way)) {
107107
geom->reset();
@@ -114,10 +114,11 @@ void create_polygon(geometry_t *geom, osmium::Way const &way)
114114
fill_point_list(&polygon.outer(), ring);
115115
}
116116

117-
geometry_t create_polygon(osmium::Way const &way)
117+
geometry_t create_polygon(osmium::Way const &way,
118+
osmium::memory::Buffer *area_buffer)
118119
{
119120
geometry_t geom{};
120-
create_polygon(&geom, way);
121+
create_polygon(&geom, way, area_buffer);
121122
return geom;
122123
}
123124

@@ -205,10 +206,10 @@ geometry_t create_multilinestring(osmium::memory::Buffer const &buffer,
205206
}
206207

207208
void create_multipolygon(geometry_t *geom, osmium::Relation const &relation,
208-
osmium::memory::Buffer const &buffer)
209+
osmium::memory::Buffer const &buffer,
210+
osmium::memory::Buffer *area_buffer)
209211
{
210-
osmium::memory::Buffer area_buffer{1024};
211-
geom::area_assembler_t assembler{&area_buffer};
212+
geom::area_assembler_t assembler{area_buffer};
212213

213214
if (!assembler(relation, buffer)) {
214215
geom->reset();
@@ -231,10 +232,11 @@ void create_multipolygon(geometry_t *geom, osmium::Relation const &relation,
231232
}
232233

233234
geometry_t create_multipolygon(osmium::Relation const &relation,
234-
osmium::memory::Buffer const &buffer)
235+
osmium::memory::Buffer const &buffer,
236+
osmium::memory::Buffer *area_buffer)
235237
{
236238
geometry_t geom{};
237-
create_multipolygon(&geom, relation, buffer);
239+
create_multipolygon(&geom, relation, buffer, area_buffer);
238240
return geom;
239241
}
240242

src/geom-from-osm.hpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,18 +76,22 @@ void create_linestring(geometry_t *geom, osmium::Way const &way);
7676
*
7777
* \param geom Pointer to an existing geometry which will be used as output.
7878
* \param way The input way.
79+
* \param area_buffer Temporary buffer used to create area.
7980
*/
80-
void create_polygon(geometry_t *geom, osmium::Way const &way);
81+
void create_polygon(geometry_t *geom, osmium::Way const &way,
82+
osmium::memory::Buffer *area_buffer);
8183

8284
/**
8385
* Create a polygon geometry from a way.
8486
*
8587
* If the resulting polygon would be invalid, a null geometry is returned.
8688
*
8789
* \param way The input way.
90+
* \param area_buffer Temporary buffer used to create area.
8891
* \returns The created geometry.
8992
*/
90-
[[nodiscard]] geometry_t create_polygon(osmium::Way const &way);
93+
[[nodiscard]] geometry_t create_polygon(osmium::Way const &way,
94+
osmium::memory::Buffer *area_buffer);
9195

9296
/**
9397
* Create a multipoint geometry from a bunch of nodes (usually this would be
@@ -163,9 +167,11 @@ create_multilinestring(osmium::memory::Buffer const &buffer,
163167
* \param geom Pointer to an existing geometry which will be used as output.
164168
* \param relation The input relation.
165169
* \param buffer Buffer with OSM objects. Anything but ways are ignored.
170+
* \param area_buffer Temporary buffer used to create area.
166171
*/
167172
void create_multipolygon(geometry_t *geom, osmium::Relation const &relation,
168-
osmium::memory::Buffer const &buffer);
173+
osmium::memory::Buffer const &buffer,
174+
osmium::memory::Buffer *area_buffer);
169175

170176
/**
171177
* Create a (multi)polygon geometry from a relation and member ways.
@@ -175,11 +181,13 @@ void create_multipolygon(geometry_t *geom, osmium::Relation const &relation,
175181
*
176182
* \param relation The input relation.
177183
* \param buffer Buffer with OSM objects. Anything but ways are ignored.
184+
* \param area_buffer Temporary buffer used to create area.
178185
* \returns The created geometry.
179186
*/
180187
[[nodiscard]] geometry_t
181188
create_multipolygon(osmium::Relation const &relation,
182-
osmium::memory::Buffer const &buffer);
189+
osmium::memory::Buffer const &buffer,
190+
osmium::memory::Buffer *area_buffer);
183191

184192
/**
185193
* Create a geometry collection from nodes and ways, usually used for

src/output-flex.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ int output_flex_t::app_as_polygon()
400400
m_way_cache.add_nodes(middle());
401401

402402
auto *geom = create_lua_geometry_object(lua_state());
403-
geom::create_polygon(geom, m_way_cache.get());
403+
geom::create_polygon(geom, m_way_cache.get(), &m_area_buffer);
404404

405405
return 1;
406406
}
@@ -459,7 +459,7 @@ int output_flex_t::app_as_multipolygon()
459459
m_way_cache.add_nodes(middle());
460460

461461
auto *geom = create_lua_geometry_object(lua_state());
462-
geom::create_polygon(geom, m_way_cache.get());
462+
geom::create_polygon(geom, m_way_cache.get(), &m_area_buffer);
463463

464464
return 1;
465465
}
@@ -468,7 +468,8 @@ int output_flex_t::app_as_multipolygon()
468468

469469
auto *geom = create_lua_geometry_object(lua_state());
470470
geom::create_multipolygon(geom, m_relation_cache.get(),
471-
m_relation_cache.members_buffer());
471+
m_relation_cache.members_buffer(),
472+
&m_area_buffer);
472473

473474
return 1;
474475
}
@@ -1173,6 +1174,7 @@ output_flex_t::output_flex_t(output_flex_t const *other,
11731174
m_db_connection(get_options()->connection_params, "out.flex.thread"),
11741175
m_stage2_way_ids(other->m_stage2_way_ids),
11751176
m_copy_thread(std::move(copy_thread)), m_lua_state(other->m_lua_state),
1177+
m_area_buffer(1024, osmium::memory::Buffer::auto_grow::yes),
11761178
m_process_node(other->m_process_node), m_process_way(other->m_process_way),
11771179
m_process_relation(other->m_process_relation),
11781180
m_select_relation_members(other->m_select_relation_members),
@@ -1203,7 +1205,8 @@ output_flex_t::output_flex_t(std::shared_ptr<middle_query_t> const &mid,
12031205
properties_t const &properties)
12041206
: output_t(mid, std::move(thread_pool), options),
12051207
m_db_connection(get_options()->connection_params, "out.flex.main"),
1206-
m_copy_thread(std::make_shared<db_copy_thread_t>(options.connection_params))
1208+
m_copy_thread(std::make_shared<db_copy_thread_t>(options.connection_params)),
1209+
m_area_buffer(1024, osmium::memory::Buffer::auto_grow::yes)
12071210
{
12081211
init_lua(options.style, properties);
12091212

src/output-flex.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,8 @@ class output_flex_t : public output_t
297297
relation_cache_t m_relation_cache;
298298
osmium::Node const *m_context_node = nullptr;
299299

300+
osmium::memory::Buffer m_area_buffer;
301+
300302
prepared_lua_function_t m_process_node{};
301303
prepared_lua_function_t m_process_way{};
302304
prepared_lua_function_t m_process_relation{};

src/output-pgsql.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ void output_pgsql_t::pgsql_out_way(osmium::Way const &way, taglist_t *tags,
9595
bool polygon, bool roads)
9696
{
9797
if (polygon && !way.nodes().empty() && way.is_closed()) {
98-
auto const geom = geom::create_polygon(way);
98+
auto const geom = geom::create_polygon(way, &m_area_buffer);
9999
auto const projected_geom = geom::transform(geom, *m_proj);
100100

101101
auto const wkb = geom_to_ewkb(projected_geom);
@@ -297,9 +297,9 @@ void output_pgsql_t::pgsql_process_relation(osmium::Relation const &rel)
297297

298298
// multipolygons and boundaries
299299
if (make_boundary || make_polygon) {
300-
auto const geoms =
301-
geom::split_multi(geom::create_multipolygon(rel, m_buffer),
302-
!get_options()->enable_multi);
300+
auto const geoms = geom::split_multi(
301+
geom::create_multipolygon(rel, m_buffer, &m_area_buffer),
302+
!get_options()->enable_multi);
303303
for (auto const &sgeom : geoms) {
304304
auto const projected_geom = geom::transform(sgeom, *m_proj);
305305
m_expire.from_geometry_if_3857(projected_geom, m_expire_config);
@@ -439,7 +439,8 @@ output_pgsql_t::output_pgsql_t(std::shared_ptr<middle_query_t> const &mid,
439439
: output_t(mid, std::move(thread_pool), options), m_proj(options.projection),
440440
m_expire(options.expire_tiles_zoom, options.projection),
441441
m_buffer(32768, osmium::memory::Buffer::auto_grow::yes),
442-
m_rels_buffer(1024, osmium::memory::Buffer::auto_grow::yes)
442+
m_rels_buffer(1024, osmium::memory::Buffer::auto_grow::yes),
443+
m_area_buffer(1024, osmium::memory::Buffer::auto_grow::yes)
443444
{
444445
m_expire_config.full_area_limit = get_options()->expire_tiles_max_bbox;
445446
if (get_options()->expire_tiles_max_bbox > 0.0) {
@@ -505,7 +506,8 @@ output_pgsql_t::output_pgsql_t(
505506
m_proj(get_options()->projection), m_expire_config(other->m_expire_config),
506507
m_expire(get_options()->expire_tiles_zoom, get_options()->projection),
507508
m_buffer(1024, osmium::memory::Buffer::auto_grow::yes),
508-
m_rels_buffer(1024, osmium::memory::Buffer::auto_grow::yes)
509+
m_rels_buffer(1024, osmium::memory::Buffer::auto_grow::yes),
510+
m_area_buffer(1024, osmium::memory::Buffer::auto_grow::yes)
509511
{
510512
for (std::size_t i = 0; i < m_tables.size(); ++i) {
511513
//copy constructor will just connect to the already there table

src/output-pgsql.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ class output_pgsql_t : public output_t
109109

110110
osmium::memory::Buffer m_buffer;
111111
osmium::memory::Buffer m_rels_buffer;
112+
osmium::memory::Buffer m_area_buffer;
112113
};
113114

114115
#endif // OSM2PGSQL_OUTPUT_PGSQL_HPP

tests/test-geom-multipolygons.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@ TEST_CASE("create_multipolygon creates simple polygon from OSM data", "[NoDB]")
7070
buffer.add_way("w21 Nn4x1y2,n1x1y1");
7171
auto const &relation = buffer.add_relation("r30 Mw20@,w21@");
7272

73-
auto const geom = geom::create_multipolygon(relation, buffer.buffer());
73+
osmium::memory::Buffer area_buffer{1024};
74+
auto const geom =
75+
geom::create_multipolygon(relation, buffer.buffer(), &area_buffer);
7476

7577
REQUIRE(geom.is_polygon());
7678
REQUIRE(geometry_type(geom) == "POLYGON");
@@ -92,7 +94,9 @@ TEST_CASE("create_multipolygon from OSM data", "[NoDB]")
9294
buffer.add_way("w22 Nn5x10y10,n6x10y20,n7x20y20,n5x10y10");
9395
auto const &relation = buffer.add_relation("r30 Mw20@,w21@,w22@");
9496

95-
auto const geom = geom::create_multipolygon(relation, buffer.buffer());
97+
osmium::memory::Buffer area_buffer{1024};
98+
auto const geom =
99+
geom::create_multipolygon(relation, buffer.buffer(), &area_buffer);
96100

97101
REQUIRE(geom.is_multipolygon());
98102
REQUIRE(geometry_type(geom) == "MULTIPOLYGON");
@@ -107,7 +111,9 @@ TEST_CASE("create_multipolygon from OSM data without locations", "[NoDB]")
107111
buffer.add_way("w20 Nn1,n2,n3,n1");
108112

109113
auto const &relation = buffer.add_relation("r30 Mw20@");
110-
auto const geom = geom::create_multipolygon(relation, buffer.buffer());
114+
osmium::memory::Buffer area_buffer{1024};
115+
auto const geom =
116+
geom::create_multipolygon(relation, buffer.buffer(), &area_buffer);
111117

112118
REQUIRE(geom.is_null());
113119
}
@@ -118,7 +124,9 @@ TEST_CASE("create_multipolygon from invalid OSM data (single node)", "[NoDB]")
118124
buffer.add_way("w20 Nn1x1y1");
119125

120126
auto const &relation = buffer.add_relation("r30 Mw20@");
121-
auto const geom = geom::create_multipolygon(relation, buffer.buffer());
127+
osmium::memory::Buffer area_buffer{1024};
128+
auto const geom =
129+
geom::create_multipolygon(relation, buffer.buffer(), &area_buffer);
122130

123131
REQUIRE(geom.is_null());
124132
}
@@ -130,7 +138,9 @@ TEST_CASE("create_multipolygon from invalid OSM data (way node closed)",
130138
buffer.add_way("w20 Nn1x1y1,n2x2y2");
131139

132140
auto const &relation = buffer.add_relation("r30 Mw20@");
133-
auto const geom = geom::create_multipolygon(relation, buffer.buffer());
141+
osmium::memory::Buffer area_buffer{1024};
142+
auto const geom =
143+
geom::create_multipolygon(relation, buffer.buffer(), &area_buffer);
134144

135145
REQUIRE(geom.is_null());
136146
}
@@ -143,7 +153,9 @@ TEST_CASE("create_multipolygon from invalid OSM data (self-intersection)",
143153
buffer.add_way("w21 Nn4x2y2,n1x1y1");
144154

145155
auto const &relation = buffer.add_relation("r30 Mw20@,w21@");
146-
auto const geom = geom::create_multipolygon(relation, buffer.buffer());
156+
osmium::memory::Buffer area_buffer{1024};
157+
auto const geom =
158+
geom::create_multipolygon(relation, buffer.buffer(), &area_buffer);
147159

148160
REQUIRE(geom.is_null());
149161
}

tests/test-geom-polygons.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,9 @@ TEST_CASE("create_polygon from OSM data", "[NoDB]")
8585
test_buffer_t buffer;
8686
buffer.add_way("w20 Nn1x1y1,n2x2y1,n3x2y2,n4x1y2,n1x1y1");
8787

88-
auto const geom = geom::create_polygon(buffer.buffer().get<osmium::Way>(0));
88+
osmium::memory::Buffer area_buffer{1024};
89+
auto const geom =
90+
geom::create_polygon(buffer.buffer().get<osmium::Way>(0), &area_buffer);
8991

9092
REQUIRE(geom.is_polygon());
9193
REQUIRE(geometry_type(geom) == "POLYGON");
@@ -104,7 +106,9 @@ TEST_CASE("create_polygon from OSM data (reverse)", "[NoDB]")
104106
test_buffer_t buffer;
105107
buffer.add_way("w20 Nn1x1y1,n2x1y2,n3x2y2,n4x2y1,n1x1y1");
106108

107-
auto const geom = geom::create_polygon(buffer.buffer().get<osmium::Way>(0));
109+
osmium::memory::Buffer area_buffer{1024};
110+
auto const geom =
111+
geom::create_polygon(buffer.buffer().get<osmium::Way>(0), &area_buffer);
108112

109113
REQUIRE(geom.is_polygon());
110114
REQUIRE(geometry_type(geom) == "POLYGON");
@@ -122,7 +126,9 @@ TEST_CASE("create_polygon from OSM data without locations", "[NoDB]")
122126
test_buffer_t buffer;
123127
buffer.add_way("w20 Nn1,n2,n3,n1");
124128

125-
auto const geom = geom::create_polygon(buffer.buffer().get<osmium::Way>(0));
129+
osmium::memory::Buffer area_buffer{1024};
130+
auto const geom =
131+
geom::create_polygon(buffer.buffer().get<osmium::Way>(0), &area_buffer);
126132

127133
REQUIRE(geom.is_null());
128134
}
@@ -132,7 +138,9 @@ TEST_CASE("create_polygon from invalid OSM data (single node)", "[NoDB]")
132138
test_buffer_t buffer;
133139
buffer.add_way("w20 Nn1x1y1");
134140

135-
auto const geom = geom::create_polygon(buffer.buffer().get<osmium::Way>(0));
141+
osmium::memory::Buffer area_buffer{1024};
142+
auto const geom =
143+
geom::create_polygon(buffer.buffer().get<osmium::Way>(0), &area_buffer);
136144

137145
REQUIRE(geom.is_null());
138146
}
@@ -142,7 +150,9 @@ TEST_CASE("create_polygon from invalid OSM data (way node closed)", "[NoDB]")
142150
test_buffer_t buffer;
143151
buffer.add_way("w20 Nn1x1y1,n2x2y2");
144152

145-
auto const geom = geom::create_polygon(buffer.buffer().get<osmium::Way>(0));
153+
osmium::memory::Buffer area_buffer{1024};
154+
auto const geom =
155+
geom::create_polygon(buffer.buffer().get<osmium::Way>(0), &area_buffer);
146156

147157
REQUIRE(geom.is_null());
148158
}
@@ -152,7 +162,9 @@ TEST_CASE("create_polygon from invalid OSM data (self-intersection)", "[NoDB]")
152162
test_buffer_t buffer;
153163
buffer.add_way("w20 Nn1x1y1,n2x1y2,n3x2y1,n4x2y2,n1x1y1");
154164

155-
auto const geom = geom::create_polygon(buffer.buffer().get<osmium::Way>(0));
165+
osmium::memory::Buffer area_buffer{1024};
166+
auto const geom =
167+
geom::create_polygon(buffer.buffer().get<osmium::Way>(0), &area_buffer);
156168

157169
REQUIRE(geom.is_null());
158170
}

0 commit comments

Comments
 (0)