You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by am...@apache.org on 2015/06/02 08:41:41 UTC

svn commit: r1683052 - in /jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability: ./ benchmarks/ suites/

Author: amitj
Date: Tue Jun  2 06:41:41 2015
New Revision: 1683052

URL: http://svn.apache.org/r1683052
Log:
OAK-2921: RDB: Scalability tests for large read/write scenarios

Added tests for concurrent reading/writing

Added:
    jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/benchmarks/ConcurrentReader.java   (with props)
    jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/benchmarks/ConcurrentWriter.java
      - copied, changed from r1682904, jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/benchmarks/ScalabilityBenchmark.java
Modified:
    jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/ScalabilityRunner.java
    jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/benchmarks/AggregateNodeSearcher.java
    jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/benchmarks/ScalabilityBenchmark.java
    jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/suites/ScalabilityAbstractSuite.java
    jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/suites/ScalabilityNodeRelationshipSuite.java
    jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/suites/ScalabilityNodeSuite.java

Modified: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/ScalabilityRunner.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/ScalabilityRunner.java?rev=1683052&r1=1683051&r2=1683052&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/ScalabilityRunner.java (original)
+++ jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/ScalabilityRunner.java Tue Jun  2 06:41:41 2015
@@ -45,6 +45,8 @@ import org.apache.jackrabbit.oak.fixture
 import org.apache.jackrabbit.oak.fixture.OakRepositoryFixture;
 import org.apache.jackrabbit.oak.fixture.RepositoryFixture;
 import org.apache.jackrabbit.oak.scalability.benchmarks.AggregateNodeSearcher;
+import org.apache.jackrabbit.oak.scalability.benchmarks.ConcurrentReader;
+import org.apache.jackrabbit.oak.scalability.benchmarks.ConcurrentWriter;
 import org.apache.jackrabbit.oak.scalability.benchmarks.FormatSearcher;
 import org.apache.jackrabbit.oak.scalability.benchmarks.FullTextSearcher;
 import org.apache.jackrabbit.oak.scalability.benchmarks.LastModifiedSearcher;
@@ -159,7 +161,9 @@ public class ScalabilityRunner {
                                         new MultiFilterOrderByOffsetPageSearcher(),
                                         new MultiFilterSplitOrderByOffsetPageSearcher(),
                                         new MultiFilterOrderByKeysetPageSearcher(),
-                                        new MultiFilterSplitOrderByKeysetPageSearcher()),
+                                        new MultiFilterSplitOrderByKeysetPageSearcher(),
+                                        new ConcurrentReader(),
+                                        new ConcurrentWriter()),
                         new ScalabilityNodeRelationshipSuite(withStorage.value(options))
                                 .addBenchmarks(new AggregateNodeSearcher())
                 };

