Ignore:
Timestamp:
2009-09-27T18:15:34+02:00 (15 years ago)
Author:
jttt
Message:

Save way nodes as array instead of ArrayList to save memory

File:
1 edited

Legend:

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

    r2181 r2204  
    22package org.openstreetmap.josm.data.osm;
    33
     4import static org.openstreetmap.josm.tools.I18n.tr;
     5
    46import java.util.ArrayList;
    5 
    67import java.util.Arrays;
    78import java.util.Collection;
     
    1112import org.openstreetmap.josm.tools.CopyList;
    1213import org.openstreetmap.josm.tools.Pair;
    13 import static org.openstreetmap.josm.tools.I18n.tr;
    1414
    1515/**
     
    2424     *
    2525     */
    26     private final List<Node> nodes = new ArrayList<Node>();
     26    private Node[] nodes = new Node[0];
    2727
    2828    /**
     
    3434     */
    3535    public List<Node> getNodes() {
    36         return new CopyList<Node>(nodes.toArray(new Node[nodes.size()]));
    37     }
    38 
    39     /**
     36        return new CopyList<Node>(nodes);
     37    }
     38
     39    /**
     40     * Set new list of nodes to way. This method is preferred to multiple calls to addNode/removeNode
     41     * and similar methods because nodes are internally saved as array which means lower memory overhead
     42     * but also slower modifying operations.
    4043     * @param nodes New way nodes. Can be null, in that case all way nodes are removed
    4144     * @since 1862
    4245     */
    4346    public void setNodes(List<Node> nodes) {
    44         this.nodes.clear();
    45         if (nodes != null) {
    46             this.nodes.addAll(nodes);
     47        if (nodes == null) {
     48            this.nodes = new Node[0];
     49        } else {
     50            this.nodes = nodes.toArray(new Node[nodes.size()]);
    4751        }
    4852        clearCached();
     
    5155    /**
    5256     * Replies the number of nodes in this ways.
    53      * 
     57     *
    5458     * @return the number of nodes in this ways.
    5559     * @since 1862
    5660     */
    5761    public int getNodesCount() {
    58         return nodes.size();
     62        return nodes.length;
    5963    }
    6064
    6165    /**
    6266     * Replies the node at position <code>index</code>.
    63      * 
     67     *
    6468     * @param index the position
    6569     * @return  the node at position <code>index</code>
     
    6973     */
    7074    public Node getNode(int index) {
    71         return nodes.get(index);
     75        return nodes[index];
    7276    }
    7377
     
    7579     * Replies true if this way contains the node <code>node</code>, false
    7680     * otherwise. Replies false if  <code>node</code> is null.
    77      * 
     81     *
    7882     * @param node the node. May be null.
    7983     * @return true if this way contains the node <code>node</code>, false
     
    8387    public boolean containsNode(Node node) {
    8488        if (node == null) return false;
    85         return nodes.contains(node);
     89        for (int i=0; i<nodes.length; i++) {
     90            if (nodes[i].equals(node)) {
     91                return true;
     92            }
     93        }
     94        return false;
    8695    }
    8796
     
    122131    /**
    123132     * Creates a new way with id 0.
    124      * 
     133     *
    125134     */
    126135    public Way(){
     
    130139    /**
    131140     * Create an identical clone of the argument (including the id).
    132      * 
     141     *
    133142     * @param original  the original way. Must not be null.
    134143     */
     
    141150     * Creates a new way for the given id. If the id > 0, the way is marked
    142151     * as incomplete.
    143      * 
     152     *
    144153     * @param id the id. > 0 required
    145154     * @throws IllegalArgumentException thrown if id < 0
     
    151160    @Override public void cloneFrom(OsmPrimitive osm) {
    152161        super.cloneFrom(osm);
    153         nodes.clear();
    154         nodes.addAll(((Way)osm).nodes);
     162        Way otherWay = (Way)osm;
     163        nodes = new Node[otherWay.nodes.length];
     164        System.arraycopy(otherWay.nodes, 0, nodes, 0, otherWay.nodes.length);
    155165    }
    156166
    157167    @Override public String toString() {
    158168        if (incomplete) return "{Way id="+getId()+" version="+getVersion()+" (incomplete)}";
    159         return "{Way id="+getId()+" version="+getVersion()+" nodes="+Arrays.toString(nodes.toArray())+"}";
     169        return "{Way id="+getId()+" version="+getVersion()+" nodes="+Arrays.toString(nodes)+"}";
    160170    }
    161171
     
    180190        boolean closed = (lastNode() == n && firstNode() == n);
    181191        int i;
    182         while ((i = nodes.indexOf(n)) >= 0) {
    183             nodes.remove(i);
    184         }
    185         i = nodes.size();
     192        List<Node> copy = getNodes();
     193        while ((i = copy.indexOf(n)) >= 0) {
     194            copy.remove(i);
     195        }
     196        i = copy.size();
    186197        if (closed && i > 2) {
    187198            addNode(firstNode());
    188         } else if (i >= 2 && i <= 3 && nodes.get(0) == nodes.get(i-1)) {
    189             nodes.remove(i-1);
    190         }
     199        } else if (i >= 2 && i <= 3 && copy.get(0) == copy.get(i-1)) {
     200            copy.remove(i-1);
     201        }
     202        setNodes(copy);
    191203    }
    192204
     
    202214    /**
    203215     * Adds a node to the end of the list of nodes. Ignored, if n is null.
    204      * 
     216     *
    205217     * @param n the node. Ignored, if null.
    206218     * @throws IllegalStateException thrown, if this way is marked as incomplete. We can't add a node
     
    211223        if (incomplete)
    212224            throw new IllegalStateException(tr("Cannot add node {0} to incomplete way {1}.", n.getId(), getId()));
    213         if (incomplete) return;
    214225        clearCached();
    215         nodes.add(n);
     226        Node[] newNodes = new Node[nodes.length + 1];
     227        System.arraycopy(nodes, 0, newNodes, 0, nodes.length);
     228        newNodes[nodes.length] = n;
     229        nodes = newNodes;
    216230    }
    217231
    218232    /**
    219233     * Adds a node at position offs.
    220      * 
     234     *
    221235     * @param int offs the offset
    222236     * @param n the node. Ignored, if null.
     
    230244            throw new IllegalStateException(tr("Cannot add node {0} to incomplete way {1}.", n.getId(), getId()));
    231245        clearCached();
    232         nodes.add(offs, n);
     246        Node[] newNodes = new Node[nodes.length + 1];
     247        System.arraycopy(nodes, 0, newNodes, 0, offs);
     248        System.arraycopy(nodes, offs, newNodes, offs + 1, nodes.length - offs);
     249        newNodes[offs] = n;
     250        nodes = newNodes;
    233251    }
    234252
    235253    public boolean isClosed() {
    236254        if (incomplete) return false;
    237         return nodes.size() >= 3 && lastNode() == firstNode();
     255        return nodes.length >= 3 && lastNode() == firstNode();
    238256    }
    239257
    240258    public Node lastNode() {
    241         if (incomplete || nodes.size() == 0) return null;
    242         return nodes.get(nodes.size()-1);
     259        if (incomplete || nodes.length == 0) return null;
     260        return nodes[nodes.length-1];
    243261    }
    244262
    245263    public Node firstNode() {
    246         if (incomplete || nodes.size() == 0) return null;
    247         return nodes.get(0);
     264        if (incomplete || nodes.length == 0) return null;
     265        return nodes[0];
    248266    }
    249267
    250268    public boolean isFirstLastNode(Node n) {
    251         if (incomplete || nodes.size() == 0) return false;
     269        if (incomplete || nodes.length == 0) return false;
    252270        return n == firstNode() || n == lastNode();
    253271    }
Note: See TracChangeset for help on using the changeset viewer.