Ticket #18654: 18654.diff

File 18654.diff, 15.1 KB (added by Don-vip, 6 years ago)
  • src/org/openstreetmap/josm/data/osm/AbstractPrimitive.java

     
    1717import java.util.Objects;
    1818import java.util.Set;
    1919import java.util.concurrent.TimeUnit;
    20 import java.util.concurrent.atomic.AtomicLong;
    2120import java.util.function.BiPredicate;
    2221
    2322import org.openstreetmap.josm.data.gpx.GpxConstants;
     
    3130 */
    3231public abstract class AbstractPrimitive implements IPrimitive {
    3332
    34     private static final AtomicLong idCounter = new AtomicLong(0);
    35 
    36     /**
    37      * Generates a new primitive unique id.
    38      * @return new primitive unique (negative) id
    39      */
    40     static long generateUniqueId() {
    41         return idCounter.decrementAndGet();
    42     }
    43 
    44     /**
    45      * Returns the current primitive unique id.
    46      * @return the current primitive unique (negative) id (last generated)
    47      * @since 12536
    48      */
    49     public static long currentUniqueId() {
    50         return idCounter.get();
    51     }
    52 
    53     /**
    54      * Advances the current primitive unique id to skip a range of values.
    55      * @param newId new unique id
    56      * @throws IllegalArgumentException if newId is greater than current unique id
    57      * @since 12536
    58      */
    59     public static void advanceUniqueId(long newId) {
    60         if (newId > currentUniqueId()) {
    61             throw new IllegalArgumentException("Cannot modify the id counter backwards");
    62         }
    63         idCounter.set(newId);
    64     }
    65 
    6633    /**
    6734     * This flag shows, that the properties have been changed by the user
    6835     * and on upload the object will be send to the server.
     
    283250     */
    284251    public void clearOsmMetadata() {
    285252        // Not part of dataset - no lock necessary
    286         this.id = generateUniqueId();
     253        this.id = getIdGenerator().generateUniqueId();
    287254        this.version = 0;
    288255        this.user = null;
    289256        this.changesetId = 0; // reset changeset id on a new object
     
    293260        this.setVisible(true);
    294261    }
    295262
     263    /**
     264     * Returns the unique identifier generator.
     265     * @return the unique identifier generator
     266     * @since xxx
     267     */
     268    public abstract UniqueIdGenerator getIdGenerator();
     269
    296270    @Override
    297271    public User getUser() {
    298272        return user;
  • src/org/openstreetmap/josm/data/osm/Node.java

     
    2626 */
    2727public final class Node extends OsmPrimitive implements INode {
    2828
     29    static final UniqueIdGenerator idGenerator = new UniqueIdGenerator();
     30
    2931    /*
    3032     * We "inline" lat/lon rather than using a LatLon-object => reduces memory footprint
    3133     */
     
    422424        }
    423425        return false;
    424426    }
     427
     428    @Override
     429    public UniqueIdGenerator getIdGenerator() {
     430        return idGenerator;
     431    }
    425432}
  • src/org/openstreetmap/josm/data/osm/NodeData.java

     
    1212public class NodeData extends PrimitiveData implements INode {
    1313
    1414    private static final long serialVersionUID = 5626323599550908773L;
     15    private static final UniqueIdGenerator idGenerator = Node.idGenerator;
    1516    /*
    1617     * we "inline" lat/lon coordinates instead of using a LatLon => reduces memory footprint
    1718     */
     
    2324     */
    2425    public NodeData() {
    2526        // contents can be set later with setters
     27        this(idGenerator.generateUniqueId());
    2628    }
    2729
    2830    /**
     
    108110    public boolean isReferredByWays(int n) {
    109111        return false;
    110112    }
     113
     114    @Override
     115    public UniqueIdGenerator getIdGenerator() {
     116        return idGenerator;
     117    }
    111118}
  • src/org/openstreetmap/josm/data/osm/OsmPrimitive.java

     
    111111            if (id < 0)
    112112                throw new IllegalArgumentException(MessageFormat.format("Expected ID >= 0. Got {0}.", id));
    113113            else if (id == 0) {
    114                 this.id = generateUniqueId();
     114                this.id = getIdGenerator().generateUniqueId();
    115115            } else {
    116116                this.id = id;
    117117            }
  • src/org/openstreetmap/josm/data/osm/OsmPrimitiveType.java

     
    1515public enum OsmPrimitiveType {
    1616
    1717    /** Node type */
    18     NODE(marktr(/* ICON(data/) */"node"), Node.class, NodeData.class),
     18    NODE(marktr(/* ICON(data/) */"node"), Node.class, NodeData.class, Node.idGenerator),
    1919    /** Way type */
    20     WAY(marktr(/* ICON(data/) */"way"), Way.class, WayData.class),
     20    WAY(marktr(/* ICON(data/) */"way"), Way.class, WayData.class, Way.idGenerator),
    2121    /** Relation type */
    22     RELATION(marktr(/* ICON(data/) */"relation"), Relation.class, RelationData.class),
     22    RELATION(marktr(/* ICON(data/) */"relation"), Relation.class, RelationData.class, Relation.idGenerator),
    2323
    2424    /** Closed way: only for display, no real type */
    25     CLOSEDWAY(marktr(/* ICON(data/) */"closedway"), null, WayData.class),
     25    CLOSEDWAY(marktr(/* ICON(data/) */"closedway"), null, WayData.class, Way.idGenerator),
    2626    /** Multipolygon: only for display, no real type */
    27     MULTIPOLYGON(marktr(/* ICON(data/) */"multipolygon"), null, RelationData.class);
     27    MULTIPOLYGON(marktr(/* ICON(data/) */"multipolygon"), null, RelationData.class, Relation.idGenerator);
    2828
    2929    private static final Collection<OsmPrimitiveType> DATA_VALUES = Arrays.asList(NODE, WAY, RELATION);
    3030
    3131    private final String apiTypeName;
    3232    private final Class<? extends OsmPrimitive> osmClass;
    3333    private final Class<? extends PrimitiveData> dataClass;
     34    private final UniqueIdGenerator idGenerator;
    3435
    35     OsmPrimitiveType(String apiTypeName, Class<? extends OsmPrimitive> osmClass, Class<? extends PrimitiveData> dataClass) {
     36    OsmPrimitiveType(String apiTypeName, Class<? extends OsmPrimitive> osmClass, Class<? extends PrimitiveData> dataClass,
     37            UniqueIdGenerator idGenerator) {
    3638        this.apiTypeName = apiTypeName;
    3739        this.osmClass = osmClass;
    3840        this.dataClass = dataClass;
     41        this.idGenerator = idGenerator;
    3942    }
    4043
    4144    /**
     
    153156        }
    154157    }
    155158
     159    /**
     160     * Returns the unique identifier generator.
     161     * @return the unique identifier generator
     162     * @since xxx
     163     */
     164    public final UniqueIdGenerator getIdGenerator() {
     165        return idGenerator;
     166    }
     167
    156168    @Override
    157169    public String toString() {
    158170        return tr(getAPIName());
  • src/org/openstreetmap/josm/data/osm/PrimitiveData.java

     
    2727    private static final long serialVersionUID = -1044837092478109138L;
    2828
    2929    /**
    30      * Constructs a new {@code PrimitiveData}.
    31      */
    32     public PrimitiveData() {
    33         this(OsmPrimitive.generateUniqueId());
    34     }
    35 
    36     /**
    3730     * Constructs a new {@code PrimitiveData} with given id.
    3831     * @param id id
    3932     * @since 12017
  • src/org/openstreetmap/josm/data/osm/Relation.java

     
    2828 */
    2929public final class Relation extends OsmPrimitive implements IRelation<RelationMember> {
    3030
     31    static final UniqueIdGenerator idGenerator = new UniqueIdGenerator();
     32
    3133    private RelationMember[] members = new RelationMember[0];
    3234
    3335    private BBox bbox;
     
    549551                .filter(m -> m instanceof OsmPrimitive)
    550552                .map(m -> (OsmPrimitive) m).collect(Collectors.toList());
    551553    }
     554
     555    @Override
     556    public UniqueIdGenerator getIdGenerator() {
     557        return idGenerator;
     558    }
    552559}
  • src/org/openstreetmap/josm/data/osm/RelationData.java

     
    1313public class RelationData extends PrimitiveData implements IRelation<RelationMemberData> {
    1414
    1515    private static final long serialVersionUID = 1163664954890478565L;
     16    private static final UniqueIdGenerator idGenerator = Relation.idGenerator;
    1617    private List<RelationMemberData> members = new ArrayList<>();
    1718
    1819    /**
     
    2021     */
    2122    public RelationData() {
    2223        // contents can be set later with setters
     24        this(idGenerator.generateUniqueId());
    2325    }
    2426
    2527    /**
     
    99101    public BBox getBBox() {
    100102        throw new UnsupportedOperationException();
    101103    }
     104
     105    @Override
     106    public UniqueIdGenerator getIdGenerator() {
     107        return idGenerator;
     108    }
    102109}
  • src/org/openstreetmap/josm/data/osm/UniqueIdGenerator.java

     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.data.osm;
     3
     4import java.util.concurrent.atomic.AtomicLong;
     5
     6/**
     7 * Generator of unique identifiers.
     8 * @since xxx
     9 */
     10public final class UniqueIdGenerator {
     11
     12    private final AtomicLong idCounter = new AtomicLong(0);
     13
     14    /**
     15     * Generates a new primitive unique id.
     16     * @return new primitive unique (negative) id
     17     */
     18    long generateUniqueId() {
     19        return idCounter.decrementAndGet();
     20    }
     21
     22    /**
     23     * Returns the current primitive unique id.
     24     * @return the current primitive unique (negative) id (last generated)
     25     */
     26    public long currentUniqueId() {
     27        return idCounter.get();
     28    }
     29
     30    /**
     31     * Advances the current primitive unique id to skip a range of values.
     32     * @param newId new unique id
     33     * @throws IllegalArgumentException if newId is greater than current unique id
     34     */
     35    public void advanceUniqueId(long newId) {
     36        if (newId > currentUniqueId()) {
     37            throw new IllegalArgumentException("Cannot modify the id counter backwards");
     38        }
     39        idCounter.set(newId);
     40    }
     41}
  • src/org/openstreetmap/josm/data/osm/Way.java

    Property changes on: src\org\openstreetmap\josm\data\osm\UniqueIdGenerator.java
    ___________________________________________________________________
    Added: svn:eol-style
    ## -0,0 +1 ##
    +native
     
    2828 */
    2929public final class Way extends OsmPrimitive implements IWay<Node> {
    3030
     31    static final UniqueIdGenerator idGenerator = new UniqueIdGenerator();
     32
    3133    /**
    3234     * All way nodes in this way
    3335     */
     
    748750
    749751        return angles;
    750752    }
     753
     754    @Override
     755    public UniqueIdGenerator getIdGenerator() {
     756        return idGenerator;
     757    }
    751758}
  • src/org/openstreetmap/josm/data/osm/WayData.java

     
    1313public class WayData extends PrimitiveData implements IWay<NodeData> {
    1414
    1515    private static final long serialVersionUID = 106944939313286415L;
     16    private static final UniqueIdGenerator idGenerator = Way.idGenerator;
    1617    private List<Long> nodes = new ArrayList<>();
    1718
    1819    /**
     
    2021     */
    2122    public WayData() {
    2223        // contents can be set later with setters
     24        this(idGenerator.generateUniqueId());
    2325    }
    2426
    2527    /**
     
    129131    public boolean isInnerNode(INode n) {
    130132        throw new UnsupportedOperationException();
    131133    }
     134
     135    @Override
     136    public UniqueIdGenerator getIdGenerator() {
     137        return idGenerator;
     138    }
    132139}
  • src/org/openstreetmap/josm/io/AbstractReader.java

     
    325325        } catch (IOException e) {
    326326            throw new IllegalDataException(e);
    327327        } finally {
    328             OptionalLong minId = externalIdMap.values().stream().mapToLong(AbstractPrimitive::getUniqueId).min();
    329             synchronized (AbstractPrimitive.class) {
    330                 if (minId.isPresent() && minId.getAsLong() < AbstractPrimitive.currentUniqueId()) {
    331                     AbstractPrimitive.advanceUniqueId(minId.getAsLong());
     328            for (OsmPrimitiveType dataType : OsmPrimitiveType.dataValues()) {
     329                OptionalLong minId = externalIdMap.entrySet().parallelStream()
     330                        .filter(e -> e.getKey().getType() == dataType)
     331                        .mapToLong(e -> e.getValue().getUniqueId()).min();
     332                synchronized (dataType.getDataClass()) {
     333                    if (minId.isPresent() && minId.getAsLong() < dataType.getIdGenerator().currentUniqueId()) {
     334                        dataType.getIdGenerator().advanceUniqueId(minId.getAsLong());
     335                    }
    332336                }
    333337            }
    334338            progressMonitor.finishTask();
     
    614618
    615619    protected OsmPrimitive buildPrimitive(PrimitiveData pd) {
    616620        OsmPrimitive p;
    617         if (pd.getUniqueId() < AbstractPrimitive.currentUniqueId()) {
     621        if (pd.getUniqueId() < pd.getIdGenerator().currentUniqueId()) {
    618622            p = pd.getType().newInstance(pd.getUniqueId(), true);
    619             AbstractPrimitive.advanceUniqueId(pd.getUniqueId());
     623            pd.getIdGenerator().advanceUniqueId(pd.getUniqueId());
    620624        } else {
    621625            p = pd.getType().newVersionedInstance(pd.getId(), pd.getVersion());
    622626        }
     
    654658
    655659    protected final Node parseNode(String lat, String lon, CommonReader commonReader, NodeReader nodeReader)
    656660            throws IllegalDataException {
    657         NodeData nd = new NodeData();
     661        NodeData nd = new NodeData(0);
    658662        LatLon ll = null;
    659663        if (areLatLonDefined(lat, lon)) {
    660664            try {