Opened 5 years ago
Last modified 4 years ago
#18970 new enhancement
Way.hasIncompleteNodes() should remember the result
Reported by: | GerdP | Owned by: | team |
---|---|---|---|
Priority: | normal | Milestone: | |
Component: | Core | Version: | |
Keywords: | validator mapcss performance | Cc: |
Description
Since Way.isUsable() calls this method we should store the result in a Boolean instead of doing the
Arrays.stream(nodes).anyMatch(Node::isIncomplete);
again and again. Most ways don't have incomplete nodes.
Attachments (2)
Change History (10)
by , 5 years ago
Attachment: | 18970.patch added |
---|
comment:1 by , 5 years ago
A flag is better. No need to add an additional boolean for all ways where a single bit is needed.
comment:2 by , 5 years ago
While you're at it, you can modify the Relation
class to also use this new flag for hasIncompleteMembers()
implementation.
follow-up: 4 comment:3 by , 5 years ago
OK, I try. my first patch doesn't work anyway as a way is not updated when a node changes its status regarding incompleteness. Please check OsmPrimitive.setIncomplete()
. Why does it fire PrimitiveRemoved or PrimitiveAdded?
This looks like a copy&paste error made in r3348, code for setDeleted()
and setIncomplete()
were both changed.
comment:4 by , 5 years ago
comment:6 by , 5 years ago
I wonder if this could explain some of the "IAE: Node is already deleted" errors?
by , 5 years ago
Attachment: | 18970.2.patch added |
---|
use flags, remember status also for relations, add unit tests
comment:7 by , 5 years ago
Please review. I don't fully understand the meaning of the allowWithoutDataset flag in OsmPrimitive.referrers(boolean allowWithoutDataset, Class<T> filter)
comment:8 by , 4 years ago
Is the performance of Way.hasIncompleteNodes
an actual issue? I dislike the complexity of the update mechanism – it's spread over many functions and hard to reason about…
An alternative approach could be to cache ALL_COMPLETE_NODES
as flag (this assumes that a node will never transition from complete to incomplete), such as shown in this draft:
// org.openstreetmap.josm.data.osm.Way public boolean hasIncompleteNodes() { if ((flags & ALL_COMPLETE_NODES) != 0) { return false; } boolean isIncomplete = Arrays.stream(nodes).anyMatch(Node::isIncomplete); if (!isIncomplete) { updateFlags(ALL_COMPLETE_NODES, true); } return isIncomplete; } private static final short ALL_COMPLETE_NODES = 1 << 14;
Would this be the right way to do it?