You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2010/08/06 10:30:10 UTC

svn commit: r982904 - in /jackrabbit/commons/jcr-benchmark/trunk/src/main/java/org/apache/jackrabbit/benchmark: ConcurrentReadTest.java ConcurrentReadWriteTest.java PerformanceTestSuite.java

Author: jukka
Date: Fri Aug  6 08:30:10 2010
New Revision: 982904

URL: http://svn.apache.org/viewvc?rev=982904&view=rev
Log:
JCR-2699: Improve read/write concurrency

Make the concurrent reader test measure the total throughput of continuously running readers instead of the completion of 50 single traversals started simultaneously.

Add a concurrent read/write test that includes a single writer.

Added:
    jackrabbit/commons/jcr-benchmark/trunk/src/main/java/org/apache/jackrabbit/benchmark/ConcurrentReadWriteTest.java   (with props)
Modified:
    jackrabbit/commons/jcr-benchmark/trunk/src/main/java/org/apache/jackrabbit/benchmark/ConcurrentReadTest.java
    jackrabbit/commons/jcr-benchmark/trunk/src/main/java/org/apache/jackrabbit/benchmark/PerformanceTestSuite.java

Modified: jackrabbit/commons/jcr-benchmark/trunk/src/main/java/org/apache/jackrabbit/benchmark/ConcurrentReadTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/jcr-benchmark/trunk/src/main/java/org/apache/jackrabbit/benchmark/ConcurrentReadTest.java?rev=982904&r1=982903&r2=982904&view=diff
==============================================================================
--- jackrabbit/commons/jcr-benchmark/trunk/src/main/java/org/apache/jackrabbit/benchmark/ConcurrentReadTest.java (original)
+++ jackrabbit/commons/jcr-benchmark/trunk/src/main/java/org/apache/jackrabbit/benchmark/ConcurrentReadTest.java Fri Aug  6 08:30:10 2010
@@ -16,6 +16,8 @@
  */
 package org.apache.jackrabbit.benchmark;
 
+import java.util.concurrent.CountDownLatch;
+
 import javax.jcr.ItemVisitor;
 import javax.jcr.Node;
 import javax.jcr.NodeIterator;