Modified: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/benchmarks/AggregateNodeSearcher.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/benchmarks/AggregateNodeSearcher.java?rev=1683052&r1=1683051&r2=1683052&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/benchmarks/AggregateNodeSearcher.java (original)
+++ jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/benchmarks/AggregateNodeSearcher.java Tue Jun  2 06:41:41 2015
@@ -84,7 +84,7 @@ public class AggregateNodeSearcher exten
 
     @Override
     public void execute(Repository repository, Credentials credentials,
-        ScalabilityAbstractSuite.ExecutionContext context) throws Exception {
+        ExecutionContext context) throws Exception {
         Session session = repository.login(credentials);
         QueryManager qm;
         try {

Added: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/benchmarks/ConcurrentReader.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/benchmarks/ConcurrentReader.java?rev=1683052&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/benchmarks/ConcurrentReader.java (added)
+++ jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/benchmarks/ConcurrentReader.java Tue Jun  2 06:41:41 2015
@@ -0,0 +1,204 @@
+/*
+ * 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.oak.scalability.benchmarks;
+
+import com.google.common.collect.Lists;
+import org.apache.jackrabbit.commons.JcrUtils;
+import org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants;
+import org.apache.jackrabbit.oak.scalability.suites.ScalabilityAbstractSuite;
+import org.apache.jackrabbit.oak.scalability.suites.ScalabilityAbstractSuite.ExecutionContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jcr.Credentials;
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import java.util.List;
+import java.util.Random;
+import java.util.UUID;
+
+/**
+ * Reads random paths concurrently with multiple readers/writers configured with {#WRITERS} and {#READERS}.
+ */
+public class ConcurrentReader extends ScalabilityBenchmark {
+    protected static final Logger LOG = LoggerFactory.getLogger(ConcurrentReader.class);
+    private static final Random rand = new Random();
+    private static final int WRITERS = Integer.getInteger("concurrentReaders", 0);
+    private static final int READERS = Integer.getInteger("concurrentWriters", 0);
+    private static final int MAX_ASSETS = Integer.getInteger("assets", 100);
+    private static final String ROOT_NODE_NAME =
+        ConcurrentReader.class.getSimpleName() + UUID.randomUUID();
+
+    private boolean running;
+    private List<Thread> jobs = Lists.newArrayList();
+
+    @Override
+    public void beforeExecute(Repository repository, Credentials credentials, ExecutionContext context) throws Exception {
+        Session session = repository.login(credentials);
+        JcrUtils.getOrAddNode(session.getRootNode(), ROOT_NODE_NAME);
+        session.save();
+        session.logout();
+
+        for(int idx = 0; idx < WRITERS; idx++) {
+            try {
+                Thread thread = createJob(
+                    new Writer("concurrentWriter-" + UUID.randomUUID() + idx, MAX_ASSETS,
+                        repository.login(credentials), context));
+                jobs.add(thread);
+                thread.start();
+            } catch (Exception e) {
+                LOG.error("error creating background writer", e);
+            }
+        }
+
+        for(int idx = 0; idx < READERS; idx++) {
+            try {
+                Thread thread = createJob(
+                    new Reader("concurrentReader-" + UUID.randomUUID() + idx, MAX_ASSETS,
+                        repository.login(credentials), context));
+                jobs.add(thread);
+                thread.start();
+            } catch (Exception e) {
+                LOG.error("error creating background reader", e);
+            }
+        }
+        running = true;
+    }
+
+    private Thread createJob(final Job job) throws RepositoryException {
+        Thread thread = new Thread(job.id) {
+            @Override public void run() {
+                while (running) {
+                    job.process();
+                }
+            }
+        };
+        thread.setDaemon(true);
+        return thread;
+    }
+
+    @Override
+    public void afterExecute(Repository repository, Credentials credentials, ExecutionContext context) {
+        running = false;
+        for (Thread thread : jobs) {
+            try {
+                thread.join();
+            } catch (InterruptedException e) {
+                LOG.error("Error stopping thread", e);
+            }
+        }
+        jobs.clear();
+    }
+
+    @Override
+    public void execute(Repository repository, Credentials credentials, ExecutionContext context)
+        throws Exception {
+        Reader reader = new Reader(this.getClass().getSimpleName() + UUID.randomUUID(),
+            100, repository.login(credentials), context);
+        reader.process();
+    }
+
+    abstract class Job {
+        final Node parent;
+        final Session session;
+        final String id;
+        final int maxAssets;
+        final List<String> readPaths;
+        final Random rand;
+
+        Job(String id, int maxAssets, Session session, ExecutionContext context) throws RepositoryException {
+            this.id = id;
+            this.maxAssets = maxAssets;
+            this.session = session;
+            this.parent = session
+                .getRootNode()
+                .getNode(ROOT_NODE_NAME)
+                .addNode(id);
+            readPaths =
+                (List<String>) context.getMap().get(ScalabilityAbstractSuite.CTX_SEARCH_PATHS_PROP);
+            rand = new Random();
+            session.save();
+        }
+
+        public abstract void process();
+    }
+
+
+    /**
+     * Simple Reader job
+     */
+    class Reader extends Job {
+        Reader(String id, int maxAssets, Session session, ExecutionContext context) throws RepositoryException {
+            super(id, maxAssets, session, context);
+        }
+
+        @Override
+        public void process() {
+            try {
+                int count = 1;
+                int readPathSize = readPaths.size();
+                while (count <= maxAssets) {
+                    session.refresh(false);
+                    Node node =
+                        JcrUtils.getNodeIfExists(readPaths.get(rand.nextInt(readPathSize)), session);
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug(node.getPath());
+                    }
+                    count++;
+                }
+            } catch (Exception e) {
+                LOG.error("Exception in reading", e);
+            }
+        }
+    }
+
+
+    /**
+     * Simple Writer job
+     */
+    class Writer extends Job {
+        Writer(String id, int maxAssets, Session session, ExecutionContext context) throws RepositoryException {
+            super(id, maxAssets, session, context);
+        }
+
+        @Override
+        public void process() {
+            try {
+                int count = 1;
+                while (count <= maxAssets) {
+                    session.refresh(false);
+                    Node node =
+                        JcrUtils.getOrAddNode(parent, "Node" + count, NodeTypeConstants.NT_OAK_UNSTRUCTURED);
+                    node.setProperty("prop1", "val1");
+                    node.setProperty("prop2", "val2");
+                    session.save();
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug(node.getPath());
+                    }
+                    count++;
+                }
+            } catch (Exception e) {
+                LOG.error("Exception in write", e);
+            }
+        }
+    }
+
+}

