Changeset 4520 in josm


Ignore:
Timestamp:
Oct 15, 2011 9:46:37 PM (20 months ago)
Author:
simon04
Message:

see #6964 - Improve Start-up Time by removing blocking queue, concurrency in XmlObjectParser

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/tools/XmlObjectParser.java

    r3612 r4520  
    1111import java.util.HashMap; 
    1212import java.util.Iterator; 
     13import java.util.LinkedList; 
    1314import java.util.Map; 
    14 import java.util.NoSuchElementException; 
    1515import java.util.Stack; 
    16 import java.util.concurrent.ArrayBlockingQueue; 
    17 import java.util.concurrent.BlockingQueue; 
    1816 
    1917import javax.xml.parsers.SAXParser; 
    2018import javax.xml.parsers.SAXParserFactory; 
    21 import javax.xml.transform.Source; 
    2219import javax.xml.transform.stream.StreamSource; 
    2320import javax.xml.validation.Schema; 
     
    9592        private Iterator<Object> iterator; 
    9693        /** 
    97          * @param klass This has to be specified since generics are ereased from 
     94         * @param klass This has to be specified since generics are erased from 
    9895         * class files so the JVM cannot deduce T itself. 
    9996         */ 
     
    135132    private class Parser extends DefaultHandler { 
    136133        Stack<Object> current = new Stack<Object>(); 
    137         String characters = ""; 
     134        StringBuilder characters = new StringBuilder(64); 
    138135 
    139136        private Locator locator; 
     
    162159                    report(); 
    163160                } 
    164                 if (mapping.get(qname).both) 
    165                 { 
    166                     try { 
    167                         queue.put(current.peek()); 
    168                     } catch (InterruptedException e) { 
    169                     } 
     161                if (mapping.get(qname).both) { 
     162                    queue.add(current.peek()); 
    170163                } 
    171164            } 
     
    175168                report(); 
    176169            } else if (characters != null && !current.isEmpty()) { 
    177                 setValue(qname, characters.trim()); 
    178                 characters = ""; 
     170                setValue(qname, characters.toString().trim()); 
     171                characters  = new StringBuilder(64); 
    179172            } 
    180173        } 
    181174        @Override public void characters(char[] ch, int start, int length) { 
    182             String s = new String(ch, start, length); 
    183             characters += s; 
     175            characters.append(ch, start, length); 
    184176        } 
    185177 
    186178        private void report() { 
    187             try { 
    188                 queue.put(current.pop()); 
    189             } catch (InterruptedException e) { 
    190             } 
    191             characters = ""; 
     179            queue.add(current.pop()); 
     180            characters  = new StringBuilder(64); 
    192181        } 
    193182 
     
    249238 
    250239        private boolean parseBoolean(String s) { 
    251             return s != null && 
    252             !s.equals("0") && 
    253             !s.startsWith("off") && 
    254             !s.startsWith("false") && 
    255             !s.startsWith("no"); 
     240            return s != null 
     241                    && !s.equals("0") 
     242                    && !s.startsWith("off") 
     243                    && !s.startsWith("false") 
     244                    && !s.startsWith("no"); 
    256245        } 
    257246 
     
    285274     * The queue of already parsed items from the parsing thread. 
    286275     */ 
    287     private BlockingQueue<Object> queue = new ArrayBlockingQueue<Object>(10); 
    288  
    289     /** 
    290      * This stores one item retrieved from the queue to give hasNext a chance. 
    291      * So this is also the object that will be returned on the next call to next(). 
    292      */ 
    293     private Object lookAhead = null; 
    294  
    295     /** 
    296      * This object represent the end of the stream (null is not allowed as 
    297      * member in class Queue). 
    298      */ 
    299     private Object EOS = new Object(); 
     276    private LinkedList<Object> queue = new LinkedList<Object>(); 
     277    private Iterator<Object> queueIterator = null; 
    300278 
    301279    public XmlObjectParser() { 
     
    308286 
    309287    private Iterable<Object> start(final Reader in, final ContentHandler contentHandler) { 
    310         new Thread("XML Reader"){ 
    311             @Override public void run() { 
    312                 try { 
    313                     SAXParserFactory parserFactory = SAXParserFactory.newInstance(); 
    314                     parserFactory.setNamespaceAware(true); 
    315                     SAXParser parser = parserFactory.newSAXParser(); 
    316                     XMLReader reader = parser.getXMLReader(); 
    317                     reader.setContentHandler(contentHandler); 
    318                     reader.parse(new InputSource(in)); 
    319                 } catch (Exception e) { 
    320                     try { 
    321                         queue.put(e); 
    322                     } catch (InterruptedException e1) { 
    323                     } 
    324                 } 
    325                 try { 
    326                     queue.put(EOS); 
    327                 } catch (InterruptedException e) { 
    328                 } 
    329             } 
    330         }.start(); 
     288        try { 
     289            SAXParserFactory parserFactory = SAXParserFactory.newInstance(); 
     290            parserFactory.setNamespaceAware(true); 
     291            SAXParser saxParser = parserFactory.newSAXParser(); 
     292            XMLReader reader = saxParser.getXMLReader(); 
     293            reader.setContentHandler(contentHandler); 
     294            reader.parse(new InputSource(in)); 
     295        } catch (Exception e) { 
     296            throw new RuntimeException(e); 
     297        } 
     298        queueIterator = queue.iterator(); 
    331299        return this; 
    332300    } 
     
    364332    } 
    365333 
    366     /** 
    367      * @return The next object from the xml stream or <code>null</code>, 
    368      * if no more objects. 
    369      */ 
    370     public Object next() throws SAXException { 
    371         fillLookAhead(); 
    372         if (lookAhead == EOS) 
    373             throw new NoSuchElementException(); 
    374         Object o = lookAhead; 
    375         lookAhead = null; 
    376         return o; 
    377     } 
    378  
    379     private void fillLookAhead() throws SAXException { 
    380         if (lookAhead != null) 
    381             return; 
    382         try { 
    383             lookAhead = queue.take(); 
    384             if (lookAhead instanceof SAXException) 
    385                 throw (SAXException)lookAhead; 
    386             else if (lookAhead instanceof RuntimeException) 
    387                 throw (RuntimeException)lookAhead; 
    388             else if (lookAhead instanceof Exception) 
    389                 throw new SAXException((Exception)lookAhead); 
    390         } catch (InterruptedException e) { 
    391             throw new RuntimeException("XmlObjectParser must not be interrupted.", e); 
    392         } 
    393     } 
    394  
    395     public boolean hasNext() throws SAXException { 
    396         fillLookAhead(); 
    397         return lookAhead != EOS; 
    398     } 
    399  
     334    public Object next() { 
     335        return queueIterator.next(); 
     336    } 
     337 
     338    public boolean hasNext() { 
     339        return queueIterator.hasNext(); 
     340    } 
     341 
     342    @Override 
    400343    public Iterator<Object> iterator() { 
    401         return new Iterator<Object>(){ 
    402             public boolean hasNext() { 
    403                 try { 
    404                     return XmlObjectParser.this.hasNext(); 
    405                 } catch (SAXException e) { 
    406                     e.printStackTrace(); 
    407                     throw new RuntimeException(e); 
    408                 } 
    409             } 
    410             public Object next() { 
    411                 try { 
    412                     return XmlObjectParser.this.next(); 
    413                 } catch (SAXException e) { 
    414                     e.printStackTrace(); 
    415                     throw new RuntimeException(e); 
    416                 } 
    417             } 
    418             public void remove() { 
    419                 throw new UnsupportedOperationException(); 
    420             } 
    421         }; 
     344        return queue.iterator(); 
    422345    } 
    423346} 
Note: See TracChangeset for help on using the changeset viewer.