@@ -24,50 +26,65 @@ import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 
 /**
- * Test case that creates 10k nt:folder nodes (100x100) and starts 50
- * concurrent readers to traverse this content tree.
+ * Test case that creates 10k unstructured nodes (100x100) and starts
+ * 50 concurrent readers to traverse this content tree. Note that this
+ * test measures total throughput of such a concurrent set of readers,
+ * not the performance of individual readers nor the overall fairness of
+ * the scheduling.
  */
 public class ConcurrentReadTest extends PerformanceTest {
 
-    private static final int FOLDER_COUNT = 100;
+    private static final int NODE_COUNT = 100;
 
-    private static final int CLIENT_COUNT = 50;
+    private static final int READER_COUNT = 50;
 
     private Session session;
 
-    private Node root;
+    protected Node root;
+
+    private Thread[] readers = new Thread[READER_COUNT];
+
+    private volatile boolean running;
 
-    private Session[] clients = new Session[CLIENT_COUNT];
+    private volatile CountDownLatch latch;
 
-    public void beforeSuite() throws RepositoryException {
+    public void beforeSuite() throws Exception {
         session = getRepository().login(getCredentials());
 
-        root = session.getRootNode().addNode(
-                "ConcurrentReadTest", "nt:folder");
-        for (int i = 0; i < FOLDER_COUNT; i++) {
-            Node folder = root.addNode("folder" + i, "nt:folder");
-            for (int j = 0; j < FOLDER_COUNT; j++) {
-                folder.addNode("folder" + j, "nt:folder");
+        root = session.getRootNode().addNode("testroot", "nt:unstructured");
+        for (int i = 0; i < NODE_COUNT; i++) {
+            Node node = root.addNode("node" + i, "nt:unstructured");
+            for (int j = 0; j < NODE_COUNT; j++) {
+                node.addNode("node" + j, "nt:unstructured");
             }
             session.save();
         }
 
-        for (int i = 0; i < clients.length; i++) {
-            clients[i] = getRepository().login();
+        running = true;
+        latch = new CountDownLatch(0);
+        for (int i = 0; i < READER_COUNT; i++) {
+            readers[i] = new Reader();
+            readers[i].start();
+            // Give the reader some time to get started
+            Thread.sleep(100); 
         }
     }
 
-    private static class Traversal implements Runnable, ItemVisitor {
-
-        private final Node root;
-
-        public Traversal(Session session) throws RepositoryException {
-            this.root = session.getRootNode().getNode("ConcurrentReadTest");
-        }
+    private class Reader extends Thread implements ItemVisitor {
 
+        @Override
         public void run() {
             try {
-                root.accept(this);
+                Session session = getRepository().login();
+                try {
+                    Node node = session.getRootNode().getNode(root.getName());
+                    while (running) {
+                        node.accept(this);
+                        latch.countDown();
+                    }
+                } finally {
+                    session.logout();
+                }
             } catch (RepositoryException e) {
                 throw new RuntimeException(e);
             }
@@ -86,25 +103,18 @@ public class ConcurrentReadTest extends 
     }
 
     public void runTest() throws Exception {
-        Thread[] threads = new Thread[clients.length];
-        for (int i = 0; i < threads.length; i++) {
-            threads[i] = new Thread(new Traversal(clients[i]));
-        }
-        for (int i = 0; i < threads.length; i++) {
-            threads[i].start();
-        }
-        for (int i = 0; i < threads.length; i++) {
-            threads[i].join();
-        }
+        latch = new CountDownLatch(READER_COUNT);
+        latch.await();
     }
 
-    public void afterSuite() throws RepositoryException {
-        for (int i = 0; i < clients.length; i++) {
-            clients[i].logout();
+    public void afterSuite() throws Exception {
+        running = false;
+        for (int i = 0; i < READER_COUNT; i++) {
+            readers[i].join();
         }
 
-        for (int i = 0; i < FOLDER_COUNT; i++) {
-            root.getNode("folder" + i).remove();
+        for (int i = 0; i < NODE_COUNT; i++) {
+            root.getNode("node" + i).remove();
             session.save();
         }
 

Added: jackrabbit/commons/jcr-benchmark/trunk/src/main/java/org/apache/jackrabbit/benchmark/ConcurrentReadWriteTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/jcr-benchmark/trunk/src/main/java/org/apache/jackrabbit/benchmark/ConcurrentReadWriteTest.java?rev=982904&view=auto
==============================================================================
--- jackrabbit/commons/jcr-benchmark/trunk/src/main/java/org/apache/jackrabbit/benchmark/ConcurrentReadWriteTest.java (added)
+++ jackrabbit/commons/jcr-benchmark/trunk/src/main/java/org/apache/jackrabbit/benchmark/ConcurrentReadWriteTest.java Fri Aug  6 08:30:10 2010
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.benchmark;
+
+import javax.jcr.ItemVisitor;
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+
+/**
+ * A {@link ConcurrentReadTest} with a single writer thread that continuously
+ * updates the nodes being accessed by the concurrent readers.
+ */
+public class ConcurrentReadWriteTest extends ConcurrentReadTest {
+
+    private volatile boolean running;
+
+    private Thread writer;
+
+    public void beforeSuite() throws Exception {
+        super.beforeSuite();
+
+        running = true;
+        writer = new Writer();
+        writer.start();
+    }
+
+    private class Writer extends Thread implements ItemVisitor {
+
+        private long count = 0;
+
+        @Override
+        public void run() {
+            try {
+                while (running) {
+                    root.accept(this);
+                }
+            } catch (RepositoryException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        public void visit(Node node) throws RepositoryException {
+            if (running) {
+                node.setProperty("count", count++);
+                node.getSession().save();
+
+                NodeIterator iterator = node.getNodes();
+                while (iterator.hasNext()) {
+                    iterator.nextNode().accept(this);
+                }
+            }
+        }
+
+        public void visit(Property property) {
+        }
+
+    }
+
+    public void afterSuite() throws Exception {
+        running = false;
+        writer.join();
+
+        super.afterSuite();
+    }
+
+}

Propchange: jackrabbit/commons/jcr-benchmark/trunk/src/main/java/org/apache/jackrabbit/benchmark/ConcurrentReadWriteTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/commons/jcr-benchmark/trunk/src/main/java/org/apache/jackrabbit/benchmark/PerformanceTestSuite.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/jcr-benchmark/trunk/src/main/java/org/apache/jackrabbit/benchmark/PerformanceTestSuite.java?rev=982904&r1=982903&r2=982904&view=diff
==============================================================================
--- jackrabbit/commons/jcr-benchmark/trunk/src/main/java/org/apache/jackrabbit/benchmark/PerformanceTestSuite.java (original)
+++ jackrabbit/commons/jcr-benchmark/trunk/src/main/java/org/apache/jackrabbit/benchmark/PerformanceTestSuite.java Fri Aug  6 08:30:10 2010
@@ -23,7 +23,7 @@ import javax.jcr.Repository;
 import javax.jcr.SimpleCredentials;
 
 import org.apache.commons.io.FileUtils;
-import org.apache.commons.math.stat.descriptive.SummaryStatistics;
+import org.apache.commons.math.stat.descriptive.DescriptiveStatistics;
 import org.apache.jackrabbit.core.RepositoryImpl;
 import org.apache.jackrabbit.core.config.RepositoryConfig;
 
@@ -43,8 +43,8 @@ public class PerformanceTestSuite {
         this.credentials = credentials;
     }
 
-    public SummaryStatistics runTest(PerformanceTest test) throws Exception {
-        SummaryStatistics statistics = new SummaryStatistics();
+    public DescriptiveStatistics runTest(PerformanceTest test) throws Exception {
+        DescriptiveStatistics statistics = new DescriptiveStatistics();
 
         test.setRepository(repository);
         test.setCredentials(credentials);
@@ -75,7 +75,7 @@ public class PerformanceTestSuite {
     }
 
     public void run(PerformanceTest test) throws Exception {
-        SummaryStatistics statistics = runTest(test);
+        DescriptiveStatistics statistics = runTest(test);
         System.out.format(
                 "%-36.36s  %6.0f  %6.0f  %6.0f  %6.0f  %6d%n",
                 test,