Propchange: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/benchmarks/ConcurrentReader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Copied: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/benchmarks/ConcurrentWriter.java (from r1682904, jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/benchmarks/ScalabilityBenchmark.java)
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/benchmarks/ConcurrentWriter.java?p2=jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/benchmarks/ConcurrentWriter.java&p1=jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/benchmarks/ScalabilityBenchmark.java&r1=1682904&r2=1683052&rev=1683052&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/benchmarks/ScalabilityBenchmark.java (original)
+++ jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/benchmarks/ConcurrentWriter.java Tue Jun  2 06:41:41 2015
@@ -18,37 +18,21 @@
  */
 package org.apache.jackrabbit.oak.scalability.benchmarks;
 
+import org.apache.jackrabbit.oak.scalability.suites.ScalabilityAbstractSuite;
+
 import javax.jcr.Credentials;
 import javax.jcr.Repository;
-
-import org.apache.jackrabbit.oak.scalability.ScalabilitySuite;
-import org.apache.jackrabbit.oak.scalability.suites.ScalabilityAbstractSuite.ExecutionContext;
-
+import java.util.UUID;
 
 /**
- * Base class for all the Scalability/Longevity benchmarks/tests.
- * 
- * The implementations should implement the method
- * {@link ScalabilityBenchmark#execute(Repository, Credentials, ExecutionContext)}.
- * 
- * This method will then be called from the {@link ScalabilitySuite} where configured.
- * 
+ * Writes random paths concurrently with multiple readers/writers configured with {#WRITERS} and {#READERS}.
  */
