Skip to content

Commit f83b6b5

Browse files
authored
Merge pull request #2221 from joto/flat-node-file-non-slim
Make --flat-nodes also work in non-slim mode
2 parents f8c78ae + d6256a0 commit f83b6b5

File tree

7 files changed

+80
-28
lines changed

7 files changed

+80
-28
lines changed

man/osm2pgsql.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -155,16 +155,17 @@ mandatory for short options too.
155155
timestamp and version.
156156

157157
\--flat-nodes=FILENAME
158-
: The flat-nodes mode is a separate method to store slim mode node information on disk.
159-
Instead of storing this information in the main PostgreSQL database, this mode creates
160-
its own separate custom database to store the information. As this custom database
161-
has application level knowledge about the data to store and is not general purpose,
162-
it can store the data much more efficiently. Storing the node information for the full
163-
planet requires more than 300GB in PostgreSQL, the same data is stored in "only" 50GB using
158+
: Use a file on disk to store node locations instead of storing them in
159+
memory (in non-slim mode) or in the database (in slim mode). This is much
160+
more efficient than storing the data in the database.
161+
Storing the node information for the full
162+
planet requires more than 500GB in PostgreSQL, the same data is stored in "only" 90GB using
164163
the flat-nodes mode. This can also increase the speed of applying diff files. This option
165164
activates the flat-nodes mode and specifies the location of the database file. It is a
166165
single large file. This mode is only recommended for full planet imports
167-
as it doesn't work well with small imports. The default is disabled.
166+
as it doesn't work well with small imports. The default is disabled. The
167+
file will stay on disk after import, use \--drop to remove it (but you
168+
can't do updates then).
168169

169170
\--middle-schema=SCHEMA
170171
: Use PostgreSQL schema SCHEMA for all tables, indexes, and functions in the

src/command-line-parser.cpp

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,9 @@ void parse_expire_tiles_param(char const *arg, uint32_t *expire_tiles_zoom_min,
114114
void check_options_non_slim(CLI::App const &app)
115115
{
116116
std::vector<std::string> const slim_options = {
117-
"--flat-nodes", "--middle-schema",
118-
"--middle-with-nodes", "--middle-way-node-index-id-shift",
119-
"--tablespace-slim-data", "--tablespace-slim-index"};
117+
"--middle-schema", "--middle-with-nodes",
118+
"--middle-way-node-index-id-shift", "--tablespace-slim-data",
119+
"--tablespace-slim-index"};
120120

121121
for (auto const &opt : slim_options) {
122122
if (app.count(opt) > 0) {
@@ -190,10 +190,6 @@ void check_options(options_t *options)
190190
throw std::runtime_error{"--append can only be used with slim mode!"};
191191
}
192192

193-
if (options->droptemp && !options->slim) {
194-
throw std::runtime_error{"--drop only makes sense with --slim."};
195-
}
196-
197193
if (options->cache < 0) {
198194
options->cache = 0;
199195
log_warn("RAM cache cannot be negative. Using 0 instead.");
@@ -494,7 +490,7 @@ options_t parse_command_line(int argc, char *argv[])
494490

495491
// --drop
496492
app.add_flag("--drop", options.droptemp)
497-
->description("Drop middle tables after import (needs --slim).")
493+
->description("Drop middle tables and flat node file after import.")
498494
->group("Middle options");
499495

500496
// --extra-attributes
@@ -505,8 +501,8 @@ options_t parse_command_line(int argc, char *argv[])
505501

506502
// --flat-nodes
507503
app.add_option("-F,--flat-nodes", options.flat_node_file)
508-
->description("File for storing node locations (needs --slim,"
509-
" default: store in database).")
504+
->description(
505+
"File for storing node locations (default: store in database).")
510506
->type_name("FILE")
511507
->group("Middle options");
512508

src/middle-ram.cpp

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
* For a full list of authors see the git log.
88
*/
99

10-
#include "logging.hpp"
1110
#include "middle-ram.hpp"
11+
12+
#include "logging.hpp"
13+
#include "node-persistent-cache.hpp"
1214
#include "options.hpp"
1315
#include "output-requirements.hpp"
1416

@@ -75,6 +77,11 @@ middle_ram_t::middle_ram_t(std::shared_ptr<thread_pool_t> thread_pool,
7577
if (options->extra_attributes) {
7678
m_store_options.untagged_nodes = true;
7779
}
80+
81+
if (!options->flat_node_file.empty()) {
82+
m_persistent_cache = std::make_shared<node_persistent_cache>(
83+
options->flat_node_file, options->droptemp);
84+
}
7885
}
7986

8087
void middle_ram_t::set_requirements(output_requirements const &requirements)
@@ -94,6 +101,7 @@ void middle_ram_t::set_requirements(output_requirements const &requirements)
94101

95102
log_debug("Middle 'ram' options:");
96103
log_debug(" locations: {}", m_store_options.locations);
104+
log_debug(" locations_on_disk: {}", !!m_persistent_cache);
97105
log_debug(" way_nodes: {}", m_store_options.way_nodes);
98106
log_debug(" nodes: {}", m_store_options.nodes);
99107
log_debug(" untagged_nodes: {}", m_store_options.untagged_nodes);
@@ -107,8 +115,15 @@ void middle_ram_t::stop()
107115

108116
auto const mbyte = 1024 * 1024;
109117

110-
log_debug("Middle 'ram': Node locations: size={} bytes={}M",
111-
m_node_locations.size(), m_node_locations.used_memory() / mbyte);
118+
if (m_persistent_cache) {
119+
log_debug("Middle 'ram': Node locations on disk: size={} bytes={}M",
120+
m_persistent_cache->size(),
121+
m_persistent_cache->used_memory() / mbyte);
122+
} else {
123+
log_debug("Middle 'ram': Node locations in memory: size={} bytes={}M",
124+
m_node_locations.size(),
125+
m_node_locations.used_memory() / mbyte);
126+
}
112127

113128
log_debug("Middle 'ram': Way nodes data: size={} capacity={} bytes={}M",
114129
m_way_nodes_data.size(), m_way_nodes_data.capacity(),
@@ -180,7 +195,11 @@ void middle_ram_t::node(osmium::Node const &node)
180195
assert(node.visible());
181196

182197
if (m_store_options.locations) {
183-
m_node_locations.set(node.id(), node.location());
198+
if (m_persistent_cache) {
199+
m_persistent_cache->set(node.id(), node.location());
200+
} else {
201+
m_node_locations.set(node.id(), node.location());
202+
}
184203
}
185204

186205
if (m_store_options.nodes &&
@@ -222,7 +241,9 @@ void middle_ram_t::after_nodes()
222241
m_middle_state = middle_state::way;
223242
#endif
224243

225-
m_node_locations.log_stats();
244+
if (!m_persistent_cache) {
245+
m_node_locations.log_stats();
246+
}
226247
}
227248

228249
osmium::Location middle_ram_t::get_node_location(osmid_t id) const
@@ -237,10 +258,19 @@ std::size_t middle_ram_t::nodes_get_list(osmium::WayNodeList *nodes) const
237258
std::size_t count = 0;
238259

239260
if (m_store_options.locations) {
240-
for (auto &nr : *nodes) {
241-
nr.set_location(m_node_locations.get(nr.ref()));
242-
if (nr.location().valid()) {
243-
++count;
261+
if (m_persistent_cache) {
262+
for (auto &nr : *nodes) {
263+
nr.set_location(m_persistent_cache->get(nr.ref()));
264+
if (nr.location().valid()) {
265+
++count;
266+
}
267+
}
268+
} else {
269+
for (auto &nr : *nodes) {
270+
nr.set_location(m_node_locations.get(nr.ref()));
271+
if (nr.location().valid()) {
272+
++count;
273+
}
244274
}
245275
}
246276
}

src/middle-ram.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <string>
2525
#include <utility>
2626

27+
class node_persistent_cache;
2728
class thread_pool_t;
2829

2930
/**
@@ -124,6 +125,10 @@ class middle_ram_t : public middle_t, public middle_query_t
124125

125126
/// Options for this middle.
126127
middle_ram_options m_store_options;
128+
129+
/// File cache
130+
std::shared_ptr<node_persistent_cache> m_persistent_cache;
131+
127132
}; // class middle_ram_t
128133

129134
#endif // OSM2PGSQL_MIDDLE_RAM_HPP

src/node-persistent-cache.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ class node_persistent_cache
3333
void set(osmid_t id, osmium::Location location);
3434
osmium::Location get(osmid_t id) const noexcept;
3535

36+
/// The number of locations stored.
37+
std::size_t size() const { return m_index->size(); }
38+
39+
/// Return the approximate number of bytes used for internal storage.
40+
std::size_t used_memory() const { return m_index->used_memory(); }
41+
3642
private:
3743
using index_t =
3844
osmium::index::map::DenseFileArray<osmium::unsigned_object_id_type,

tests/bdd/regression/multipolygon.feature

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,22 @@ Feature: Import and update of multipolygon areas
137137
| -k | the default |
138138

139139

140+
Scenario: Import with flat-node option
141+
When running osm2pgsql pgsql with parameters
142+
| -F | flat.store | --drop |
143+
144+
Then table planet_osm_polygon contains
145+
| osm_id | landuse | name | round(ST_Area(way)) |
146+
| -1 | residential | Name_rel | 12895 |
147+
| 4 | farmland | Name_way3 | 3144 |
148+
| -8 | residential | Name_rel2 | 12894 |
149+
| 5 | farmland | Name_way4 | 3144 |
150+
| -14 | residential | Name_way5 | 12894 |
151+
| -11 | residential | Name_rel6 | 11529 |
152+
| -3 | residential | Name_rel11| 9286 |
153+
| 83 | farmland | NULL | 24859 |
154+
155+
140156
Scenario: Import and update with flat-node option
141157
When running osm2pgsql pgsql with parameters
142158
| --slim | -F | flat.store |

tests/test-options-parse.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,6 @@ TEST_CASE("Incompatible arguments", "[NoDB]")
4848
{
4949
bad_opt({"-a", "-c", "--slim"}, "options can not be used at the same time");
5050

51-
bad_opt({"--drop"}, "drop only makes sense with");
52-
5351
bad_opt({"-j", "-k"}, "--hstore excludes --hstore-all");
5452

5553
bad_opt({"-a"}, "--append can only be used with slim mode");

0 commit comments

Comments
 (0)