From 03a638b95da83e150d4f69451c8733b5f09c37aa Mon Sep 17 00:00:00 2001 From: Maros Marsalek Date: Thu, 3 Nov 2016 16:24:17 +0100 Subject: HONEYCOMB-287 Infra micro-benchmarks Config (write) Operational (read) Add -Pbenchmark to maven execution to include benchmarks Change-Id: Ia4815ffc109e34629279b9418b962a9f91c38c30 Signed-off-by: Maros Marsalek --- .../fd/honeycomb/benchmark/util/DataProvider.java | 197 +++++++++++++++++++++ .../fd/honeycomb/benchmark/util/DataSubmitter.java | 40 +++++ .../fd/honeycomb/benchmark/util/FileManager.java | 41 +++++ .../io/fd/honeycomb/benchmark/util/NoopWriter.java | 63 +++++++ .../fd/honeycomb/benchmark/util/StaticReader.java | 83 +++++++++ 5 files changed, 424 insertions(+) create mode 100644 infra/it/benchmark/src/main/java/io/fd/honeycomb/benchmark/util/DataProvider.java create mode 100644 infra/it/benchmark/src/main/java/io/fd/honeycomb/benchmark/util/DataSubmitter.java create mode 100644 infra/it/benchmark/src/main/java/io/fd/honeycomb/benchmark/util/FileManager.java create mode 100644 infra/it/benchmark/src/main/java/io/fd/honeycomb/benchmark/util/NoopWriter.java create mode 100644 infra/it/benchmark/src/main/java/io/fd/honeycomb/benchmark/util/StaticReader.java (limited to 'infra/it/benchmark/src/main/java/io/fd/honeycomb/benchmark/util') diff --git a/infra/it/benchmark/src/main/java/io/fd/honeycomb/benchmark/util/DataProvider.java b/infra/it/benchmark/src/main/java/io/fd/honeycomb/benchmark/util/DataProvider.java new file mode 100644 index 000000000..7d3df2691 --- /dev/null +++ b/infra/it/benchmark/src/main/java/io/fd/honeycomb/benchmark/util/DataProvider.java @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed 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 io.fd.honeycomb.benchmark.util; + +import static com.google.common.base.Preconditions.checkArgument; + +import com.google.common.collect.Lists; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.ContainerWithList; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.SimpleContainer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.SimpleContainerBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.container.with.list.ListInContainer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.container.with.list.ListInContainerBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.container.with.list.ListInContainerKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.container.with.list.list.in.container.ContainerInListBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.container.with.list.list.in.container.container.in.list.NestedList; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.container.with.list.list.in.container.container.in.list.NestedListBuilder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public interface DataProvider { + + String SIMPLE_CONTAINER = "simple-container"; + String LIST_IN_CONTAINER = "list-in-container"; + String COMPLEX_LIST_IN_CONTAINER = "complex-list-in-container"; + + InstanceIdentifier getId(final long counter); + + DataObject getData(final long counter); + + static DataProvider from(String data) { + return new MapBackedDataProvider(data); + } + + final class MapBackedDataProvider implements DataProvider { + + private static final Map map; + + static { + map = new HashMap<>(); + + final InstanceIdentifier simpleContainerId = InstanceIdentifier.create(SimpleContainer.class); + map.put(SIMPLE_CONTAINER, new MultiValueDataProvider(Lists.newArrayList( + // Multiple values of container to ensure each time the value in DS after commit changes to trigger + // writers in test + new SingleValueDataProvider<>( + new SimpleContainerBuilder().setSimpleContainerName("first").build(), simpleContainerId), + new SingleValueDataProvider<>( + new SimpleContainerBuilder().setSimpleContainerName("second").build(), simpleContainerId), + new SingleValueDataProvider<>( + new SimpleContainerBuilder().setSimpleContainerName("third").build(), simpleContainerId)) + )); + map.put(LIST_IN_CONTAINER, new MultiValueDataProvider(getListInContainerValues(100_000))); + map.put(COMPLEX_LIST_IN_CONTAINER, + new MultiValueDataProvider(getComplexListInContainerValues(100_000))); + } + + private final DataProvider delegate; + + MapBackedDataProvider(final String data) { + checkArgument(map.containsKey(data)); + this.delegate = map.get(data); + } + + @Override + public InstanceIdentifier getId(final long counter) { + return delegate.getId(counter); + } + + @Override + public DataObject getData(final long counter) { + return delegate.getData(counter); + } + + @Override + public String toString() { + return "MapBackedDataProvider{" + + "delegate=" + delegate + + '}'; + } + } + + + static List getListInContainerValues(final int i) { + return IntStream.range(0, i) + .mapToObj(idx -> new SingleValueDataProvider<>( + new ListInContainerBuilder() + .setId((long) idx) + .build(), + InstanceIdentifier.create(ContainerWithList.class) + .child(ListInContainer.class, new ListInContainerKey((long) idx)) + )) + .collect(Collectors.toList()); + } + + static List getComplexListInContainerValues(final int i) { + return IntStream.range(0, i) + .mapToObj(idx -> new SingleValueDataProvider<>( + new ListInContainerBuilder() + .setId((long) idx) + .setContainerInList(new ContainerInListBuilder() + .setName("nested container") + .setNestedList(Lists.newArrayList( + getNestedList("1"), + getNestedList("2"), + getNestedList("3"))) + .build()) + .build(), + InstanceIdentifier.create(ContainerWithList.class) + .child(ListInContainer.class, new ListInContainerKey((long) idx)) + )) + .collect(Collectors.toList()); + } + + static NestedList getNestedList(final String value) { + return new NestedListBuilder() + .setNestedId(value) + .setNestedName(value + "N") + .build(); + } + + final class SingleValueDataProvider implements DataProvider { + + private final DataObject data; + private final InstanceIdentifier id; + + SingleValueDataProvider(final T data, final InstanceIdentifier id) { + this.data = data; + this.id = id; + } + + @Override + public InstanceIdentifier getId(final long counter) { + return id; + } + + @Override + public DataObject getData(final long counter) { + return data; + } + + @Override + public String toString() { + return "SingleValueDataProvider{" + + "data=" + data + + ", id=" + id + + '}'; + } + } + + final class MultiValueDataProvider implements DataProvider { + + private final List values; + private int valueSize; + + public MultiValueDataProvider(final List values) { + // Wrap as array list so that index lookup is fast + this.values = Lists.newArrayList(values); + this.valueSize = values.size(); + } + + @Override + public InstanceIdentifier getId(final long counter) { + return values.get((int) (counter % valueSize)).getId(counter); + } + + @Override + public DataObject getData(final long counter) { + return values.get((int) (counter % valueSize)).getData(counter); + } + + @Override + public String toString() { + return "MultiValueDataProvider{" + + "valueSize=" + valueSize + + '}'; + } + } +} diff --git a/infra/it/benchmark/src/main/java/io/fd/honeycomb/benchmark/util/DataSubmitter.java b/infra/it/benchmark/src/main/java/io/fd/honeycomb/benchmark/util/DataSubmitter.java new file mode 100644 index 000000000..ebad65335 --- /dev/null +++ b/infra/it/benchmark/src/main/java/io/fd/honeycomb/benchmark/util/DataSubmitter.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed 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 io.fd.honeycomb.benchmark.util; + +import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +@FunctionalInterface +public interface DataSubmitter { + + void submit(LogicalDatastoreType type, WriteTransaction tx, InstanceIdentifier id, DataObject data); + + public static DataSubmitter from(String operation) { + switch (operation) { + case "put": { + return (type, tx, id, data) -> tx.put(type, (InstanceIdentifier) id, data); + } + case "merge": { + return (type, tx, id, data) -> tx.merge(type, (InstanceIdentifier) id, data); + } + default: throw new UnsupportedOperationException("Operation: " + operation); + } + } +} diff --git a/infra/it/benchmark/src/main/java/io/fd/honeycomb/benchmark/util/FileManager.java b/infra/it/benchmark/src/main/java/io/fd/honeycomb/benchmark/util/FileManager.java new file mode 100644 index 000000000..8aa9f9370 --- /dev/null +++ b/infra/it/benchmark/src/main/java/io/fd/honeycomb/benchmark/util/FileManager.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed 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 io.fd.honeycomb.benchmark.util; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +public interface FileManager { + + FileManager INSTANCE = new FileManager() {}; + + default Path createTempFile(String config) throws IOException { + return Files.createTempFile("hcbenchmark", config); + } + + default void deleteFile(final Path toDelete) { + if (toDelete != null) { + try { + Files.delete(toDelete); + } catch (IOException e) { + // NOOP, dont care about temp files too much + } + } + } + +} diff --git a/infra/it/benchmark/src/main/java/io/fd/honeycomb/benchmark/util/NoopWriter.java b/infra/it/benchmark/src/main/java/io/fd/honeycomb/benchmark/util/NoopWriter.java new file mode 100644 index 000000000..f61bd1b5d --- /dev/null +++ b/infra/it/benchmark/src/main/java/io/fd/honeycomb/benchmark/util/NoopWriter.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed 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 io.fd.honeycomb.benchmark.util; + +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.honeycomb.translate.write.Writer; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import javax.annotation.concurrent.NotThreadSafe; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * Noop writer suitable for lists as well. + */ +@NotThreadSafe +public final class NoopWriter implements Writer { + + private final InstanceIdentifier id; + private long counter = 0; + + public NoopWriter(final InstanceIdentifier id) { + this.id = id; + } + + @Override + public void update(@Nonnull final InstanceIdentifier id, + @Nullable final DataObject dataBefore, + @Nullable final DataObject dataAfter, + @Nonnull final WriteContext ctx) throws WriteFailedException { + counter++; + // NOOP + } + + @Nonnull + @Override + public InstanceIdentifier getManagedDataObjectType() { + return id; + } + + @Override + public String toString() { + return "NoopWriter{" + + id.getTargetType().getSimpleName() + + ", counter=" + counter + + '}'; + } +} diff --git a/infra/it/benchmark/src/main/java/io/fd/honeycomb/benchmark/util/StaticReader.java b/infra/it/benchmark/src/main/java/io/fd/honeycomb/benchmark/util/StaticReader.java new file mode 100644 index 000000000..90e560152 --- /dev/null +++ b/infra/it/benchmark/src/main/java/io/fd/honeycomb/benchmark/util/StaticReader.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed 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 io.fd.honeycomb.benchmark.util; + +import com.google.common.base.Optional; +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.read.Reader; +import javax.annotation.Nonnull; +import javax.annotation.concurrent.NotThreadSafe; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * Statically preconfigured reader. + */ +@NotThreadSafe +public final class StaticReader> implements Reader { + + private final InstanceIdentifier id; + private final DataProvider data; + private long counter = 0; + + public StaticReader(final InstanceIdentifier id, final DataProvider data) { + this.id = id; + this.data = data; + } + + @Nonnull + @Override + public InstanceIdentifier getManagedDataObjectType() { + return id; + } + + @Override + public String toString() { + return "NoopReader{" + + id.getTargetType().getSimpleName() + + ", counter=" + counter + + '}'; + } + + @Nonnull + @Override + public Optional read(@Nonnull final InstanceIdentifier id, + @Nonnull final ReadContext ctx) throws ReadFailedException { + counter++; + return Optional.of(data.getData(counter)); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final B builder, + @Nonnull final ReadContext ctx) + throws ReadFailedException { + throw new UnsupportedOperationException("No read current attrs!"); + } + + @Nonnull + @Override + public B getBuilder(final InstanceIdentifier id) { + throw new UnsupportedOperationException("No builder!"); + } + + @Override + public void merge(@Nonnull final Builder parentBuilder, @Nonnull final T readValue) { + throw new UnsupportedOperationException("No merge!"); + } +} -- cgit 1.2.3-korg