Permalink
Browse files

XML parser pool example

  • Loading branch information...
1 parent fa8e4ef commit 446cbf4d60150e62cf0095c84fd321d317b88671 Andrey Paramonov committed Feb 11, 2010
Showing with 116 additions and 0 deletions.
  1. +19 −0 xmlparser/XmlParserPool.java
  2. +36 −0 xmlparser/XmlParserPoolableObjectFactory.java
  3. +61 −0 xmlparser/XmlParserTest.groovy
@@ -0,0 +1,19 @@
+import org.apache.commons.pool.impl.GenericObjectPool;
+
+public class XmlParserPool {
+
+ private final GenericObjectPool pool;
+
+ public XmlParserPool(int maxActive) {
+ pool = new GenericObjectPool(new XmlParserPoolableObjectFactory(), maxActive,
+ GenericObjectPool.WHEN_EXHAUSTED_BLOCK, 0);
+ }
+
+ public Object borrowObject() throws Exception {
+ return pool.borrowObject();
+ }
+
+ public void returnObject(Object obj) throws Exception {
+ pool.returnObject(obj);
+ }
+}
@@ -0,0 +1,36 @@
+import javax.xml.parsers.SAXParserFactory;
+import org.apache.commons.pool.PoolableObjectFactory;
+
+public class XmlParserPoolableObjectFactory implements PoolableObjectFactory {
+
+ private SAXParserFactory parserFactory;
+
+ public XmlParserPoolableObjectFactory() {
+ parserFactory = SAXParserFactory.newInstance();
+ }
+
+ @Override
+ public Object makeObject() throws Exception {
+ return parserFactory.newSAXParser();
+ }
+
+ @Override
+ public boolean validateObject(Object obj) {
+ return true;
+ }
+
+ @Override
+ public void activateObject(Object obj) throws Exception {
+ // Do nothing
+ }
+
+ @Override
+ public void destroyObject(Object obj) throws Exception {
+ // Do nothing
+ }
+
+ @Override
+ public void passivateObject(Object obj) throws Exception {
+ // Do nothing
+ }
+}
@@ -0,0 +1,61 @@
+import org.junit.*
+
+class XmlParserTest {
+
+ static XmlParserPool parserPool = new XmlParserPool(1000)
+
+ static int iterations = 1000
+ static int threadCount = 5
+
+ static {
+ // warm up the environment
+ new XmlSlurper()
+ }
+
+ def xml = """
+ <root>
+ <node1 aName='aValue'>
+ <node1.1 aName='aValue'>1.1</node1.1>
+ <node1.2 aName='aValue'>1.2</node1.2>
+ <node1.3 aName='aValue'>1.3</node1.3>
+ </node1>
+ <node2 aName='aValue'>
+ <node2.1 aName='aValue'>2.1</node2.1>
+ <node2.2 aName='aValue'>2.2</node2.2>
+ <node2.3 aName='aValue'>2.3</node2.3>
+ </node2>
+ <nodeN aName='aValue'>
+ <nodeN.1 aName='aValue'>N.1</nodeN.1>
+ <nodeN.2 aName='aValue'>N.2</nodeN.2>
+ <nodeN.3 aName='aValue'>N.3</nodeN.3>
+ </nodeN>
+ </root>
+ """
+
+ def parseSequential() {
+ iterations.times {
+ def parser = parserPool.borrowObject()
+ def root = new XmlSlurper(parser).parseText(xml)
+ parserPool.returnObject(parser)
+ assert 'aValue' == root.node1.@aName.toString()
+ }
+ }
+
+ @Test void testSequentialXmlParsing() {
+ long start = System.currentTimeMillis()
+ parseSequential()
+ long stop = System.currentTimeMillis()
+ println "${iterations} XML documents parsed sequentially in ${stop-start} ms"
+ }
+
+ @Test void testParallelXmlParsing() {
+ def threads = []
+ long start = System.currentTimeMillis()
+ threadCount.times {
+ threads << Thread.start { parseSequential() }
+ }
+ threads.each { it.join() }
+ long stop = System.currentTimeMillis()
+ println "${threadCount*iterations} XML documents parsed parallelly by ${threadCount} threads in ${stop-start} ms"
+ }
+}

0 comments on commit 446cbf4

Please sign in to comment.