Ignore:
Timestamp:
2010-06-27T17:07:49+02:00 (14 years ago)
Author:
jttt
Message:

Thread safe Dataset and OsmPrimitive, read/write lock for dataset

File:
1 edited

Legend:

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

    r3254 r3348  
    4747     */
    4848    public void setNodes(List<Node> nodes) {
    49         for (Node node:this.nodes) {
    50             node.removeReferrer(this);
    51         }
    52 
    53         if (nodes == null) {
    54             this.nodes = new Node[0];
    55         } else {
    56             this.nodes = nodes.toArray(new Node[nodes.size()]);
    57         }
    58         for (Node node:this.nodes) {
    59             node.addReferrer(this);
    60         }
    61 
    62         clearCached();
    63         fireNodesChanged();
     49        boolean locked = writeLock();
     50        try {
     51            for (Node node:this.nodes) {
     52                node.removeReferrer(this);
     53            }
     54
     55            if (nodes == null) {
     56                this.nodes = new Node[0];
     57            } else {
     58                this.nodes = nodes.toArray(new Node[nodes.size()]);
     59            }
     60            for (Node node:this.nodes) {
     61                node.addReferrer(this);
     62            }
     63
     64            clearCached();
     65            fireNodesChanged();
     66        } finally {
     67            writeUnlock(locked);
     68        }
    6469    }
    6570
     
    98103    public boolean containsNode(Node node) {
    99104        if (node == null) return false;
     105
     106        Node[] nodes = this.nodes;
    100107        for (int i=0; i<nodes.length; i++) {
    101108            if (nodes[i].equals(node))
     
    115122    }
    116123
    117     public ArrayList<Pair<Node,Node>> getNodePairs(boolean sort) {
    118         ArrayList<Pair<Node,Node>> chunkSet = new ArrayList<Pair<Node,Node>>();
     124    public List<Pair<Node,Node>> getNodePairs(boolean sort) {
     125        List<Pair<Node,Node>> chunkSet = new ArrayList<Pair<Node,Node>>();
    119126        if (isIncomplete()) return chunkSet;
    120127        Node lastN = null;
    121         for (Node n : this.nodes) {
     128        Node[] nodes = this.nodes;
     129        for (Node n : nodes) {
    122130            if (lastN == null) {
    123131                lastN = n;
     
    198206    @Override
    199207    public void load(PrimitiveData data) {
    200         super.load(data);
    201 
    202         WayData wayData = (WayData) data;
    203 
    204         List<Node> newNodes = new ArrayList<Node>(wayData.getNodes().size());
    205         for (Long nodeId : wayData.getNodes()) {
    206             Node node = (Node)getDataSet().getPrimitiveById(nodeId, OsmPrimitiveType.NODE);
    207             if (node != null) {
    208                 newNodes.add(node);
    209             } else
    210                 throw new AssertionError("Data consistency problem - way with missing node detected");
    211         }
    212         setNodes(newNodes);
     208        boolean locked = writeLock();
     209        try {
     210            super.load(data);
     211
     212            WayData wayData = (WayData) data;
     213
     214            List<Node> newNodes = new ArrayList<Node>(wayData.getNodes().size());
     215            for (Long nodeId : wayData.getNodes()) {
     216                Node node = (Node)getDataSet().getPrimitiveById(nodeId, OsmPrimitiveType.NODE);
     217                if (node != null) {
     218                    newNodes.add(node);
     219                } else
     220                    throw new AssertionError("Data consistency problem - way with missing node detected");
     221            }
     222            setNodes(newNodes);
     223        } finally {
     224            writeUnlock(locked);
     225        }
    213226    }
    214227
     
    223236
    224237    @Override public void cloneFrom(OsmPrimitive osm) {
    225         super.cloneFrom(osm);
    226         Way otherWay = (Way)osm;
    227         setNodes(otherWay.getNodes());
     238        boolean locked = writeLock();
     239        try {
     240            super.cloneFrom(osm);
     241            Way otherWay = (Way)osm;
     242            setNodes(otherWay.getNodes());
     243        } finally {
     244            writeUnlock(locked);
     245        }
    228246    }
    229247
     
    256274    public void removeNode(Node n) {
    257275        if (isIncomplete()) return;
    258         boolean closed = (lastNode() == n && firstNode() == n);
    259         int i;
    260         List<Node> copy = getNodes();
    261         while ((i = copy.indexOf(n)) >= 0) {
    262             copy.remove(i);
    263         }
    264         i = copy.size();
    265         if (closed && i > 2) {
    266             copy.add(copy.get(0));
    267         } else if (i >= 2 && i <= 3 && copy.get(0) == copy.get(i-1)) {
    268             copy.remove(i-1);
    269         }
    270         setNodes(copy);
     276        boolean locked = writeLock();
     277        try {
     278            boolean closed = (lastNode() == n && firstNode() == n);
     279            int i;
     280            List<Node> copy = getNodes();
     281            while ((i = copy.indexOf(n)) >= 0) {
     282                copy.remove(i);
     283            }
     284            i = copy.size();
     285            if (closed && i > 2) {
     286                copy.add(copy.get(0));
     287            } else if (i >= 2 && i <= 3 && copy.get(0) == copy.get(i-1)) {
     288                copy.remove(i-1);
     289            }
     290            setNodes(copy);
     291        } finally {
     292            writeUnlock(locked);
     293        }
    271294    }
    272295
    273296    public void removeNodes(Collection<? extends OsmPrimitive> selection) {
    274297        if (isIncomplete()) return;
    275         for(OsmPrimitive p : selection) {
    276             if (p instanceof Node) {
    277                 removeNode((Node)p);
    278             }
     298        boolean locked = writeLock();
     299        try {
     300            for(OsmPrimitive p : selection) {
     301                if (p instanceof Node) {
     302                    removeNode((Node)p);
     303                }
     304            }
     305        } finally {
     306            writeUnlock(locked);
    279307        }
    280308    }
     
    289317    public void addNode(Node n) throws IllegalStateException {
    290318        if (n==null) return;
    291         if (isIncomplete())
    292             throw new IllegalStateException(tr("Cannot add node {0} to incomplete way {1}.", n.getId(), getId()));
    293         clearCached();
    294         n.addReferrer(this);
    295         Node[] newNodes = new Node[nodes.length + 1];
    296         System.arraycopy(nodes, 0, newNodes, 0, nodes.length);
    297         newNodes[nodes.length] = n;
    298         nodes = newNodes;
    299         fireNodesChanged();
     319
     320        boolean locked = writeLock();
     321        try {
     322            if (isIncomplete())
     323                throw new IllegalStateException(tr("Cannot add node {0} to incomplete way {1}.", n.getId(), getId()));
     324            clearCached();
     325            n.addReferrer(this);
     326            Node[] newNodes = new Node[nodes.length + 1];
     327            System.arraycopy(nodes, 0, newNodes, 0, nodes.length);
     328            newNodes[nodes.length] = n;
     329            nodes = newNodes;
     330            fireNodesChanged();
     331        } finally {
     332            writeUnlock(locked);
     333        }
    300334    }
    301335
     
    311345    public void addNode(int offs, Node n) throws IllegalStateException, IndexOutOfBoundsException {
    312346        if (n==null) return;
    313         if (isIncomplete())
    314             throw new IllegalStateException(tr("Cannot add node {0} to incomplete way {1}.", n.getId(), getId()));
    315         clearCached();
    316         n.addReferrer(this);
    317         Node[] newNodes = new Node[nodes.length + 1];
    318         System.arraycopy(nodes, 0, newNodes, 0, offs);
    319         System.arraycopy(nodes, offs, newNodes, offs + 1, nodes.length - offs);
    320         newNodes[offs] = n;
    321         nodes = newNodes;
    322         fireNodesChanged();
     347
     348        boolean locked = writeLock();
     349        try {
     350            if (isIncomplete())
     351                throw new IllegalStateException(tr("Cannot add node {0} to incomplete way {1}.", n.getId(), getId()));
     352
     353            clearCached();
     354            n.addReferrer(this);
     355            Node[] newNodes = new Node[nodes.length + 1];
     356            System.arraycopy(nodes, 0, newNodes, 0, offs);
     357            System.arraycopy(nodes, offs, newNodes, offs + 1, nodes.length - offs);
     358            newNodes[offs] = n;
     359            nodes = newNodes;
     360            fireNodesChanged();
     361        } finally {
     362            writeUnlock(locked);
     363        }
    323364    }
    324365
    325366    @Override
    326367    public void setDeleted(boolean deleted) {
    327         for (Node n:nodes) {
    328             if (deleted) {
    329                 n.removeReferrer(this);
    330             } else {
    331                 n.addReferrer(this);
    332             }
    333         }
    334         fireNodesChanged();
    335         super.setDeleted(deleted);
     368        boolean locked = writeLock();
     369        try {
     370            for (Node n:nodes) {
     371                if (deleted) {
     372                    n.removeReferrer(this);
     373                } else {
     374                    n.addReferrer(this);
     375                }
     376            }
     377            fireNodesChanged();
     378            super.setDeleted(deleted);
     379        } finally {
     380            writeUnlock(locked);
     381        }
    336382    }
    337383
    338384    public boolean isClosed() {
    339385        if (isIncomplete()) return false;
    340         return nodes.length >= 3 && lastNode() == firstNode();
     386
     387        Node[] nodes = this.nodes;
     388        return nodes.length >= 3 && nodes[nodes.length-1] == nodes[0];
    341389    }
    342390
    343391    public Node lastNode() {
     392        Node[] nodes = this.nodes;
    344393        if (isIncomplete() || nodes.length == 0) return null;
    345394        return nodes[nodes.length-1];
     
    347396
    348397    public Node firstNode() {
     398        Node[] nodes = this.nodes;
    349399        if (isIncomplete() || nodes.length == 0) return null;
    350400        return nodes[0];
     
    352402
    353403    public boolean isFirstLastNode(Node n) {
     404        Node[] nodes = this.nodes;
    354405        if (isIncomplete() || nodes.length == 0) return false;
    355         return n == firstNode() || n == lastNode();
     406        return n == nodes[0] || n == nodes[nodes.length -1];
    356407    }
    357408
     
    368419        DataSet dataSet = getDataSet();
    369420        if (dataSet != null) {
     421            Node[] nodes = this.nodes;
    370422            for (Node n: nodes) {
    371423                if (n.getDataSet() != dataSet)
     
    412464
    413465    public boolean hasIncompleteNodes() {
     466        Node[] nodes = this.nodes;
    414467        for (Node node:nodes) {
    415468            if (node.isIncomplete())
Note: See TracChangeset for help on using the changeset viewer.