Skip to content

Fix relations read several times with --store when relation blocks are subdivided - #980

Open
geoneutrino wants to merge 1 commit into
systemed:masterfrom
geoneutrino:fix/store-relation-subdivision
Open

geoneutrino wants to merge 1 commit into
systemed:masterfrom
geoneutrino:fix/store-relation-subdivision

Conversation

@geoneutrino

Copy link
Copy Markdown
Contributor

With --store (sharded stores), relations are processed threadNum times when an extract's ways fall into more than one shard and there are fewer than 2 * threadNum relation blocks. Each shard pass subdivided the remaining relation blocks again, and since ReadBlock never erases subdivided blocks, the second pass created threadNum copies of every chunk.

Effect: duplicated multipolygon features in the tiles, and output that depends on the thread count. The planet is not affected (enough relation blocks), and neither is the CI test area (single shard).

Fix: subdivide only once.

Measured on test data (OpenMapTiles profile, --store):

12 threads 4 threads without --store
master 14,347,612 features 14,249,548
this PR 14,212,774 14,212,774 14,212,774

Example: one z3 landcover tile contained the same mangrove polygon 12 times with 12 threads and 4 times with 4 threads; now once. Unit tests pass.

Found while verifying the deterministic-output work from discussion #969: together with those changes, --store output is byte-identical for 1, 4 and 12 threads and to the output without --store.

…e subdivided

With sharded stores (the default with --store) the relations phase runs once
per shard. When there are fewer than 2 * threadNum relation blocks, each pass
subdivided the remaining blocks into threadNum chunks. ReadBlock never erases
subdivided blocks, so the pass for the next shard subdivided the chunks again:
threadNum * threadNum entries, each chunk threadNum times, and every relation
of that shard was processed threadNum times.

This only happens with --store, an extract whose ways fall into more than one
shard, and few relation blocks, e.g. a country extract crossing a shard
border. The duplicated multipolygons end up as identical features in the
tiles, so the output also depended on the thread count.

Subdivide only once. On test data with --store the tiles had 14,347,612
features with 12 threads and 14,249,548 with 4 threads (12,258 extra
features per additional copy); now both have 14,212,774, the same as without
--store.
@dktue

dktue commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

Reviewed: the fix looks right to me. Subdivided blocks are never reported as done by ReadBlock, so they stay in blocks, and every later shard pass subdivided them again; subdividing only once avoids that.

One data point on when it triggers, in case it helps judge how common it is: I couldn't reproduce it on Norway with --store (6 shards, 187 relation blocks), even at 96 threads. Way blocks are also only removed in the pass for the last shard, and Norway's last shard is empty, so that pass is skipped. At the relations phase, blocks still holds the 4,359 way blocks, and with 4,546 entries the blocks.size() < threadNum * 2 condition never holds. So it needs an extract whose ways reach the last shard. As expected, Norway's output is the same with and without this PR (only the usual poi differences).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants