Ignore:
Timestamp:
2017-02-26T00:59:32+01:00 (7 years ago)
Author:
Don-vip
Message:

fix #3346 - improve drastically the performance of fixing duplicate nodes by:

  • caching data sources area computation
  • moving layer invalidation from UndoRedoHandler.addNoRedraw to UndoRedoHandler.add
  • avoiding any EDT call when building tag conflict dialog if it's not meant to be displayed
Location:
trunk/src/org/openstreetmap/josm/data
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/UndoRedoHandler.java

    r11553 r11627  
    5252        CheckParameterUtil.ensureParameterNotNull(c, "c");
    5353        c.executeCommand();
    54         c.invalidateAffectedLayers();
    5554        commands.add(c);
    5655        // Limit the number of commands in the undo list.
     
    8180        }
    8281        addNoRedraw(c);
     82        c.invalidateAffectedLayers();
    8383        afterAdd();
    8484
  • trunk/src/org/openstreetmap/josm/data/osm/DataSet.java

    r11440 r11627  
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
     6import java.awt.geom.Area;
    67import java.util.ArrayList;
    78import java.util.Arrays;
     
    2526
    2627import org.openstreetmap.josm.Main;
     28import org.openstreetmap.josm.data.Bounds;
    2729import org.openstreetmap.josm.data.Data;
    2830import org.openstreetmap.josm.data.DataSource;
     
    127129    private final Object selectionLock = new Object();
    128130
     131    private Area cachedDataSourceArea;
     132    private List<Bounds> cachedDataSourceBounds;
     133
    129134    /**
    130135     * Constructs a new {@code DataSet}.
     
    184189            copyFrom.getReadLock().unlock();
    185190        }
     191    }
     192
     193    /**
     194     * Adds a new data source.
     195     * @param source data source to add
     196     * @return {@code true} if the collection changed as a result of the call
     197     * @since 11626
     198     */
     199    public synchronized boolean addDataSource(DataSource source) {
     200        return addDataSources(Collections.singleton(source));
     201    }
     202
     203    /**
     204     * Adds new data sources.
     205     * @param sources data sources to add
     206     * @return {@code true} if the collection changed as a result of the call
     207     * @since 11626
     208     */
     209    public synchronized boolean addDataSources(Collection<DataSource> sources) {
     210        boolean changed = dataSources.addAll(sources);
     211        if (changed) {
     212            cachedDataSourceArea = null;
     213            cachedDataSourceBounds = null;
     214        }
     215        return changed;
    186216    }
    187217
     
    917947            fireSelectionChanged();
    918948        }
     949    }
     950
     951    @Override
     952    public synchronized Area getDataSourceArea() {
     953        if (cachedDataSourceArea == null) {
     954            cachedDataSourceArea = Data.super.getDataSourceArea();
     955        }
     956        return cachedDataSourceArea;
     957    }
     958
     959    @Override
     960    public synchronized List<Bounds> getDataSourceBounds() {
     961        if (cachedDataSourceBounds == null) {
     962            cachedDataSourceBounds = Data.super.getDataSourceBounds();
     963        }
     964        return Collections.unmodifiableList(cachedDataSourceBounds);
    919965    }
    920966
     
    13341380     * @param progressMonitor The progress monitor
    13351381     */
    1336     public void mergeFrom(DataSet from, ProgressMonitor progressMonitor) {
     1382    public synchronized void mergeFrom(DataSet from, ProgressMonitor progressMonitor) {
    13371383        if (from != null) {
    13381384            new DataSetMerger(this, from).merge(progressMonitor);
    1339             dataSources.addAll(from.dataSources);
    1340             from.dataSources.clear();
     1385            if (!from.dataSources.isEmpty()) {
     1386                if (dataSources.addAll(from.dataSources)) {
     1387                    cachedDataSourceArea = null;
     1388                    cachedDataSourceBounds = null;
     1389                }
     1390                from.dataSources.clear();
     1391                from.cachedDataSourceArea = null;
     1392                from.cachedDataSourceBounds = null;
     1393            }
    13411394        }
    13421395    }
  • trunk/src/org/openstreetmap/josm/data/validation/tests/DuplicateNode.java

    r11590 r11627  
    309309    @Override
    310310    public Command fixError(TestError testError) {
    311         if (!isFixable(testError)) return null;
    312311        Collection<OsmPrimitive> sel = new LinkedList<>(testError.getPrimitives());
    313312        Set<Node> nodes = new LinkedHashSet<>(OsmPrimitive.getFilteredList(sel, Node.class));
  • trunk/src/org/openstreetmap/josm/data/validation/tests/DuplicateRelation.java

    r11452 r11627  
    293293        }
    294294
    295         //Delete all relations in the list
     295        // Delete all relations in the list
    296296        relFix.remove(relationToKeep);
    297297        commands.add(new DeleteCommand(relFix));
     
    306306        // We fix it only if there is no more than one relation that is relation member.
    307307        Collection<? extends OsmPrimitive> sel = testError.getPrimitives();
    308         Set<Relation> relations = new HashSet<>();
     308        Set<Relation> rels = new HashSet<>();
    309309
    310310        for (OsmPrimitive osm : sel) {
    311311            if (osm instanceof Relation) {
    312                 relations.add((Relation) osm);
    313             }
    314         }
    315 
    316         if (relations.size() < 2)
     312                rels.add((Relation) osm);
     313            }
     314        }
     315
     316        if (rels.size() < 2)
    317317            return false;
    318318
    319319        int relationsWithRelations = 0;
    320         for (Relation w : relations) {
     320        for (Relation w : rels) {
    321321            List<Relation> rel = OsmPrimitive.getFilteredList(w.getReferrers(), Relation.class);
    322322            if (!rel.isEmpty()) {
  • trunk/src/org/openstreetmap/josm/data/validation/tests/DuplicateWay.java

    r11129 r11627  
    249249    public Command fixError(TestError testError) {
    250250        Collection<? extends OsmPrimitive> sel = testError.getPrimitives();
    251         Set<Way> ways = new HashSet<>();
     251        Set<Way> wayz = new HashSet<>();
    252252
    253253        for (OsmPrimitive osm : sel) {
    254254            if (osm instanceof Way && !osm.isDeleted()) {
    255                 ways.add((Way) osm);
    256             }
    257         }
    258 
    259         if (ways.size() < 2)
     255                wayz.add((Way) osm);
     256            }
     257        }
     258
     259        if (wayz.size() < 2)
    260260            return null;
    261261
    262262        long idToKeep = 0;
    263         Way wayToKeep = ways.iterator().next();
     263        Way wayToKeep = wayz.iterator().next();
    264264        // Find the way that is member of one or more relations. (If any)
    265265        Way wayWithRelations = null;
    266266        List<Relation> relations = null;
    267         for (Way w : ways) {
     267        for (Way w : wayz) {
    268268            List<Relation> rel = OsmPrimitive.getFilteredList(w.getReferrers(), Relation.class);
    269269            if (!rel.isEmpty()) {
     
    284284
    285285        // Fix relations.
    286         if (wayWithRelations != null && wayToKeep != wayWithRelations) {
     286        if (wayWithRelations != null && relations != null && wayToKeep != wayWithRelations) {
    287287            for (Relation rel : relations) {
    288288                Relation newRel = new Relation(rel);
     
    297297        }
    298298
    299         //Delete all ways in the list
    300         //Note: nodes are not deleted, these can be detected and deleted at next pass
    301         ways.remove(wayToKeep);
    302         commands.add(new DeleteCommand(ways));
     299        // Delete all ways in the list
     300        // Note: nodes are not deleted, these can be detected and deleted at next pass
     301        wayz.remove(wayToKeep);
     302        commands.add(new DeleteCommand(wayz));
    303303        return new SequenceCommand(tr("Delete duplicate ways"), commands);
    304304    }
     
    309309            return false;
    310310
    311         //Do not automatically fix same ways with different tags
     311        // Do not automatically fix same ways with different tags
    312312        if (testError.getCode() != DUPLICATE_WAY) return false;
    313313
    314314        // We fix it only if there is no more than one way that is relation member.
    315315        Collection<? extends OsmPrimitive> sel = testError.getPrimitives();
    316         Set<Way> ways = new HashSet<>();
     316        Set<Way> wayz = new HashSet<>();
    317317
    318318        for (OsmPrimitive osm : sel) {
    319319            if (osm instanceof Way) {
    320                 ways.add((Way) osm);
    321             }
    322         }
    323 
    324         if (ways.size() < 2)
     320                wayz.add((Way) osm);
     321            }
     322        }
     323
     324        if (wayz.size() < 2)
    325325            return false;
    326326
    327327        int waysWithRelations = 0;
    328         for (Way w : ways) {
     328        for (Way w : wayz) {
    329329            List<Relation> rel = OsmPrimitive.getFilteredList(w.getReferrers(), Relation.class);
    330330            if (!rel.isEmpty()) {
Note: See TracChangeset for help on using the changeset viewer.