Changeset 3584 in josm


Ignore:
Timestamp:
Oct 3, 2010 3:25:36 PM (3 years ago)
Author:
jttt
Message:

Fix #5525 Error when adding a node in the middle of a way

Location:
trunk/src/org/openstreetmap/josm/data/osm
Files:
2 edited

Legend:

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

    r3541 r3584  
    152152 
    153153    public List<Node> searchNodes(BBox bbox) { 
    154         return nodes.search(bbox); 
     154        lock.readLock().lock(); 
     155        try { 
     156            return nodes.search(bbox); 
     157        } finally { 
     158            lock.readLock().unlock(); 
     159        } 
    155160    } 
    156161 
     
    172177 
    173178    public List<Way> searchWays(BBox bbox) { 
    174         return ways.search(bbox); 
     179        lock.readLock().lock(); 
     180        try { 
     181            return ways.search(bbox); 
     182        } finally { 
     183            lock.readLock().unlock(); 
     184        } 
    175185    } 
    176186 
     
    190200 
    191201    public List<Relation> searchRelations(BBox bbox) { 
    192         // QuadBuckets might be useful here (don't forget to do reindexing after some of rm is changed) 
    193         List<Relation> result = new ArrayList<Relation>(); 
    194         for (Relation r: relations) { 
    195             if (r.getBBox().intersects(bbox)) { 
    196                 result.add(r); 
    197             } 
    198         } 
    199         return result; 
     202        lock.readLock().lock(); 
     203        try { 
     204            // QuadBuckets might be useful here (don't forget to do reindexing after some of rm is changed) 
     205            List<Relation> result = new ArrayList<Relation>(); 
     206            for (Relation r: relations) { 
     207                if (r.getBBox().intersects(bbox)) { 
     208                    result.add(r); 
     209                } 
     210            } 
     211            return result; 
     212        } finally { 
     213            lock.readLock().unlock(); 
     214        } 
    200215    } 
    201216 
  • trunk/src/org/openstreetmap/josm/data/osm/QuadBuckets.java

    r3476 r3584  
    1414 * Note: bbox of primitives added to QuadBuckets has to stay the same. In case of coordinate change, primitive must 
    1515 * be removed and readded. 
     16 * 
     17 * This class is (no longer) thread safe. 
    1618 * 
    1719 */ 
     
    2426    private static final int SE_INDEX = 2; 
    2527    private static final int SW_INDEX = 0; 
    26     /* 
    27      * Functions prefixed with __ need locking before 
    28      * being called. 
    29      */ 
    30     private final Object split_lock = new Object(); 
    3128 
    3229    static void abort(String s) 
     
    169166        boolean remove_content(T o) 
    170167        { 
    171             synchronized (split_lock) { 
    172                 // If two threads try to remove item at the same time from different buckets of this QBLevel, 
    173                 // it might happen that one thread removes bucket but don't remove parent because it still sees 
    174                 // another bucket set. Second thread do the same. Due to thread memory caching, it's possible that 
    175                 // changes made by threads will show up in children array too late, leading to QBLevel with all children 
    176                 // set to null 
    177                 if (content == null) 
    178                     return false; 
    179                 boolean ret = this.content.remove(o); 
    180                 if (this.content.size() == 0) { 
    181                     this.content = null; 
    182                 } 
    183                 if (this.canRemove()) { 
    184                     this.remove_from_parent(); 
    185                 } 
    186                 return ret; 
    187             } 
     168            // If two threads try to remove item at the same time from different buckets of this QBLevel, 
     169            // it might happen that one thread removes bucket but don't remove parent because it still sees 
     170            // another bucket set. Second thread do the same. Due to thread memory caching, it's possible that 
     171            // changes made by threads will show up in children array too late, leading to QBLevel with all children 
     172            // set to null 
     173            if (content == null) 
     174                return false; 
     175            boolean ret = this.content.remove(o); 
     176            if (this.content.size() == 0) { 
     177                this.content = null; 
     178            } 
     179            if (this.canRemove()) { 
     180                this.remove_from_parent(); 
     181            } 
     182            return ret; 
    188183        } 
    189184        // Get the correct index for the given primitive 
     
    394389                } 
    395390            } 
    396             synchronized (split_lock) { 
    397                 __add_content(o); 
    398                 if (isLeaf() && content.size() > MAX_OBJECTS_PER_LEVEL && level < QuadTiling.NR_LEVELS) { 
    399                     __split(); 
    400                 } 
     391            __add_content(o); 
     392            if (isLeaf() && content.size() > MAX_OBJECTS_PER_LEVEL && level < QuadTiling.NR_LEVELS) { 
     393                __split(); 
    401394            } 
    402395        } 
    403396 
    404397        void add(T o) { 
    405             synchronized (split_lock) { 
    406                 findBucket(o.getBBox()).doAdd(o); 
    407             } 
     398            findBucket(o.getBBox()).doAdd(o); 
    408399        } 
    409400 
     
    529520    } 
    530521    public void clear()  { 
    531         synchronized (split_lock) { 
    532             root = new QBLevel(); 
    533             search_cache = null; 
    534             size = 0; 
    535             if (debug) { 
    536                 out("QuadBuckets() cleared: " + this); 
    537                 out("root: " + root + " level: " + root.level + " bbox: " + root.bbox()); 
    538             } 
     522        root = new QBLevel(); 
     523        search_cache = null; 
     524        size = 0; 
     525        if (debug) { 
     526            out("QuadBuckets() cleared: " + this); 
     527            out("root: " + root + " level: " + root.level + " bbox: " + root.bbox()); 
    539528        } 
    540529    } 
    541530    public boolean add(T n) { 
    542         synchronized (split_lock) { 
    543             root.add(n); 
    544             size++; 
    545             return true; 
    546         } 
    547     } 
     531        root.add(n); 
     532        size++; 
     533        return true; 
     534    } 
     535 
    548536    public void unsupported() 
    549537    { 
     
    588576    public boolean remove(Object o) { 
    589577        @SuppressWarnings("unchecked") T t = (T) o; 
    590         synchronized (split_lock) { 
    591             search_cache = null; // Search cache might point to one of removed buckets 
    592             QBLevel bucket = root.findBucket(t.getBBox()); 
    593             if (bucket.remove_content(t)) { 
    594                 size--; 
    595                 return true; 
    596             } else 
    597                 return false; 
    598         } 
     578        search_cache = null; // Search cache might point to one of removed buckets 
     579        QBLevel bucket = root.findBucket(t.getBBox()); 
     580        if (bucket.remove_content(t)) { 
     581            size--; 
     582            return true; 
     583        } else 
     584            return false; 
    599585    } 
    600586    public boolean contains(Object o) { 
     
    634620            QBLevel orig = q; 
    635621            QBLevel next; 
    636             synchronized (split_lock) { 
    637                 next = q.nextContentNode(); 
    638             } 
     622            next = q.nextContentNode(); 
    639623            //if (consistency_testing && (orig == next)) 
    640624            if (orig == next) { 
     
    726710    } 
    727711    public int size() { 
    728         synchronized (split_lock) { 
    729             return size; 
    730         } 
     712        return size; 
    731713    } 
    732714 
Note: See TracChangeset for help on using the changeset viewer.