Add datastore benchmark 57/89457/2
authorRobert Varga <robert.varga@pantheon.tech>
Mon, 27 Apr 2020 19:14:57 +0000 (21:14 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Mon, 27 Apr 2020 20:51:28 +0000 (22:51 +0200)
Change-Id: I2e5b1589805ddf9feae4d54667e60483a6c16530
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
artifacts/pom.xml
dom/mdsal-dom-inmemory-datastore-benchmark/pom.xml [new file with mode: 0644]
dom/mdsal-dom-inmemory-datastore-benchmark/src/main/java/org/opendaylight/mdsal/dom/store/inmemory/benchmark/AbstractInMemoryBrokerWriteTransactionBenchmark.java [new file with mode: 0644]
dom/mdsal-dom-inmemory-datastore-benchmark/src/main/java/org/opendaylight/mdsal/dom/store/inmemory/benchmark/AbstractInMemoryDatastoreWriteTransactionBenchmark.java [new file with mode: 0644]
dom/mdsal-dom-inmemory-datastore-benchmark/src/main/java/org/opendaylight/mdsal/dom/store/inmemory/benchmark/AbstractInMemoryWriteTransactionBenchmark.java [new file with mode: 0644]
dom/mdsal-dom-inmemory-datastore-benchmark/src/main/java/org/opendaylight/mdsal/dom/store/inmemory/benchmark/BenchmarkModel.java [new file with mode: 0644]
dom/mdsal-dom-inmemory-datastore-benchmark/src/main/java/org/opendaylight/mdsal/dom/store/inmemory/benchmark/InMemoryBrokerWriteTransactionBenchmark.java [new file with mode: 0644]
dom/mdsal-dom-inmemory-datastore-benchmark/src/main/java/org/opendaylight/mdsal/dom/store/inmemory/benchmark/InMemoryDataStoreWithSameThreadedExecutorBenchmark.java [new file with mode: 0644]
dom/mdsal-dom-inmemory-datastore-benchmark/src/main/java/org/opendaylight/mdsal/dom/store/inmemory/benchmark/InMemoryDataStoreWriteTransactionBenchmark.java [new file with mode: 0644]
dom/mdsal-dom-inmemory-datastore-benchmark/src/main/resources/odl-datastore-test.yang [new file with mode: 0644]
dom/pom.xml

index 68f004e4135538a014cc08d6e8a639eb4d13ac64..92bdcb3a7ab221c3d43ae53e8e15ea062adca729 100644 (file)
                 <artifactId>mdsal-dom-inmemory-datastore</artifactId>
                 <version>6.0.1-SNAPSHOT</version>
             </dependency>
+            <dependency>
+                <groupId>org.opendaylight.mdsal</groupId>
+                <artifactId>mdsal-dom-inmemory-datastore-benchmark</artifactId>
+                <version>6.0.1-SNAPSHOT</version>
+                <scope>test</scope>
+            </dependency>
 
             <!-- Binding MD-SAL & Java Binding -->
             <dependency>
diff --git a/dom/mdsal-dom-inmemory-datastore-benchmark/pom.xml b/dom/mdsal-dom-inmemory-datastore-benchmark/pom.xml
new file mode 100644 (file)
index 0000000..e9005a2
--- /dev/null
@@ -0,0 +1,101 @@
+<?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">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.opendaylight.mdsal</groupId>
+        <artifactId>dom-parent</artifactId>
+        <version>6.0.1-SNAPSHOT</version>
+        <relativePath>../dom-parent</relativePath>
+    </parent>
+
+    <groupId>org.opendaylight.mdsal</groupId>
+    <artifactId>mdsal-dom-inmemory-datastore-benchmark</artifactId>
+    <packaging>jar</packaging>
+
+    <properties>
+        <odlparent.spotbugs.skip>true</odlparent.spotbugs.skip>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>yang-data-impl</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.openjdk.jmh</groupId>
+            <artifactId>jmh-core</artifactId>
+            <version>1.23</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.mdsal</groupId>
+            <artifactId>mdsal-dom-inmemory-datastore</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.mdsal</groupId>
+            <artifactId>mdsal-dom-broker</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>yang-test-util</artifactId>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <annotationProcessorPaths>
+                        <dependency>
+                            <groupId>org.openjdk.jmh</groupId>
+                            <artifactId>jmh-generator-annprocess</artifactId>
+                            <version>1.23</version>
+                        </dependency>
+                    </annotationProcessorPaths>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <profiles>
+        <profile>
+            <id>benchmarks</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>exec-maven-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>run-benchmarks</id>
+                                <phase>integration-test</phase>
+                                <goals>
+                                    <goal>exec</goal>
+                                </goals>
+                                <configuration>
+                                    <classpathScope>test</classpathScope>
+                                    <executable>java</executable>
+                                    <arguments>
+                                        <argument>-classpath</argument>
+                                        <classpath />
+                                        <argument>org.openjdk.jmh.Main</argument>
+                                        <argument>.*</argument>
+                                    </arguments>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+</project>
diff --git a/dom/mdsal-dom-inmemory-datastore-benchmark/src/main/java/org/opendaylight/mdsal/dom/store/inmemory/benchmark/AbstractInMemoryBrokerWriteTransactionBenchmark.java b/dom/mdsal-dom-inmemory-datastore-benchmark/src/main/java/org/opendaylight/mdsal/dom/store/inmemory/benchmark/AbstractInMemoryBrokerWriteTransactionBenchmark.java
new file mode 100644 (file)
index 0000000..ed6b47a
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2013, 2017 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.mdsal.dom.store.inmemory.benchmark;
+
+import java.util.concurrent.TimeUnit;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
+import org.opendaylight.mdsal.dom.broker.SerializedDOMDataBroker;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Warmup;
+
+/**
+ * Abstract class to handle transaction benchmarks.
+ *
+ * @author Lukas Sedlak
+ */
+public abstract class AbstractInMemoryBrokerWriteTransactionBenchmark
+        extends AbstractInMemoryWriteTransactionBenchmark {
+
+    protected SerializedDOMDataBroker domBroker;
+
+    protected void initTestNode() throws Exception {
+        final YangInstanceIdentifier testPath = YangInstanceIdentifier.builder(BenchmarkModel.TEST_PATH).build();
+        DOMDataTreeReadWriteTransaction writeTx = domBroker.newReadWriteTransaction();
+        writeTx.put(LogicalDatastoreType.OPERATIONAL, testPath, provideOuterListNode());
+
+        writeTx.commit().get();
+    }
+
+    @Benchmark
+    @Warmup(iterations = WARMUP_ITERATIONS, timeUnit = TimeUnit.MILLISECONDS)
+    @Measurement(iterations = MEASUREMENT_ITERATIONS, timeUnit = TimeUnit.MILLISECONDS)
+    public void write100KSingleNodeWithOneInnerItemInOneCommitBenchmark() throws Exception {
+
+        DOMDataTreeReadWriteTransaction writeTx = domBroker.newReadWriteTransaction();
+        for (int outerListKey = 0; outerListKey < OUTER_LIST_100K; ++outerListKey) {
+            writeTx.put(LogicalDatastoreType.OPERATIONAL, OUTER_LIST_100K_PATHS[outerListKey],
+                    OUTER_LIST_ONE_ITEM_INNER_LIST[outerListKey]);
+        }
+
+        writeTx.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) {
+            DOMDataTreeReadWriteTransaction writeTx = domBroker.newReadWriteTransaction();
+            writeTx.put(LogicalDatastoreType.OPERATIONAL, OUTER_LIST_100K_PATHS[outerListKey],
+                    OUTER_LIST_ONE_ITEM_INNER_LIST[outerListKey]);
+
+            writeTx.commit().get();
+        }
+    }
+
+    @Benchmark
+    @Warmup(iterations = WARMUP_ITERATIONS, timeUnit = TimeUnit.MILLISECONDS)
+    @Measurement(iterations = MEASUREMENT_ITERATIONS, timeUnit = TimeUnit.MILLISECONDS)
+    public void write50KSingleNodeWithTwoInnerItemsInOneCommitBenchmark() throws Exception {
+        DOMDataTreeReadWriteTransaction writeTx = domBroker.newReadWriteTransaction();
+        for (int outerListKey = 0; outerListKey < OUTER_LIST_50K; ++outerListKey) {
+            writeTx.put(LogicalDatastoreType.OPERATIONAL, OUTER_LIST_50K_PATHS[outerListKey],
+                    OUTER_LIST_TWO_ITEM_INNER_LIST[outerListKey]);
+        }
+
+        writeTx.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) {
+            DOMDataTreeReadWriteTransaction writeTx = domBroker.newReadWriteTransaction();
+            writeTx.put(LogicalDatastoreType.OPERATIONAL, OUTER_LIST_50K_PATHS[outerListKey],
+                    OUTER_LIST_TWO_ITEM_INNER_LIST[outerListKey]);
+            writeTx.commit().get();
+        }
+    }
+
+    @Benchmark
+    @Warmup(iterations = WARMUP_ITERATIONS, timeUnit = TimeUnit.MILLISECONDS)
+    @Measurement(iterations = MEASUREMENT_ITERATIONS, timeUnit = TimeUnit.MILLISECONDS)
+    public void write10KSingleNodeWithTenInnerItemsInOneCommitBenchmark() throws Exception {
+        DOMDataTreeReadWriteTransaction writeTx = domBroker.newReadWriteTransaction();
+        for (int outerListKey = 0; outerListKey < OUTER_LIST_10K; ++outerListKey) {
+            writeTx.put(LogicalDatastoreType.OPERATIONAL, OUTER_LIST_10K_PATHS[outerListKey],
+                    OUTER_LIST_TEN_ITEM_INNER_LIST[outerListKey]);
+        }
+        writeTx.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) {
+            DOMDataTreeReadWriteTransaction writeTx = domBroker.newReadWriteTransaction();
+            writeTx.put(LogicalDatastoreType.OPERATIONAL, OUTER_LIST_10K_PATHS[outerListKey],
+                    OUTER_LIST_TEN_ITEM_INNER_LIST[outerListKey]);
+            writeTx.commit().get();
+        }
+    }
+}
diff --git a/dom/mdsal-dom-inmemory-datastore-benchmark/src/main/java/org/opendaylight/mdsal/dom/store/inmemory/benchmark/AbstractInMemoryDatastoreWriteTransactionBenchmark.java b/dom/mdsal-dom-inmemory-datastore-benchmark/src/main/java/org/opendaylight/mdsal/dom/store/inmemory/benchmark/AbstractInMemoryDatastoreWriteTransactionBenchmark.java
new file mode 100644 (file)
index 0000000..7d15db5
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2013, 2017 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.mdsal.dom.store.inmemory.benchmark;
+
+import java.util.concurrent.TimeUnit;
+import org.opendaylight.mdsal.dom.spi.store.DOMStoreReadWriteTransaction;
+import org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort;
+import org.opendaylight.mdsal.dom.store.inmemory.InMemoryDOMDataStore;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Warmup;
+
+/**
+ * Abstract class for in-memory Datastore transaction benchmarks.
+ *
+ * @author Lukas Sedlak
+ */
+public abstract class AbstractInMemoryDatastoreWriteTransactionBenchmark
+        extends AbstractInMemoryWriteTransactionBenchmark {
+
+    protected InMemoryDOMDataStore domStore;
+
+    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();
+    }
+
+    @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/dom/mdsal-dom-inmemory-datastore-benchmark/src/main/java/org/opendaylight/mdsal/dom/store/inmemory/benchmark/AbstractInMemoryWriteTransactionBenchmark.java b/dom/mdsal-dom-inmemory-datastore-benchmark/src/main/java/org/opendaylight/mdsal/dom/store/inmemory/benchmark/AbstractInMemoryWriteTransactionBenchmark.java
new file mode 100644 (file)
index 0000000..29b557c
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2014, 2017 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.mdsal.dom.store.inmemory.benchmark;
+
+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.EffectiveModelContext;
+
+public abstract class AbstractInMemoryWriteTransactionBenchmark {
+    protected static final int OUTER_LIST_100K = 100000;
+    protected static final int OUTER_LIST_50K = 50000;
+    protected static final int OUTER_LIST_10K = 10000;
+
+    protected static final YangInstanceIdentifier[] OUTER_LIST_100K_PATHS = initOuterListPaths(OUTER_LIST_100K);
+    protected static final YangInstanceIdentifier[] OUTER_LIST_50K_PATHS = initOuterListPaths(OUTER_LIST_50K);
+    protected 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;
+    }
+
+    protected static final int WARMUP_ITERATIONS = 6;
+    protected static final int MEASUREMENT_ITERATIONS = 6;
+
+    protected static final MapNode ONE_ITEM_INNER_LIST = initInnerListItems(1);
+    protected static final MapNode TWO_ITEM_INNER_LIST = initInnerListItems(2);
+    protected 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();
+    }
+
+    protected static final NormalizedNode<?, ?>[] OUTER_LIST_ONE_ITEM_INNER_LIST = initOuterListItems(OUTER_LIST_100K,
+            ONE_ITEM_INNER_LIST);
+    protected static final NormalizedNode<?, ?>[] OUTER_LIST_TWO_ITEM_INNER_LIST = initOuterListItems(OUTER_LIST_50K,
+            TWO_ITEM_INNER_LIST);
+    protected static final NormalizedNode<?, ?>[] OUTER_LIST_TEN_ITEM_INNER_LIST = initOuterListItems(OUTER_LIST_10K,
+            TEN_ITEM_INNER_LIST);
+
+    private static NormalizedNode<?, ?>[] initOuterListItems(final int outerListItemsCount, final 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 EffectiveModelContext schemaContext;
+
+    public abstract void setUp() throws Exception;
+
+    public abstract void tearDown();
+
+    protected static DataContainerChild<?, ?> provideOuterListNode() {
+        return ImmutableContainerNodeBuilder.create()
+                .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(BenchmarkModel.TEST_QNAME))
+                .withChild(ImmutableNodes.mapNodeBuilder(BenchmarkModel.OUTER_LIST_QNAME).build()).build();
+    }
+}
diff --git a/dom/mdsal-dom-inmemory-datastore-benchmark/src/main/java/org/opendaylight/mdsal/dom/store/inmemory/benchmark/BenchmarkModel.java b/dom/mdsal-dom-inmemory-datastore-benchmark/src/main/java/org/opendaylight/mdsal/dom/store/inmemory/benchmark/BenchmarkModel.java
new file mode 100644 (file)
index 0000000..e108fc2
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2013, 2017 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.mdsal.dom.store.inmemory.benchmark;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
+import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
+
+/**
+ * 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
+ */
+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();
+
+    private BenchmarkModel() {
+    }
+
+    public static EffectiveModelContext createTestContext() {
+        return YangParserTestUtils.parseYangResources(BenchmarkModel.class, DATASTORE_TEST_YANG);
+    }
+}
diff --git a/dom/mdsal-dom-inmemory-datastore-benchmark/src/main/java/org/opendaylight/mdsal/dom/store/inmemory/benchmark/InMemoryBrokerWriteTransactionBenchmark.java b/dom/mdsal-dom-inmemory-datastore-benchmark/src/main/java/org/opendaylight/mdsal/dom/store/inmemory/benchmark/InMemoryBrokerWriteTransactionBenchmark.java
new file mode 100644 (file)
index 0000000..516a255
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2014, 2017 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.mdsal.dom.store.inmemory.benchmark;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+import java.util.Map;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.dom.broker.SerializedDOMDataBroker;
+import org.opendaylight.mdsal.dom.spi.store.DOMStore;
+import org.opendaylight.mdsal.dom.store.inmemory.InMemoryDOMDataStore;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+@State(Scope.Thread)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@Fork(1)
+public class InMemoryBrokerWriteTransactionBenchmark extends AbstractInMemoryBrokerWriteTransactionBenchmark {
+    private ListeningExecutorService executor = null;
+
+    @Setup(Level.Trial)
+    @Override
+    public void setUp() throws Exception {
+        ListeningExecutorService dsExec = MoreExecutors.newDirectExecutorService();
+        executor = MoreExecutors.listeningDecorator(
+                MoreExecutors.getExitingExecutorService((ThreadPoolExecutor) Executors.newFixedThreadPool(1), 1L,
+                        TimeUnit.SECONDS));
+
+        InMemoryDOMDataStore operStore = new InMemoryDOMDataStore("OPER", dsExec);
+        InMemoryDOMDataStore configStore = new InMemoryDOMDataStore("CFG", dsExec);
+        Map<LogicalDatastoreType, DOMStore> datastores = ImmutableMap.of(
+            LogicalDatastoreType.OPERATIONAL, (DOMStore)operStore,
+            LogicalDatastoreType.CONFIGURATION, configStore);
+
+        domBroker = new SerializedDOMDataBroker(datastores, executor);
+        schemaContext = BenchmarkModel.createTestContext();
+        configStore.onModelContextUpdated(schemaContext);
+        operStore.onModelContextUpdated(schemaContext);
+        initTestNode();
+    }
+
+    @Override
+    public void tearDown() {
+        domBroker.close();
+        executor.shutdown();
+    }
+}
diff --git a/dom/mdsal-dom-inmemory-datastore-benchmark/src/main/java/org/opendaylight/mdsal/dom/store/inmemory/benchmark/InMemoryDataStoreWithSameThreadedExecutorBenchmark.java b/dom/mdsal-dom-inmemory-datastore-benchmark/src/main/java/org/opendaylight/mdsal/dom/store/inmemory/benchmark/InMemoryDataStoreWithSameThreadedExecutorBenchmark.java
new file mode 100644 (file)
index 0000000..9184b39
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2013, 2017 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.mdsal.dom.store.inmemory.benchmark;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.TimeUnit;
+import org.opendaylight.mdsal.dom.store.inmemory.InMemoryDOMDataStore;
+import org.opendaylight.yangtools.util.concurrent.SpecialExecutors;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+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 Blocking Bounded Fast Thread Pool
+ * and DOM Store Executor Service as Same Thread Executor.
+ *
+ * @author Lukas Sedlak
+ */
+@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;
+
+    @Override
+    @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",
+                InMemoryDataStoreWithSameThreadedExecutorBenchmark.class);
+
+        domStore = new InMemoryDOMDataStore("SINGLE_THREADED_DS_BENCHMARK", dataChangeListenerExecutor);
+        schemaContext = BenchmarkModel.createTestContext();
+        domStore.onModelContextUpdated(schemaContext);
+        initTestNode();
+    }
+
+    @Override
+    @TearDown
+    public void tearDown() {
+        schemaContext = null;
+        domStore = null;
+    }
+}
diff --git a/dom/mdsal-dom-inmemory-datastore-benchmark/src/main/java/org/opendaylight/mdsal/dom/store/inmemory/benchmark/InMemoryDataStoreWriteTransactionBenchmark.java b/dom/mdsal-dom-inmemory-datastore-benchmark/src/main/java/org/opendaylight/mdsal/dom/store/inmemory/benchmark/InMemoryDataStoreWriteTransactionBenchmark.java
new file mode 100644 (file)
index 0000000..2d44373
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * 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.mdsal.dom.store.inmemory.benchmark;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import org.opendaylight.mdsal.dom.store.inmemory.InMemoryDOMDataStore;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+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
+ */
+@State(Scope.Thread)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@Fork(1)
+public class InMemoryDataStoreWriteTransactionBenchmark extends AbstractInMemoryDatastoreWriteTransactionBenchmark {
+
+    @Override
+    @Setup(Level.Trial)
+    public void setUp() throws Exception {
+        domStore = new InMemoryDOMDataStore("SINGLE_THREADED_DS_BENCHMARK", Executors.newSingleThreadExecutor());
+        schemaContext = BenchmarkModel.createTestContext();
+        domStore.onModelContextUpdated(schemaContext);
+        initTestNode();
+    }
+
+    @Override
+    @TearDown
+    public void tearDown() {
+        schemaContext = null;
+        domStore = null;
+    }
+}
diff --git a/dom/mdsal-dom-inmemory-datastore-benchmark/src/main/resources/odl-datastore-test.yang b/dom/mdsal-dom-inmemory-datastore-benchmark/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 96c8b237302902b4405f753fa88cab836740553d..ee76e0e548deb121bd888d8ce70db9859bc78da6 100644 (file)
@@ -29,6 +29,7 @@
         <module>mdsal-dom-spi</module>
         <module>mdsal-dom-broker</module>
         <module>mdsal-dom-inmemory-datastore</module>
+        <module>mdsal-dom-inmemory-datastore-benchmark</module>
         <module>mdsal-dom-schema-osgi</module>
     </modules>