Created Benchmark for InMemoryDataStore Write Op 48/10948/6
authorLukas Sedlak <lsedlak@cisco.com>
Tue, 9 Sep 2014 14:35:44 +0000 (16:35 +0200)
committerLukas Sedlak <lsedlak@cisco.com>
Fri, 12 Sep 2014 07:09:12 +0000 (07:09 +0000)
Created Benchmark suite for testing InMemoryDataStore write operations. The benchmark
is designed to measure efficiency of InMemoryDataStore write operations for scenarios:
 -100K Writes executed as One commit (100K items in one commit) of One outer list item with one inner list item
 -100K Writes executed as Each commit per Write (100K commits) of One outer list item with one inner list item
 -50K Writes executed as One commit (50K items in one commit) of One outer list item with two inner list items
 -50K Writes executed as Each commit per Write (50K commits) of One outer list item with two inner list items
 -10K Writes executed as One commit (10K items in one commit) of One outer list item with ten inner list items
 -10K Writes executed as Each commit per Write (10K commits) of One outer list item with ten inner list items

Benchmark suite contains of three benchmark scenarios where InMemoryDataStore is instantiated with different combinations
of executors. This will allow us to see how executor services has performance impact on DataStore write operations.

The md-sal parent pom is extended with benchmarks profile.

Change-Id: I04f6e4545445d5879d8de9785d7ba1a53ec007af
Signed-off-by: Lukas Sedlak <lsedlak@cisco.com>
opendaylight/commons/opendaylight/pom.xml
opendaylight/md-sal/benchmark-data-store/pom.xml [new file with mode: 0644]
opendaylight/md-sal/benchmark-data-store/src/main/java/org/opendaylight/controller/md/sal/dom/store/benchmark/AbstractInMemoryDatastoreWriteTransactionBenchmark.java [new file with mode: 0644]
opendaylight/md-sal/benchmark-data-store/src/main/java/org/opendaylight/controller/md/sal/dom/store/benchmark/BenchmarkModel.java [new file with mode: 0644]
opendaylight/md-sal/benchmark-data-store/src/main/java/org/opendaylight/controller/md/sal/dom/store/benchmark/InMemoryDataStoreWithExecutorServiceBenchmark.java [new file with mode: 0644]
opendaylight/md-sal/benchmark-data-store/src/main/java/org/opendaylight/controller/md/sal/dom/store/benchmark/InMemoryDataStoreWithSameThreadedExecutorBenchmark.java [new file with mode: 0644]
opendaylight/md-sal/benchmark-data-store/src/main/java/org/opendaylight/controller/md/sal/dom/store/benchmark/InMemoryDataStoreWriteTransactionBenchmark.java [new file with mode: 0644]
opendaylight/md-sal/benchmark-data-store/src/main/resources/odl-datastore-test.yang [new file with mode: 0644]
opendaylight/md-sal/pom.xml

index 2e817b97f36a85eebc9a0256284221f60b2b61a3..d1ce63159b64100be2dfd9feb5b080d7d76870f6 100644 (file)
     <yang-ext.version>2013.09.07.4-SNAPSHOT</yang-ext.version>
     <yang-jmx-generator.version>1.0.0-SNAPSHOT</yang-jmx-generator.version>
     <yangtools.version>0.6.2-SNAPSHOT</yangtools.version>
-      <sshd-core.version>0.12.0</sshd-core.version>
+    <sshd-core.version>0.12.0</sshd-core.version>
+    <jmh.version>0.9.7</jmh.version>
   </properties>
 
   <dependencyManagement>
         <type>xml</type>
         <scope>runtime</scope>
       </dependency>
+      <!-- JMH Benchmark dependencies -->
+      <dependency>
+        <groupId>org.openjdk.jmh</groupId>
+        <artifactId>jmh-core</artifactId>
+        <version>${jmh.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.openjdk.jmh</groupId>
+        <artifactId>jmh-generator-annprocess</artifactId>
+        <version>${jmh.version}</version>
+      </dependency>
     </dependencies>
   </dependencyManagement>
 
diff --git a/opendaylight/md-sal/benchmark-data-store/pom.xml b/opendaylight/md-sal/benchmark-data-store/pom.xml
new file mode 100644 (file)
index 0000000..1af2287
--- /dev/null
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+
+This program and the accompanying materials are made available under the
+terms of the Eclipse Public License v1.0 which accompanies this distribution,
+and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <parent>
+    <artifactId>sal-parent</artifactId>
+    <groupId>org.opendaylight.controller</groupId>
+    <version>1.1-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>org.opendaylight.controller</groupId>
+  <artifactId>benchmark-data-store</artifactId>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-data-impl</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-parser-impl</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.openjdk.jmh</groupId>
+      <artifactId>jmh-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.openjdk.jmh</groupId>
+      <artifactId>jmh-generator-annprocess</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-inmemory-datastore</artifactId>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>exec-maven-plugin</artifactId>
+        <configuration>
+          <classpathScope>test</classpathScope>
+          <executable>java</executable>
+          <arguments>
+            <argument>-classpath</argument>
+            <classpath/>
+            <argument>org.openjdk.jmh.Main</argument>
+            <argument>.*</argument>
+          </arguments>
+        </configuration>
+        <executions>
+          <execution>
+            <id>run-benchmarks</id>
+            <phase>integration-test</phase>
+            <goals>
+              <goal>exec</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
\ No newline at end of file
diff --git a/opendaylight/md-sal/benchmark-data-store/src/main/java/org/opendaylight/controller/md/sal/dom/store/benchmark/AbstractInMemoryDatastoreWriteTransactionBenchmark.java b/opendaylight/md-sal/benchmark-data-store/src/main/java/org/opendaylight/controller/md/sal/dom/store/benchmark/AbstractInMemoryDatastoreWriteTransactionBenchmark.java
new file mode 100644 (file)
index 0000000..aa5ef61
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.store.benchmark;
+
+import java.util.concurrent.TimeUnit;
+import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Warmup;
+
+/**
+ * @author Lukas Sedlak <lsedlak@cisco.com>
+ */
+public abstract class AbstractInMemoryDatastoreWriteTransactionBenchmark {
+
+    private static final int WARMUP_ITERATIONS = 20;
+    private static final int MEASUREMENT_ITERATIONS = 20;
+
+    private static final int OUTER_LIST_100K = 100000;
+    private static final int OUTER_LIST_50K = 50000;
+    private static final int OUTER_LIST_10K = 10000;
+
+    private static final YangInstanceIdentifier[] OUTER_LIST_100K_PATHS = initOuterListPaths(OUTER_LIST_100K);
+    private static final YangInstanceIdentifier[] OUTER_LIST_50K_PATHS = initOuterListPaths(OUTER_LIST_50K);
+    private static final YangInstanceIdentifier[] OUTER_LIST_10K_PATHS = initOuterListPaths(OUTER_LIST_10K);
+
+    private static YangInstanceIdentifier[] initOuterListPaths(final int outerListPathsCount) {
+        final YangInstanceIdentifier[] paths = new YangInstanceIdentifier[outerListPathsCount];
+
+        for (int outerListKey = 0; outerListKey < outerListPathsCount; ++outerListKey) {
+            paths[outerListKey] = YangInstanceIdentifier.builder(BenchmarkModel.OUTER_LIST_PATH)
+                .nodeWithKey(BenchmarkModel.OUTER_LIST_QNAME, BenchmarkModel.ID_QNAME, outerListKey)
+                .build();
+        }
+        return paths;
+    }
+
+    private static final MapNode ONE_ITEM_INNER_LIST = initInnerListItems(1);
+    private static final MapNode TWO_ITEM_INNER_LIST = initInnerListItems(2);
+    private static final MapNode TEN_ITEM_INNER_LIST = initInnerListItems(10);
+
+    private static MapNode initInnerListItems(final int count) {
+        final CollectionNodeBuilder<MapEntryNode, MapNode> mapEntryBuilder = ImmutableNodes
+            .mapNodeBuilder(BenchmarkModel.INNER_LIST_QNAME);
+
+        for (int i = 1; i <= count; ++i) {
+            mapEntryBuilder
+                .withChild(ImmutableNodes.mapEntry(BenchmarkModel.INNER_LIST_QNAME, BenchmarkModel.NAME_QNAME, i));
+        }
+        return mapEntryBuilder.build();
+    }
+
+    private static final NormalizedNode<?, ?>[] OUTER_LIST_ONE_ITEM_INNER_LIST = initOuterListItems(OUTER_LIST_100K, ONE_ITEM_INNER_LIST);
+    private static final NormalizedNode<?, ?>[] OUTER_LIST_TWO_ITEM_INNER_LIST = initOuterListItems(OUTER_LIST_50K, TWO_ITEM_INNER_LIST);
+    private static final NormalizedNode<?, ?>[] OUTER_LIST_TEN_ITEM_INNER_LIST = initOuterListItems(OUTER_LIST_10K, TEN_ITEM_INNER_LIST);
+
+    private static NormalizedNode<?,?>[] initOuterListItems(int outerListItemsCount, MapNode innerList) {
+        final NormalizedNode<?,?>[] outerListItems = new NormalizedNode[outerListItemsCount];
+
+        for (int i = 0; i < outerListItemsCount; ++i) {
+            int outerListKey = i;
+            outerListItems[i] = ImmutableNodes.mapEntryBuilder(BenchmarkModel.OUTER_LIST_QNAME, BenchmarkModel.ID_QNAME, outerListKey)
+                .withChild(innerList).build();
+        }
+        return outerListItems;
+    }
+
+    protected SchemaContext schemaContext;
+    protected InMemoryDOMDataStore domStore;
+
+    abstract public void setUp() throws Exception;
+
+    abstract public void tearDown();
+
+    protected void initTestNode() throws Exception {
+        final YangInstanceIdentifier testPath = YangInstanceIdentifier.builder(BenchmarkModel.TEST_PATH)
+            .build();
+        DOMStoreReadWriteTransaction writeTx = domStore.newReadWriteTransaction();
+        writeTx.write(testPath, provideOuterListNode());
+
+        DOMStoreThreePhaseCommitCohort cohort = writeTx.ready();
+        cohort.canCommit().get();
+        cohort.preCommit().get();
+        cohort.commit().get();
+    }
+
+    private DataContainerChild<?, ?> provideOuterListNode() {
+        return ImmutableContainerNodeBuilder
+            .create()
+            .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(BenchmarkModel.TEST_QNAME))
+            .withChild(
+                ImmutableNodes.mapNodeBuilder(BenchmarkModel.OUTER_LIST_QNAME)
+                    .build()).build();
+    }
+
+    @Benchmark
+    @Warmup(iterations = WARMUP_ITERATIONS, timeUnit = TimeUnit.MILLISECONDS)
+    @Measurement(iterations = MEASUREMENT_ITERATIONS, timeUnit = TimeUnit.MILLISECONDS)
+    public void write100KSingleNodeWithOneInnerItemInOneCommitBenchmark() throws Exception {
+        DOMStoreReadWriteTransaction writeTx = domStore.newReadWriteTransaction();
+        for (int outerListKey = 0; outerListKey < OUTER_LIST_100K; ++outerListKey) {
+            writeTx.write(OUTER_LIST_100K_PATHS[outerListKey], OUTER_LIST_ONE_ITEM_INNER_LIST[outerListKey]);
+        }
+        DOMStoreThreePhaseCommitCohort cohort = writeTx.ready();
+        cohort.canCommit().get();
+        cohort.preCommit().get();
+        cohort.commit().get();
+    }
+
+    @Benchmark
+    @Warmup(iterations = WARMUP_ITERATIONS, timeUnit = TimeUnit.MILLISECONDS)
+    @Measurement(iterations = MEASUREMENT_ITERATIONS, timeUnit = TimeUnit.MILLISECONDS)
+    public void write100KSingleNodeWithOneInnerItemInCommitPerWriteBenchmark() throws Exception {
+        for (int outerListKey = 0; outerListKey < OUTER_LIST_100K; ++outerListKey) {
+            DOMStoreReadWriteTransaction writeTx = domStore.newReadWriteTransaction();
+            writeTx.write(OUTER_LIST_100K_PATHS[outerListKey], OUTER_LIST_ONE_ITEM_INNER_LIST[outerListKey]);
+
+            DOMStoreThreePhaseCommitCohort cohort = writeTx.ready();
+            cohort.canCommit().get();
+            cohort.preCommit().get();
+            cohort.commit().get();
+        }
+    }
+
+    @Benchmark
+    @Warmup(iterations = WARMUP_ITERATIONS, timeUnit = TimeUnit.MILLISECONDS)
+    @Measurement(iterations = MEASUREMENT_ITERATIONS, timeUnit = TimeUnit.MILLISECONDS)
+    public void write50KSingleNodeWithTwoInnerItemsInOneCommitBenchmark() throws Exception {
+        DOMStoreReadWriteTransaction writeTx = domStore.newReadWriteTransaction();
+        for (int outerListKey = 0; outerListKey < OUTER_LIST_50K; ++outerListKey) {
+            writeTx.write(OUTER_LIST_50K_PATHS[outerListKey], OUTER_LIST_TWO_ITEM_INNER_LIST[outerListKey]);
+        }
+        DOMStoreThreePhaseCommitCohort cohort = writeTx.ready();
+        cohort.canCommit().get();
+        cohort.preCommit().get();
+        cohort.commit().get();
+    }
+
+    @Benchmark
+    @Warmup(iterations = WARMUP_ITERATIONS, timeUnit = TimeUnit.MILLISECONDS)
+    @Measurement(iterations = MEASUREMENT_ITERATIONS, timeUnit = TimeUnit.MILLISECONDS)
+    public void write50KSingleNodeWithTwoInnerItemsInCommitPerWriteBenchmark() throws Exception {
+        for (int outerListKey = 0; outerListKey < OUTER_LIST_50K; ++outerListKey) {
+            DOMStoreReadWriteTransaction writeTx = domStore.newReadWriteTransaction();
+            writeTx.write(OUTER_LIST_50K_PATHS[outerListKey], OUTER_LIST_TWO_ITEM_INNER_LIST[outerListKey]);
+            DOMStoreThreePhaseCommitCohort cohort = writeTx.ready();
+            cohort.canCommit().get();
+            cohort.preCommit().get();
+            cohort.commit().get();
+        }
+    }
+
+    @Benchmark
+    @Warmup(iterations = WARMUP_ITERATIONS, timeUnit = TimeUnit.MILLISECONDS)
+    @Measurement(iterations = MEASUREMENT_ITERATIONS, timeUnit = TimeUnit.MILLISECONDS)
+    public void write10KSingleNodeWithTenInnerItemsInOneCommitBenchmark() throws Exception {
+        DOMStoreReadWriteTransaction writeTx = domStore.newReadWriteTransaction();
+        for (int outerListKey = 0; outerListKey < OUTER_LIST_10K; ++outerListKey) {
+            writeTx.write(OUTER_LIST_10K_PATHS[outerListKey], OUTER_LIST_TEN_ITEM_INNER_LIST[outerListKey]);
+        }
+        DOMStoreThreePhaseCommitCohort cohort = writeTx.ready();
+        cohort.canCommit().get();
+        cohort.preCommit().get();
+        cohort.commit().get();
+    }
+
+    @Benchmark
+    @Warmup(iterations = WARMUP_ITERATIONS, timeUnit = TimeUnit.MILLISECONDS)
+    @Measurement(iterations = MEASUREMENT_ITERATIONS, timeUnit = TimeUnit.MILLISECONDS)
+    public void write10KSingleNodeWithTenInnerItemsInCommitPerWriteBenchmark() throws Exception {
+        for (int outerListKey = 0; outerListKey < OUTER_LIST_10K; ++outerListKey) {
+            DOMStoreReadWriteTransaction writeTx = domStore.newReadWriteTransaction();
+            writeTx.write(OUTER_LIST_10K_PATHS[outerListKey], OUTER_LIST_TEN_ITEM_INNER_LIST[outerListKey]);
+            DOMStoreThreePhaseCommitCohort cohort = writeTx.ready();
+            cohort.canCommit().get();
+            cohort.preCommit().get();
+            cohort.commit().get();
+        }
+    }
+}
diff --git a/opendaylight/md-sal/benchmark-data-store/src/main/java/org/opendaylight/controller/md/sal/dom/store/benchmark/BenchmarkModel.java b/opendaylight/md-sal/benchmark-data-store/src/main/java/org/opendaylight/controller/md/sal/dom/store/benchmark/BenchmarkModel.java
new file mode 100644 (file)
index 0000000..024385b
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.store.benchmark;
+
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.Set;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+
+/**
+ * Benchmark Model class loads the odl-datastore-test.yang model from resources.
+ * <br>
+ * This class serves as facilitator class which holds several references to initialized yang model as static final
+ * members.
+ *
+ * @author Lukas Sedlak <lsedlak@cisco.com>
+ */
+public final class BenchmarkModel {
+
+    public static final QName TEST_QNAME = QName
+        .create("urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test", "2014-03-13","test");
+    public static final QName OUTER_LIST_QNAME = QName.create(TEST_QNAME, "outer-list");
+    public static final QName INNER_LIST_QNAME = QName.create(TEST_QNAME, "inner-list");
+    public static final QName ID_QNAME = QName.create(TEST_QNAME, "id");
+    public static final QName NAME_QNAME = QName.create(TEST_QNAME, "name");
+    private static final String DATASTORE_TEST_YANG = "/odl-datastore-test.yang";
+
+    public static final YangInstanceIdentifier TEST_PATH = YangInstanceIdentifier.of(TEST_QNAME);
+    public static final YangInstanceIdentifier OUTER_LIST_PATH = YangInstanceIdentifier.builder(TEST_PATH).node(OUTER_LIST_QNAME).build();
+
+    public static final InputStream getDatastoreBenchmarkInputStream() {
+        return getInputStream(DATASTORE_TEST_YANG);
+    }
+
+    private static InputStream getInputStream(final String resourceName) {
+        return BenchmarkModel.class.getResourceAsStream(resourceName);
+    }
+
+    public static SchemaContext createTestContext() {
+        YangParserImpl parser = new YangParserImpl();
+        Set<Module> modules = parser.parseYangModelsFromStreams(Collections.singletonList(
+            getDatastoreBenchmarkInputStream()));
+        return parser.resolveSchemaContext(modules);
+    }
+}
diff --git a/opendaylight/md-sal/benchmark-data-store/src/main/java/org/opendaylight/controller/md/sal/dom/store/benchmark/InMemoryDataStoreWithExecutorServiceBenchmark.java b/opendaylight/md-sal/benchmark-data-store/src/main/java/org/opendaylight/controller/md/sal/dom/store/benchmark/InMemoryDataStoreWithExecutorServiceBenchmark.java
new file mode 100644 (file)
index 0000000..4b9d66f
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.store.benchmark;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.TimeUnit;
+import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
+import org.opendaylight.yangtools.util.concurrent.SpecialExecutors;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+
+/**
+ * Benchmark for testing of performance of write operations for InMemoryDataStore. The instance
+ * of benchmark creates InMemoryDataStore with Data Change Listener Executor Service as BlockingBoundedFastThreadPool
+ * and DOM Store Executor Service as Blocking Bounded Fast Thread Pool.
+ *
+ * @see org.opendaylight.yangtools.util.concurrent.SpecialExecutors
+ * @see org.opendaylight.controller.md.sal.dom.store.benchmark.AbstractInMemoryDatastoreWriteTransactionBenchmark
+ *
+ * @author Lukas Sedlak <lsedlak@cisco.com>
+ */
+@State(Scope.Thread)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@Fork(1)
+public class InMemoryDataStoreWithExecutorServiceBenchmark extends AbstractInMemoryDatastoreWriteTransactionBenchmark  {
+
+    private static final int MAX_DATA_CHANGE_EXECUTOR_POOL_SIZE = 20;
+    private static final int MAX_DATA_CHANGE_EXECUTOR_QUEUE_SIZE = 1000;
+    private static final int MAX_DATA_STORE_EXECUTOR_QUEUE_SIZE = 5000;
+
+    @Setup(Level.Trial)
+    public void setUp() throws Exception {
+        final String name = "DS_BENCHMARK";
+        final ExecutorService dataChangeListenerExecutor = SpecialExecutors.newBlockingBoundedFastThreadPool(
+            MAX_DATA_CHANGE_EXECUTOR_POOL_SIZE, MAX_DATA_CHANGE_EXECUTOR_QUEUE_SIZE, name + "-DCL");
+
+        final ExecutorService domStoreExecutor = SpecialExecutors.newBoundedSingleThreadExecutor(
+            MAX_DATA_STORE_EXECUTOR_QUEUE_SIZE, "DOMStore-" + name );
+
+        domStore = new InMemoryDOMDataStore(name, domStoreExecutor,
+            dataChangeListenerExecutor);
+        schemaContext = BenchmarkModel.createTestContext();
+        domStore.onGlobalContextUpdated(schemaContext);
+        initTestNode();
+    }
+
+    @TearDown
+    public void tearDown() {
+        schemaContext = null;
+        domStore = null;
+    }
+}
diff --git a/opendaylight/md-sal/benchmark-data-store/src/main/java/org/opendaylight/controller/md/sal/dom/store/benchmark/InMemoryDataStoreWithSameThreadedExecutorBenchmark.java b/opendaylight/md-sal/benchmark-data-store/src/main/java/org/opendaylight/controller/md/sal/dom/store/benchmark/InMemoryDataStoreWithSameThreadedExecutorBenchmark.java
new file mode 100644 (file)
index 0000000..6a0cecc
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.store.benchmark;
+
+import com.google.common.util.concurrent.MoreExecutors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.TimeUnit;
+import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
+import org.opendaylight.yangtools.util.concurrent.SpecialExecutors;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+
+/**
+ * Benchmark for testing of performance of write operations for InMemoryDataStore. The instance
+ * of benchmark creates InMemoryDataStore with Data Change Listener Executor Service as Blocking Bounded Fast Thread Pool
+ * and DOM Store Executor Service as Same Thread Executor.
+ *
+ * @author Lukas Sedlak <lsedlak@cisco.com>
+ */
+@State(Scope.Thread)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@Fork(1)
+public class InMemoryDataStoreWithSameThreadedExecutorBenchmark extends AbstractInMemoryDatastoreWriteTransactionBenchmark {
+
+    private static final int MAX_DATA_CHANGE_EXECUTOR_POOL_SIZE = 20;
+    private static final int MAX_DATA_CHANGE_EXECUTOR_QUEUE_SIZE = 1000;
+
+    @Setup(Level.Trial)
+    public void setUp() throws Exception {
+        final String name = "DS_BENCHMARK";
+        final ExecutorService dataChangeListenerExecutor = SpecialExecutors.newBlockingBoundedFastThreadPool(
+            MAX_DATA_CHANGE_EXECUTOR_POOL_SIZE, MAX_DATA_CHANGE_EXECUTOR_QUEUE_SIZE, name + "-DCL");
+
+        domStore = new InMemoryDOMDataStore("SINGLE_THREADED_DS_BENCHMARK", MoreExecutors.sameThreadExecutor(),
+            dataChangeListenerExecutor);
+        schemaContext = BenchmarkModel.createTestContext();
+        domStore.onGlobalContextUpdated(schemaContext);
+        initTestNode();
+    }
+
+    @TearDown
+    public void tearDown() {
+        schemaContext = null;
+        domStore = null;
+    }
+}
diff --git a/opendaylight/md-sal/benchmark-data-store/src/main/java/org/opendaylight/controller/md/sal/dom/store/benchmark/InMemoryDataStoreWriteTransactionBenchmark.java b/opendaylight/md-sal/benchmark-data-store/src/main/java/org/opendaylight/controller/md/sal/dom/store/benchmark/InMemoryDataStoreWriteTransactionBenchmark.java
new file mode 100644 (file)
index 0000000..d3dda96
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.store.benchmark;
+
+import com.google.common.util.concurrent.MoreExecutors;
+import java.util.concurrent.TimeUnit;
+import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.TearDown;
+
+/**
+ * Benchmark for testing of performance of write operations for InMemoryDataStore. The instance
+ * of benchmark creates InMemoryDataStore with Data Change Listener Executor Service as Same Thread Executor
+ * and DOM Store Executor Service as Same Thread Executor.
+ *
+ * @author Lukas Sedlak <lsedlak@cisco.com>
+ */
+@State(Scope.Thread)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@Fork(1)
+public class InMemoryDataStoreWriteTransactionBenchmark extends AbstractInMemoryDatastoreWriteTransactionBenchmark {
+
+    @Setup(Level.Trial)
+    public void setUp() throws Exception {
+        domStore = new InMemoryDOMDataStore("SINGLE_THREADED_DS_BENCHMARK", MoreExecutors.sameThreadExecutor(),
+            MoreExecutors.sameThreadExecutor());
+        schemaContext = BenchmarkModel.createTestContext();
+        domStore.onGlobalContextUpdated(schemaContext);
+        initTestNode();
+    }
+
+    @TearDown
+    public void tearDown() {
+        schemaContext = null;
+        domStore = null;
+    }
+}
diff --git a/opendaylight/md-sal/benchmark-data-store/src/main/resources/odl-datastore-test.yang b/opendaylight/md-sal/benchmark-data-store/src/main/resources/odl-datastore-test.yang
new file mode 100644 (file)
index 0000000..730ca17
--- /dev/null
@@ -0,0 +1,42 @@
+module odl-datastore-test {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test";
+    prefix "store-test";
+    
+    revision "2014-03-13" {
+        description "Initial revision.";
+    }
+
+    container test {
+        list outer-list {
+            key id;
+            leaf id {
+                type int32;
+            }
+            choice outer-choice {
+                case one {
+                    leaf one {
+                        type string;
+                    }
+                }
+                case two-three {
+                    leaf two {
+                        type string;
+                    }
+                    leaf three {
+                        type string;
+                    }
+               }
+           }
+           list inner-list {
+                key name;
+                leaf name {
+                    type int32;
+                }
+                leaf value {
+                    type string;
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
index ce830eaa62d3e1f23c288f1969b1e79969252cf7..71a0de9939a2693e2a93a62a1611ff852ab59b2c 100644 (file)
         <module>sal-binding-dom-it</module>
       </modules>
     </profile>
+    <profile>
+      <id>benchmarks</id>
+      <activation>
+        <activeByDefault>false</activeByDefault>
+      </activation>
+      <modules>
+        <module>benchmark-data-store</module>
+      </modules>
+    </profile>
   </profiles>
 </project>
\ No newline at end of file