-public abstract class ScalabilityBenchmark {
-
-    /**
-     * Runs the benchmark against the given repository.
-     * 
-     * @param fixtures repository fixtures
-     * @throws Exception 
-     */
-    public abstract void execute(Repository repository, Credentials credentials,
-            ExecutionContext context) throws Exception;
-
+public class ConcurrentWriter extends ConcurrentReader {
     @Override
-    public String toString() {
-        String name = getClass().getName();
-        return name.substring(name.lastIndexOf('.') + 1);
+    public void execute(Repository repository, Credentials credentials, ScalabilityAbstractSuite.ExecutionContext context)
+        throws Exception {
+        Writer writer = new Writer(this.getClass().getSimpleName() + UUID.randomUUID(),
+            100, repository.login(credentials), context);
+        writer.process();
     }
 }
-

Modified: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/benchmarks/ScalabilityBenchmark.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/benchmarks/ScalabilityBenchmark.java?rev=1683052&r1=1683051&r2=1683052&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/benchmarks/ScalabilityBenchmark.java (original)
+++ jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/benchmarks/ScalabilityBenchmark.java Tue Jun  2 06:41:41 2015
@@ -38,13 +38,35 @@ public abstract class ScalabilityBenchma
 
     /**
      * Runs the benchmark against the given repository.
-     * 
-     * @param fixtures repository fixtures
-     * @throws Exception 
+     *
+     * @param repository the repository instance
+     * @param credentials the credentials
+     * @param context the execution context
+     * @throws Exception
      */
     public abstract void execute(Repository repository, Credentials credentials,
             ExecutionContext context) throws Exception;
 
+    /**
+     * Run any preparatory steps before the benchmark.
+     *
+     * @param repository the repository instance
+     * @param credentials the credentials
+     * @param context the execution context
+     */
+    public void beforeExecute(Repository repository, Credentials credentials,
+        ExecutionContext context) throws Exception {}
+
+    /**
+     * Run any cleanup necessary after the benchmark
+     *
+     * @param repository the repository instance
+     * @param credentials the credentials
+     * @param context the execution context
+     */
+    public void afterExecute(Repository repository, Credentials credentials,
+        ExecutionContext context) {}
+
     @Override
     public String toString() {
         String name = getClass().getName();

Modified: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/suites/ScalabilityAbstractSuite.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/suites/ScalabilityAbstractSuite.java?rev=1683052&r1=1683051&r2=1683052&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/suites/ScalabilityAbstractSuite.java (original)
+++ jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/suites/ScalabilityAbstractSuite.java Tue Jun  2 06:41:41 2015
@@ -72,6 +72,8 @@ import org.slf4j.LoggerFactory;
  * 
  */
 public abstract class ScalabilityAbstractSuite implements ScalabilitySuite, CSVResultGenerator {
+    public static final String CTX_SEARCH_PATHS_PROP = "searchPaths";
+
     protected static final Logger LOG = LoggerFactory.getLogger(ScalabilityAbstractSuite.class);
 
     /**
@@ -320,7 +322,7 @@ public abstract class ScalabilityAbstrac
 
             watch.stop();
             result.getBenchmarkStatistics(benchmark).addValue(watch.elapsed(TimeUnit.MILLISECONDS));
-            
+
             if (LOG.isDebugEnabled()) {
                 LOG.debug("Execution time for " + benchmark + "-"
                                             + watch.elapsed(TimeUnit.MILLISECONDS));
@@ -359,6 +361,7 @@ public abstract class ScalabilityAbstrac
                 }
             }
         };
+        thread.setDaemon(true);
         thread.start();
         threads.add(thread);
     }

Modified: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/suites/ScalabilityNodeRelationshipSuite.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/suites/ScalabilityNodeRelationshipSuite.java?rev=1683052&r1=1683051&r2=1683052&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/suites/ScalabilityNodeRelationshipSuite.java (original)
+++ jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/suites/ScalabilityNodeRelationshipSuite.java Tue Jun  2 06:41:41 2015
@@ -30,6 +30,7 @@ import javax.jcr.PropertyType;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 
+import com.google.common.collect.ImmutableList;
 import org.apache.commons.math.stat.descriptive.SynchronizedDescriptiveStatistics;
 import org.apache.jackrabbit.api.JackrabbitSession;
 import org.apache.jackrabbit.api.security.user.Authorizable;
@@ -93,13 +94,20 @@ public class ScalabilityNodeRelationship
     protected static final List<String> NODE_LEVELS = Splitter.on(",").trimResults()
         .omitEmptyStrings().splitToList(System.getProperty("nodeLevels", "10,5,2,1"));
 
-    private static final int NUM_USERS = Integer.parseInt(NODE_LEVELS.get(0));
+    protected static final List<String> NODE_LEVELS_DEFAULT = ImmutableList.of("10","5","2","1");
 
-    private static final int NUM_GROUPS = Integer.parseInt(NODE_LEVELS.get(1));
+    private static final int NUM_USERS =
+        (NODE_LEVELS.size() >= 1 ? Integer.parseInt(NODE_LEVELS.get(0)) : Integer.parseInt(NODE_LEVELS_DEFAULT.get(0)));
 
-    private static final int NUM_RELATIONSHIPS = Integer.parseInt(NODE_LEVELS.get(2));
+    private static final int NUM_GROUPS =
+        (NODE_LEVELS.size() >= 2 ? Integer.parseInt(NODE_LEVELS.get(1)) : Integer.parseInt(NODE_LEVELS_DEFAULT.get(1)));
+
+    private static final int NUM_RELATIONSHIPS =
+        (NODE_LEVELS.size() >= 3 ? Integer.parseInt(NODE_LEVELS.get(2)) : Integer.parseInt(NODE_LEVELS_DEFAULT.get(2)));
+
+    private static final int NUM_ACTIVITIES =
+        (NODE_LEVELS.size() >= 4 ? Integer.parseInt(NODE_LEVELS.get(3)) : Integer.parseInt(NODE_LEVELS_DEFAULT.get(3)));
 
-    private static final int NUM_ACTIVITIES = Integer.parseInt(NODE_LEVELS.get(3));
 
     private static final long BUCKET_SIZE = 100;
 

Modified: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/suites/ScalabilityNodeSuite.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/suites/ScalabilityNodeSuite.java?rev=1683052&r1=1683051&r2=1683052&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/suites/ScalabilityNodeSuite.java (original)
+++ jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/scalability/suites/ScalabilityNodeSuite.java Tue Jun  2 06:41:41 2015
@@ -91,9 +91,9 @@ public class ScalabilityNodeSuite extend
             .omitEmptyStrings().splitToList(System.getProperty("nodeLevels", "10,5,2"));
 
     /**
-     * Controls the number of concurrent thread for searching
+     * Controls the number of concurrent tester threads
      */
-    protected static final int SEARCHERS = Integer.getInteger("searchers", 1);
+    protected static final int TESTERS = Integer.getInteger("testers", 1);
 
     /**
      * Controls the percentage of root nodes which will have sub nodes created.
@@ -126,8 +126,6 @@ public class ScalabilityNodeSuite extend
      */
     protected static final boolean CUSTOM_TYPE = Boolean.getBoolean("customType");
 
-    public static final String CTX_SEARCH_PATHS_PROP = "searchPaths";
-
     public static final String CTX_DESC_SEARCH_PATHS_PROP = "descPaths";
 
     public static final String CTX_ROOT_NODE_NAME_PROP = "rootNodeName";
@@ -370,14 +368,18 @@ public class ScalabilityNodeSuite extend
     @Override
     protected void executeBenchmark(final ScalabilityBenchmark benchmark,
             final ExecutionContext context) throws Exception {
-      LOG.info("Stated execution : " + benchmark.toString());
+
+        LOG.info("Started pre benchmark hook : {}", benchmark);
+        benchmark.beforeExecute(getRepository(), CREDENTIALS, context);
+
+        LOG.info("Started execution : {}", benchmark);
         if (PROFILE) {
             context.startProfiler();
         }
         //Execute the benchmark with the number threads configured 
-        List<Thread> threads = newArrayListWithCapacity(SEARCHERS);
-        for (int idx = 0; idx < SEARCHERS; idx++) {
-            Thread t = new Thread("Search-" + idx) {
+        List<Thread> threads = newArrayListWithCapacity(TESTERS);
+        for (int idx = 0; idx < TESTERS; idx++) {
+            Thread t = new Thread("Tester-" + idx) {
                 @Override
                 public void run() {
                     try {
@@ -399,6 +401,9 @@ public class ScalabilityNodeSuite extend
             }
         }
         context.stopProfiler();
+
+        LOG.info("Started post benchmark hook : {}", benchmark);
+        benchmark.afterExecute(getRepository(), CREDENTIALS, context);
     }
 
     @Override
@@ -430,14 +435,20 @@ public class ScalabilityNodeSuite extend
     }
 
     private synchronized void addRootSearchPath(String path) {
-        if (!searchRootPaths.contains(path)) {
+        int limit = 1000;
+        if (searchRootPaths.size() < limit) {
             searchRootPaths.add(path);
+        } else if (random.nextDouble() < 0.5) {
+            searchRootPaths.set(random.nextInt(limit), path);
         }
     }
 
     private synchronized void addDescSearchPath(String path) {
-        if (!searchDescPaths.contains(path)) {
+        int limit = 1000;
+        if (searchDescPaths.size() < limit) {
             searchDescPaths.add(path);
+        } else if (random.nextDouble() < 0.5) {
+            searchDescPaths.set(random.nextInt(limit), path);
         }
     }