Author: rhauch
Date: 2009-04-14 12:41:54 -0400 (Tue, 14 Apr 2009)
New Revision: 822
Added:
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractJcrAccessTest.java
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrReadingTest.java
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrWritingTest.java
Log:
DNA-351 Performance Test for JCR Access
Applied the patch, which adds a number of new simple performance tests for measuring reads
and writes through the JCR layer.
Added: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractJcrAccessTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractJcrAccessTest.java
(rev 0)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractJcrAccessTest.java 2009-04-14
16:41:54 UTC (rev 822)
@@ -0,0 +1,271 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * JBoss DNA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.jcr;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+import java.io.PrintStream;
+import java.util.concurrent.TimeUnit;
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import org.jboss.dna.common.statistic.Stopwatch;
+import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.Graph;
+import org.jboss.dna.graph.connector.RepositoryConnection;
+import org.jboss.dna.graph.connector.RepositoryConnectionFactory;
+import org.jboss.dna.graph.connector.RepositorySourceException;
+import org.jboss.dna.graph.connector.inmemory.InMemoryRepositorySource;
+import org.jboss.dna.graph.property.PathFactory;
+import org.junit.After;
+import org.junit.Before;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Support class for performance testing of various operations over subtrees of the
content graph
+ */
+
+public abstract class AbstractJcrAccessTest {
+
+ private InMemoryRepositorySource source;
+ private JcrSession session;
+ private JcrRepository repository;
+
+ @Before
+ public void beforeEach() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ String workspaceName = "workspace1";
+
+ // Set up the source ...
+ source = new InMemoryRepositorySource();
+ source.setName(workspaceName);
+ source.setDefaultWorkspaceName(workspaceName);
+
+ // Set up the execution context ...
+ ExecutionContext context = new ExecutionContext();
+ // Register the test namespace
+ context.getNamespaceRegistry().register(TestLexicon.Namespace.PREFIX,
TestLexicon.Namespace.URI);
+
+ // Set up the initial content ...
+ Graph graph = Graph.create(source, context);
+
+ // Make sure the path to the namespaces exists ...
+ graph.create("/jcr:system"); //
.and().create("/jcr:system/dna:namespaces");
+
graph.set("jcr:primaryType").on("/jcr:system").to(DnaLexicon.SYSTEM);
+
+ // Stub out the connection factory ...
+ RepositoryConnectionFactory connectionFactory = new RepositoryConnectionFactory()
{
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.connector.RepositoryConnectionFactory#createConnection(java.lang.String)
+ */
+ @SuppressWarnings( "synthetic-access" )
+ public RepositoryConnection createConnection( String sourceName ) throws
RepositorySourceException {
+ return source.getConnection();
+ }
+ };
+
+ repository = new JcrRepository(context, connectionFactory, "unused");
+
+ session = (JcrSession) repository.login();
+ }
+
+ @After
+ public void after() throws Exception {
+ if (session != null && session.isLive()) {
+ session.logout();
+ }
+ }
+
+ protected JcrSession session() {
+ return this.session;
+ }
+
+ private String getRandomString(int length) {
+ StringBuffer buff = new StringBuffer(length);
+
+ for (int i = 0; i < length; i++) {
+ buff.append((char) ((Math.random() *26) + 'a'));
+ }
+
+ return buff.toString();
+ }
+
+ private int createChildren(Node parent, int numProperties, int width, int depth)
+ throws Exception
+ {
+ if (depth < 1) {
+ return 0;
+
+ }
+
+ int count = width;
+
+ for (int i = 0; i < width; i++) {
+ Node newNode = parent.addNode(getRandomString(9),
"nt:unstructured");
+
+ for (int j = 0; j < numProperties; j++) {
+ newNode.setProperty(getRandomString(8), getRandomString(16));
+ }
+
+ count += createChildren(newNode, numProperties, width, depth - 1);
+ }
+ return count;
+ }
+
+ protected int createSubgraph( JcrSession session,
+ String initialPath,
+ int depth,
+ int numberOfChildrenPerNode,
+ int numberOfPropertiesPerNode,
+ boolean oneBatch,
+ Stopwatch stopwatch,
+ PrintStream output,
+ String description )
+ throws Exception
+ {
+ // Calculate the number of nodes that we'll created, but subtract 1 since it
doesn't create the root
+ long totalNumber = calculateTotalNumberOfNodesInTree(numberOfChildrenPerNode,
depth, false);
+ if (initialPath == null) initialPath = "";
+ if (description == null) {
+ description = "" + numberOfChildrenPerNode + "x" + depth
+ " tree with " + numberOfPropertiesPerNode
+ + " properties per node";
+ }
+
+ if (output != null) output.println(description + " (" + totalNumber +
" nodes):");
+ long totalNumberCreated = 0;
+
+ PathFactory pathFactory =
session.getExecutionContext().getValueFactories().getPathFactory();
+ Node parentNode = session.getNode(pathFactory.create(initialPath));
+
+ if (stopwatch != null) stopwatch.start();
+
+ totalNumberCreated += createChildren(parentNode,
+ numberOfPropertiesPerNode,
+ numberOfChildrenPerNode,
+ depth);
+
+ assertThat(totalNumberCreated, is(totalNumber));
+
+ session.save();
+
+
+ if (stopwatch != null) {
+ stopwatch.stop();
+ if (output != null) {
+ output.println(" " + getTotalAndAverageDuration(stopwatch,
totalNumberCreated));
+ }
+ }
+ return (int)totalNumberCreated;
+
+ }
+
+ protected int traverseSubgraph( JcrSession session,
+ String initialPath,
+ int depth,
+ int numberOfChildrenPerNode,
+ int numberOfPropertiesPerNode,
+ boolean oneBatch,
+ Stopwatch stopwatch,
+ PrintStream output,
+ String description )
+ throws Exception
+ {
+ // Calculate the number of nodes that we'll created, but subtract 1 since it
doesn't create the root
+ long totalNumber = calculateTotalNumberOfNodesInTree(numberOfChildrenPerNode,
depth, false);
+ if (initialPath == null) initialPath = "";
+ if (description == null) {
+ description = "" + numberOfChildrenPerNode + "x" + depth
+ " tree with " + numberOfPropertiesPerNode
+ + " properties per node";
+ }
+
+ if (output != null) output.println(description + " (" + totalNumber +
" nodes):");
+ long totalNumberTraversed = 0;
+
+ PathFactory pathFactory =
session.getExecutionContext().getValueFactories().getPathFactory();
+ Node parentNode = session.getNode(pathFactory.create(initialPath));
+
+ if (stopwatch != null) stopwatch.start();
+
+ totalNumberTraversed += traverseChildren(parentNode);
+
+ assertThat(totalNumberTraversed, is(totalNumber));
+
+ session.save();
+
+
+ if (stopwatch != null) {
+ stopwatch.stop();
+ if (output != null) {
+ output.println(" " + getTotalAndAverageDuration(stopwatch,
totalNumberTraversed));
+ }
+ }
+ return (int)totalNumberTraversed;
+
+ }
+
+ protected int traverseChildren(Node parentNode) throws Exception {
+
+ int childCount = 0;
+ NodeIterator children = parentNode.getNodes();
+
+ while (children.hasNext()) {
+ childCount++;
+
+ childCount += traverseChildren(children.nextNode());
+ }
+
+ return childCount;
+ }
+
+ protected String getTotalAndAverageDuration( Stopwatch stopwatch,
+ long numNodes ) {
+ long totalDurationInMilliseconds =
TimeUnit.NANOSECONDS.toMillis(stopwatch.getTotalDuration().longValue());
+ if (numNodes == 0) numNodes = 1;
+ long avgDuration = totalDurationInMilliseconds / numNodes;
+ String units = " millisecond(s)";
+ if (avgDuration < 1L) {
+ long totalDurationInMicroseconds =
TimeUnit.NANOSECONDS.toMicros(stopwatch.getTotalDuration().longValue());
+ avgDuration = totalDurationInMicroseconds / numNodes;
+ units = " microsecond(s)";
+ }
+ return "total = " + stopwatch.getTotalDuration() + "; avg = "
+ avgDuration + units;
+ }
+
+ protected int calculateTotalNumberOfNodesInTree( int numberOfChildrenPerNode,
+ int depth,
+ boolean countRoot ) {
+ assert depth > 0;
+ assert numberOfChildrenPerNode > 0;
+ int totalNumber = 0;
+ for (int i = 0; i <= depth; ++i) {
+ totalNumber += (int)Math.pow(numberOfChildrenPerNode, i);
+ }
+ return countRoot ? totalNumber : totalNumber - 1;
+ }
+
+
+
+}
Property changes on:
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractJcrAccessTest.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrReadingTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrReadingTest.java
(rev 0)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrReadingTest.java 2009-04-14 16:41:54
UTC (rev 822)
@@ -0,0 +1,52 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * JBoss DNA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.jcr;
+
+import org.jboss.dna.common.statistic.Stopwatch;
+import org.junit.Test;
+
+/**
+ * Test performance reading graph subtrees of various sizes with varying number of
properties
+ */
+public class JcrReadingTest extends AbstractJcrAccessTest {
+
+ @Test
+ public void testReadingTrees() throws Exception {
+ int[] breadths = new int[] { 10, };
+ int[] depths = new int[] { 1, 2, 3, };
+ int[] properties = new int[] { 0, 7, 100 };
+
+ for (int i = 0; i < breadths.length; i++) {
+ for (int j = 0; j < depths.length; j++) {
+ for (int k = 0; k < properties.length; k++) {
+ String testName = "/" + breadths[i] + "x" +
depths[j] + "x" + properties[k] + "test";
+ session().getRootNode().addNode(testName,
"nt:unstructured");
+ createSubgraph(session(), testName, depths[j], breadths[i],
properties[k], false, null, null, null);
+
+ traverseSubgraph(session(), testName, depths[j], breadths[i],
properties[k], false, new Stopwatch(), System.out, null);
+ }
+ }
+ }
+ }
+}
Property changes on: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrReadingTest.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrWritingTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrWritingTest.java
(rev 0)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrWritingTest.java 2009-04-14 16:41:54
UTC (rev 822)
@@ -0,0 +1,51 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * JBoss DNA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.jcr;
+
+import org.jboss.dna.common.statistic.Stopwatch;
+import org.junit.Test;
+
+
+/**
+ * Test performance writing graph subtrees of various sizes with varying number of
properties
+ */
+public class JcrWritingTest extends AbstractJcrAccessTest {
+
+ @Test
+ public void testCreatingTrees() throws Exception {
+ int[] breadths = new int[] { 10, };
+ int[] depths = new int[] { 1, 2, 3, };
+ int[] properties = new int[] { 0, 7, 100 };
+
+ for (int i = 0; i < breadths.length; i++) {
+ for (int j = 0; j < depths.length; j++) {
+ for (int k = 0; k < properties.length; k++) {
+ String testName = "/" + breadths[i] + "x" +
depths[j] + "x" + properties[k] + "test";
+ session().getRootNode().addNode(testName,
"nt:unstructured");
+ createSubgraph(session(), testName, depths[j], breadths[i],
properties[k], false, new Stopwatch(), System.out, null);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
Property changes on: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrWritingTest.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain