Changeset 4520 in josm for trunk


Ignore:
Timestamp:
2011-10-15T21:46:37+02:00 (13 years 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.