Ticket #22808: 22808.3.patch

File 22808.3.patch, 5.7 KB (added by taylor.smock, 20 months ago)

Avoid calling clearSelection for each removed primitive in bulk removal methods

  • src/org/openstreetmap/josm/command/AddPrimitivesCommand.java

    Subject: [PATCH] Fix #22808: Undoing "Paste" for ways of a route relation is very slow
    ---
    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/src/org/openstreetmap/josm/command/AddPrimitivesCommand.java b/src/org/openstreetmap/josm/command/AddPrimitivesCommand.java
    a b  
    1717import org.openstreetmap.josm.data.osm.NodeData;
    1818import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1919import org.openstreetmap.josm.data.osm.PrimitiveData;
     20import org.openstreetmap.josm.data.osm.PrimitiveId;
    2021import org.openstreetmap.josm.tools.CheckParameterUtil;
    2122
    2223/**
     
    127128            createdPrimitives = PurgeCommand.topoSort(createdPrimitives);
    128129        }
    129130        // reversed order, see #14620
    130         for (int i = createdPrimitives.size() - 1; i >= 0; i--) {
    131             OsmPrimitive osm = createdPrimitives.get(i);
    132             Optional<PrimitiveData> previous = preExistingData.stream()
    133                     .filter(pd -> pd.getPrimitiveId().equals(osm.getPrimitiveId())).findAny();
    134             if (previous.isPresent()) {
    135                 osm.load(previous.get());
    136             } else {
    137                 ds.removePrimitive(osm);
    138             }
    139         }
     131        final List<PrimitiveId> toRemove = new ArrayList<>(this.createdPrimitives.size());
     132        ds.update(() -> {
     133                    for (int i = createdPrimitives.size() - 1; i >= 0; i--) {
     134                        OsmPrimitive osm = createdPrimitives.get(i);
     135                        Optional<PrimitiveData> previous = preExistingData.stream()
     136                                .filter(pd -> pd.getPrimitiveId().equals(osm.getPrimitiveId())).findAny();
     137                        if (previous.isPresent()) {
     138                            osm.load(previous.get());
     139                        } else {
     140                            toRemove.add(osm);
     141                        }
     142                    }
     143                });
     144        ds.removePrimitives(toRemove);
    140145    }
    141146
    142147    @Override
  • src/org/openstreetmap/josm/data/osm/DataSet.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/src/org/openstreetmap/josm/data/osm/DataSet.java b/src/org/openstreetmap/josm/data/osm/DataSet.java
    a b  
    55
    66import java.awt.geom.Area;
    77import java.util.ArrayList;
     8import java.util.Arrays;
    89import java.util.Collection;
    910import java.util.Collections;
    1011import java.util.HashMap;
     
    564565        });
    565566    }
    566567
     568    /**
     569     * Removes primitives from the dataset. This method only removes the
     570     * primitives form the respective collection of primitives managed
     571     * by this dataset, i.e. from {@code store.nodes}, {@code store.ways}, or
     572     * {@code store.relations}. References from other primitives to this
     573     * primitive are left unchanged.
     574     *
     575     * @param primitiveIds the ids of the primitive
     576     * @throws IllegalStateException if the dataset is read-only
     577     * @since xxx
     578     */
     579    public void removePrimitives(PrimitiveId... primitiveIds) {
     580        this.removePrimitives(Arrays.asList(primitiveIds));
     581    }
     582
     583    /**
     584     * Removes primitives from the dataset. This method only removes the
     585     * primitives form the respective collection of primitives managed
     586     * by this dataset, i.e. from {@code store.nodes}, {@code store.ways}, or
     587     * {@code store.relations}. References from other primitives to this
     588     * primitive are left unchanged.
     589     *
     590     * @param primitiveIds the ids of the primitive
     591     * @throws IllegalStateException if the dataset is read-only
     592     * @since xxx
     593     */
     594    public void removePrimitives(Collection<PrimitiveId> primitiveIds) {
     595        checkModifiable();
     596        final List<PrimitiveId> selected = new ArrayList<>();
     597        update(() -> {
     598            clearSelection(primitiveIds);
     599            final List<OsmPrimitive> removed = new ArrayList<>(primitiveIds.size());
     600            for (PrimitiveId primitiveId : primitiveIds) {
     601                OsmPrimitive primitive = this.getPrimitiveByIdChecked(primitiveId);
     602                if (primitive == null) {
     603                    continue;
     604                } else if (primitive.isSelected()) {
     605                    selected.add(primitive);
     606                }
     607                this.removePrimitiveFromStorage(primitive);
     608                removed.add(primitive);
     609            }
     610            firePrimitivesRemoved(removed, false);
     611        });
     612        if (!selected.isEmpty()) {
     613            throw new DataIntegrityProblemException("Primitives were re-selected by a selection listener: "
     614            + selected.stream().map(PrimitiveId::toString).collect(Collectors.joining(", ")));
     615        }
     616    }
     617
    567618    private void removePrimitiveImpl(OsmPrimitive primitive) {
    568619        clearSelection(primitive.getPrimitiveId());
    569620        if (primitive.isSelected()) {
    570621            throw new DataIntegrityProblemException("Primitive was re-selected by a selection listener: " + primitive);
    571622        }
     623        this.removePrimitiveFromStorage(primitive);
     624    }
     625
     626    private void removePrimitiveFromStorage(OsmPrimitive primitive) {
    572627        store.removePrimitive(primitive);
    573628        allPrimitives.remove(primitive);
    574629        primitive.setDataset(null);