Ticket #8643: purgemod3.diff

File purgemod3.diff, 3.8 KB (added by bilbo, 13 years ago)

Patch that fixes both O(N2) loops

  • src/org/openstreetmap/josm/actions/PurgeAction.java

     
    9797
    9898        // Add referrer, unless the object to purge is not new
    9999        // and the parent is a relation
     100        HashSet<OsmPrimitive> toPurgeRecursive = new HashSet<OsmPrimitive>();
    100101        while (!toPurge.isEmpty()) {
    101             OsmPrimitive osm = toPurge.iterator().next();
     102
     103          for (OsmPrimitive osm: toPurge) {
    102104            for (OsmPrimitive parent: osm.getReferrers()) {
    103                 if (toPurge.contains(parent) || toPurgeChecked.contains(parent)) {
     105                if (toPurge.contains(parent) || toPurgeChecked.contains(parent) || toPurgeRecursive.contains(parent)) {
    104106                    continue;
    105107                }
    106108                if (parent instanceof Way || (parent instanceof Relation && osm.isNew())) {
    107109                    toPurgeAdditionally.add(parent);
    108                     toPurge.add(parent);
     110                    toPurgeRecursive.add(parent);
    109111                }
    110112            }
    111             toPurge.remove(osm);
    112113            toPurgeChecked.add(osm);
     114          }
     115          toPurge = toPurgeRecursive;
     116          toPurgeRecursive = new HashSet<OsmPrimitive>();
    113117        }
    114118
    115119        makeIncomplete = new HashSet<OsmPrimitive>();
  • src/org/openstreetmap/josm/command/PurgeCommand.java

     
    132132
    133133        List<OsmPrimitive> out = new ArrayList<OsmPrimitive>(in.size());
    134134
     135        // Nodes not deleted in the first pass
     136        Set<OsmPrimitive> remainingNodes = new HashSet<OsmPrimitive>(in.size());
     137
    135138        /**
    136139         *  First add nodes that have no way referrer.
    137140         */
     
    142145                    Node n = (Node) u;
    143146                    for (OsmPrimitive ref : n.getReferrers()) {
    144147                        if (ref instanceof Way && in.contains(ref)) {
     148                            it.remove();
     149                            remainingNodes.add(n);
    145150                            continue outer;
    146151                        }
    147152                    }
     
    153158        /**
    154159         * Then add all ways, each preceded by its (remaining) nodes.
    155160         */
    156         top: while (!in.isEmpty()) {
    157             for (Iterator<OsmPrimitive> it = in.iterator(); it.hasNext();) {
    158                 OsmPrimitive u = it.next();
    159                 if (u instanceof Way) {
    160                     Way w = (Way) u;
    161                     it.remove();
    162                     for (Node n : w.getNodes()) {
    163                         if (in.contains(n)) {
    164                             in.remove(n);
    165                             out.add(n);
    166                         }
     161        for (Iterator<OsmPrimitive> it = in.iterator(); it.hasNext();) {
     162            OsmPrimitive u = it.next();
     163            if (u instanceof Way) {
     164                Way w = (Way) u;
     165                it.remove();
     166                for (Node n : w.getNodes()) {
     167                    if (remainingNodes.contains(n)) {
     168                        remainingNodes.remove(n);
     169                        out.add(n);
    167170                    }
    168                     out.add(w);
    169                     continue top;
    170171                }
     172                out.add(w);
    171173            }
    172             break; // no more ways left
    173174        }
    174175
     176        if (!remainingNodes.isEmpty())
     177            throw new AssertionError("topo sort algorithm failed (nodes remaining)");
     178
    175179        /**
    176180            * Rest are relations. Do topological sorting on a DAG where each
    177181            * arrow points from child to parent. (Because it is faster to