[jboss-cvs] JBossCache/tests/perf/org/jboss/cache/manualtests/cacheloader ...

Mircea Markus mircea.markus at gmail.com
Sat Feb 10 12:47:02 EST 2007


  User: mmarkus 
  Date: 07/02/10 12:47:02

  Added:       tests/perf/org/jboss/cache/manualtests/cacheloader     
                        Benchmark.java BenchmarkRunner.java
                        BaseBenchmark.java RepeatingBenchmark.java
                        OneConnectionFactory.java
  Log:
  JDBCCaheLoader performance improvements. Also added benchmarks for comparisons and backward compatibility  tests
  
  Revision  Changes    Path
  1.1      date: 2007/02/10 17:47:02;  author: mmarkus;  state: Exp;JBossCache/tests/perf/org/jboss/cache/manualtests/cacheloader/Benchmark.java
  
  Index: Benchmark.java
  ===================================================================
  package org.jboss.cache.manualtests.cacheloader;
  
  import org.jboss.cache.loader.*;
  import org.jboss.cache.Fqn;
  import org.jboss.cache.CacheImpl;
  import org.jboss.cache.DefaultCacheFactory;
  
  import java.util.*;
  
  /**
   * Defines the algorithm used for measuring performance. The actual operation that will be investigated is defined
   * in a subclass. Buidls a homogeneous tree structure of configurable depth, each node having the same number
   * of chlidren and the same associated attribute map. The persisted tree represents the fixture for the benchmak-ed
   * operation.
   *
   * Benchmarks are runed through {@link BenchmarkRunner}
   *
   * @author Mircea.Markus at iquestint.com
   * @version 1.0
   */
  public abstract class Benchmark
  {
  
  
      /**
       * When recursively building the tree, stop at this depth.
       */
      protected abstract int getDepth();
  
      /**
       * When recursively building the tree, for each node <tt>numberOfChildren</tt> children
       */
      protected abstract int getNumnerOfChildren();
  
      /**
       * The actual loader implementation. Not started.
       */
      protected abstract CacheLoader getCacheLoader() throws Exception;
  
      /**
       * This method will be called with all the nodes that are about to be added. Implementations can filter them
       * or scuffle etc.
       */
      protected abstract List<Fqn> beforeInsertion(List<Fqn> nodesToAdd);
  
      /**
       * When recursively building the tree, for each node persist this attribute map.
       */
      protected abstract Map getAttributeMap(Fqn fqn);
  
      /**
       * The analysed operation will only be performed on those node. E.g. in the case of remove, select a list of nodes
       * of various depths for which you want to compare the perfomance.
       */
      protected abstract List<Fqn> selectRelevantNodes(List<Fqn> allNodes);
  
      /**
       * Perform the call(set of calls) for which you want to measure performance. Clock will be started right before
       * calling this.
       */
      protected abstract void processOperation(Fqn node, CacheLoader loader) throws Exception;
  
      /**
       * Register operation duration. Calld imediatelly after <tt>processOperation</tt>.
       */
      protected abstract void logOperationDuration(long duration, Fqn processedFqn);
  
      /**
       * Logs the duration of persisisting the test tree structure. Does not include the time needed for
       * generating the test tree structure.
       */
      protected abstract void logInsertionDuration(long duration);
  
  
      /**
       * Return the name of the benchmark.
       */
      protected abstract String getName();
  
      public void testPerformance() throws Exception
      {
          int numnerOfChildren = getNumnerOfChildren();
          int depth = getDepth();
          List<Fqn> nodesToAdd = buildTree(depth, numnerOfChildren);
          CacheLoader cacheLoader = getCacheLoader();
          cacheLoader.setCache((CacheImpl) DefaultCacheFactory.getInstance().createCache(false));//this is needed for marshaller
          cacheLoader.start();
          cacheLoader.remove(Fqn.ROOT);
  
          //1st step = preprocess nodes to add
          List<Fqn> processedNodes = beforeInsertion(nodesToAdd);
  
          //2nd step = add all the nodes
          long insStartTime = System.currentTimeMillis();
          for (Fqn fqn : processedNodes)
          {
              cacheLoader.put(fqn, getAttributeMap(fqn));
          }
          logInsertionDuration(System.currentTimeMillis() - insStartTime);
  
          //3d step = select relevant nodes for our operation
          List<Fqn> relevantNodes = selectRelevantNodes(processedNodes);
  
          //4th step - perform the desired operation on each selected node and log performance
          for (Fqn node : relevantNodes)
          {
              long startTime = System.currentTimeMillis();
              processOperation(node, cacheLoader);
              logOperationDuration(System.currentTimeMillis() - startTime, node);
          }
          cacheLoader.stop();
      }
  
      protected List<Fqn> buildTree(int depth, int numberOfChildren) throws Exception
      {
          List<Fqn> treeNodes = new ArrayList<Fqn>();
          for (int i = 0; i < numberOfChildren; i++)
          {
              buildNode(i, 1, "", depth, numberOfChildren, treeNodes);
          }
          return treeNodes;
      }
  
      private void buildNode(int sequence, int depth, String parent, int maxDepth, int numberOfChildren,
                             List<Fqn> treeNodes)
      {
          String newFqn = parent + Fqn.SEPARATOR + depth + "_" + sequence;
          Fqn thisNode = Fqn.fromString(newFqn);
          treeNodes.add(thisNode);
          if (depth < maxDepth)
          {
              for (int i = 0; i < numberOfChildren; i++)
              {
                  buildNode(i, depth + 1, thisNode.toString(), maxDepth, numberOfChildren, treeNodes);
              }
          }
      }
  
  
  }
  
  
  
  
  
  1.1      date: 2007/02/10 17:47:02;  author: mmarkus;  state: Exp;JBossCache/tests/perf/org/jboss/cache/manualtests/cacheloader/BenchmarkRunner.java
  
  Index: BenchmarkRunner.java
  ===================================================================
  package org.jboss.cache.manualtests.cacheloader;
  
  import org.jboss.cache.manualtests.cacheloader.newimpl.*;
  import org.jboss.cache.manualtests.cacheloader.oldimpl.*;
  
  /**
   * Entry point for running the benchmarks. The benchmark to be run are defined here, see "benchmark" static field.
   *
   * @author Mircea.Markus at iquestint.com
   * @version 1.0
   */
  public class BenchmarkRunner
  {
  
      private static String[] benchmarks = {
              RemoveNewBenchmark.class.getName(),
              LoadNewBenchmark.class.getName(),
              ChildrenNamesNewBenchmark.class.getName(),
              GetAttributesNewBenchmark.class.getName(),
              ExistsNewBenchmark.class.getName(),
              /* end of new impl benchmarks */
  
  
              RemoveOldBenchmark.class.getName(),
              LoadOldBenchmark.class.getName(),
              ChildrenNamesOldBenchmark.class.getName(),
              GetAttributesOldBenchmark.class.getName(),
              ExistsOldBenchmark.class.getName()
      };
  
      public static void main(String[] args) throws Exception
      {
          for (int i = 0; i < benchmarks.length; i++)
          {
              Benchmark benchmark = (Benchmark) Class.forName(benchmarks[i]).newInstance();
              System.out.println("Running benchmark " + benchmark.getName());
              benchmark.testPerformance();
              System.out.println("Done running benchmark " + benchmark.getName() + "\n \n");
          }
      }
  }
  
  
  
  1.1      date: 2007/02/10 17:47:02;  author: mmarkus;  state: Exp;JBossCache/tests/perf/org/jboss/cache/manualtests/cacheloader/BaseBenchmark.java
  
  Index: BaseBenchmark.java
  ===================================================================
  package org.jboss.cache.manualtests.cacheloader;
  
  import org.jboss.cache.Fqn;
  import org.jboss.cache.factories.XmlConfigurationParser;
  import org.jboss.cache.xml.XmlHelper;
  import org.jboss.cache.config.CacheLoaderConfig;
  import org.w3c.dom.Element;
  
  import java.util.*;
  
  /**
   * Implements the common operations.
   * @see Benchmark
   *
   * @author Mircea.Markus at iquestint.com
   * @version 1.0
   */
  public abstract class BaseBenchmark extends Benchmark
  {
  
      public static final int NUMBER_OF_CHILDREN = 3;
  
      public static final int DEPTH = 7;
  
      public static final Map ATTRIBUTE_MAP = new HashMap();
  
      static
      {
          ATTRIBUTE_MAP.put("a", "b");
          ATTRIBUTE_MAP.put("b", "c");
          ATTRIBUTE_MAP.put("c", "d");
          ATTRIBUTE_MAP.put("d", "e");
      }
  
  
      protected int getDepth()
      {
          return DEPTH;
      }
  
      protected int getNumnerOfChildren()
      {
          return NUMBER_OF_CHILDREN;
      }
  
      protected List<Fqn> beforeInsertion(List<Fqn> nodesToAdd)
      {
          Collections.shuffle(nodesToAdd);
          return nodesToAdd;
      }
  
      protected Map getAttributeMap(Fqn fqn)
      {
          return ATTRIBUTE_MAP;
      }
  
      protected List<Fqn> selectRelevantNodes(List<Fqn> allNodes)
      {
          List<Fqn> result = new ArrayList<Fqn>();
          selectAtThisDepth(Fqn.ROOT, 1, result);
          Collections.reverse(result);
          return result;
      }
  
      private static void selectAtThisDepth(Fqn parent, int depth, List<Fqn> result)
      {
          String forRemoval = parent + Fqn.SEPARATOR + depth + "_" + 0;
          Fqn forRemovalFqn = Fqn.fromString(forRemoval);
          result.add(forRemovalFqn);
          if (depth < DEPTH)
          {
              String next = parent + Fqn.SEPARATOR + depth + "_" + 1;
              Fqn nextFqn = Fqn.fromString(next);
              selectAtThisDepth(nextFqn, depth + 1, result);
          }
      }
  
      protected void logOperationDuration(long duration, Fqn processedFqn)
      {
          System.out.println((getDepth() + 1) - processedFqn.size() + " " + duration);
      }
  
      protected void logInsertionDuration(long duration)
      {
          System.out.println("Insertion took = " + duration);
      }
  
      protected CacheLoaderConfig getSingleCacheLoaderConfig(boolean passivation, String preload, String cacheloaderClass, String properties, boolean async, boolean fetchPersistentState, boolean shared, boolean purgeOnStartup) throws Exception
      {
          String xml = "<config>\n" +
                  "<passivation>" + passivation + "</passivation>\n" +
                  "<preload>" + preload + "</preload>\n" +
                  "<cacheloader>\n" +
                  "<class>" + cacheloaderClass + "</class>\n" +
                  "<properties>" + properties + "</properties>\n" +
                  "<async>" + async + "</async>\n" +
                  "<shared>" + shared + "</shared>\n" +
                  "<fetchPersistentState>" + fetchPersistentState + "</fetchPersistentState>\n" +
                  "<purgeOnStartup>" + purgeOnStartup + "</purgeOnStartup>\n" +
                  "</cacheloader>\n" +
                  "</config>";
          Element element = XmlHelper.stringToElement(xml);
          return XmlConfigurationParser.parseCacheLoaderConfig(element);
      }
  
      protected Properties getProperties() throws Exception
      {
          Properties prop = new Properties();
          try
          {
              prop.load(this.getClass().getClassLoader().getResourceAsStream("cache-jdbc.properties"));
              return prop;
          }
          catch (Exception e)
          {
              throw new Exception("Error loading jdbc properties ", e);
          }
  
  
      }
  
  
  }
  
  
  
  1.1      date: 2007/02/10 17:47:02;  author: mmarkus;  state: Exp;JBossCache/tests/perf/org/jboss/cache/manualtests/cacheloader/RepeatingBenchmark.java
  
  Index: RepeatingBenchmark.java
  ===================================================================
  package org.jboss.cache.manualtests.cacheloader;
  
  import org.jboss.cache.Fqn;
  import org.jboss.cache.loader.CacheLoader;
  
  /**
   * Executing some operations only once is not relevant. E.g. in the case of exits() we only get relevant timing when
   * executing it 10 timese or so.
   *
   * @author Mircea.Markus at iquestint.com
   * @version 1.0
   */
  public abstract class RepeatingBenchmark extends BaseBenchmark
  {
      public static final int NUMBER_OF_TIMES = 100;
  
      protected void processOperation(Fqn node, CacheLoader loader) throws Exception
      {
          for (int i = 0; i < NUMBER_OF_TIMES; i++)
          {
              repeatOperation(node, loader);
          }
      }
  
      public abstract void repeatOperation(Fqn node, CacheLoader loader) throws Exception;
  }
  
  
  
  1.1      date: 2007/02/10 17:47:02;  author: mmarkus;  state: Exp;JBossCache/tests/perf/org/jboss/cache/manualtests/cacheloader/OneConnectionFactory.java
  
  Index: OneConnectionFactory.java
  ===================================================================
  package org.jboss.cache.manualtests.cacheloader;
  
  import org.jboss.cache.loader.ConnectionFactory;
  import org.jboss.cache.loader.AdjListJDBCClassLoaderConfig;
  
  import java.sql.Connection;
  import java.sql.SQLException;
  import java.sql.DriverManager;
  
  /**
   * Gives only one connection all the time. There is no need for pooling as all the operations are performed
   * sequentially - so this is the leess time consuming poolig mechanism available. 
   *
   * @author Mircea.Markus at iquestint.com
   * @version 1.0
   */
  public class OneConnectionFactory implements ConnectionFactory
  {
      private AdjListJDBCClassLoaderConfig config;
  
      private Connection conn;
  
  
      public void setConfig(AdjListJDBCClassLoaderConfig config)
      {
          this.config = config;
      }
  
      public void start() throws Exception
      {
          Class.forName(config.getDriverClass());
          conn = DriverManager.getConnection(config.getJdbcURL(), config.getJdbcUser(), config.getJdbcPassword());
      }
  
      public Connection getConnection() throws SQLException
      {
          return conn;
      }
  
      public void prepare(Object tx)
      {
      }
  
      public void commit(Object tx)
      {
      }
  
      public void rollback(Object tx)
      {
      }
  
      public void close(Connection con)
      {
      }
  
      public void stop()
      {
          try
          {
              conn.close();
          } catch (SQLException e)
          {
              e.printStackTrace();
          }
      }
  }
  
  
  



More information about the jboss-cvs-commits mailing list