diff --git a/.classpath b/.classpath index 9022062d8dfa64335dc564f900678538dac21bd5..abce7149466c4bdeeedaa5ff1de5103a25f09f4a 100644 --- a/.classpath +++ b/.classpath @@ -24,7 +24,7 @@ </attributes> </classpathentry> <classpathentry including="**/*.java" kind="src" path="src/main/resources"/> - <classpathentry including="**/*.java" kind="src" path="src/test/resources"/> + <classpathentry kind="src" path="src/test/resources"/> <classpathentry kind="src" path="conf"/> <classpathentry kind="output" path="target/classes"/> </classpath> diff --git a/.settings/edu.umd.cs.findbugs.core.prefs b/.settings/edu.umd.cs.findbugs.core.prefs index 527228eb769009cd2c41b115b380f0074e067da0..ea3e4a51534a26c1a1cb963891c1838d4fcd02ed 100644 --- a/.settings/edu.umd.cs.findbugs.core.prefs +++ b/.settings/edu.umd.cs.findbugs.core.prefs @@ -1,5 +1,5 @@ #FindBugs User Preferences -#Wed Oct 22 13:08:20 CEST 2014 +#Tue Nov 04 15:49:25 CET 2014 detector_threshold=3 effort=max excludefilter0=.fbExcludeFilterFile|true diff --git a/conf/pipe-factories.conf b/conf/pipe-factories.conf index 50f869a06cb126ddb81847cfd8cc4681f1a63195..e3d966cf8d0cab50e88237071d46309bd49b1347 100644 --- a/conf/pipe-factories.conf +++ b/conf/pipe-factories.conf @@ -1,4 +1,4 @@ teetime.framework.pipe.SingleElementPipeFactory teetime.framework.pipe.OrderedGrowableArrayPipeFactory teetime.framework.pipe.UnorderedGrowablePipeFactory -teetime.framework.pipe.SpScPipeFactory +teetime.framework.pipe.SpScPipeFactory \ No newline at end of file diff --git a/pom.xml b/pom.xml index 1382270b4ed4867197d749177e4d48e0cb70ecae..ebf91fd7e684c4be602f0a674a5531ecb8631f4b 100644 --- a/pom.xml +++ b/pom.xml @@ -81,11 +81,6 @@ <artifactId>hamcrest-library</artifactId> <version>1.3</version> </dependency> - <dependency> - <groupId>net.kieker-monitoring</groupId> - <artifactId>kieker</artifactId> - <version>1.10-SNAPSHOT</version> - </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> diff --git a/src/main/java/teetime/framework/FileSearcher.java b/src/main/java/teetime/framework/FileSearcher.java new file mode 100644 index 0000000000000000000000000000000000000000..5902ba89fd2b954f4106d4277ad7dec62b54577d --- /dev/null +++ b/src/main/java/teetime/framework/FileSearcher.java @@ -0,0 +1,26 @@ +package teetime.framework; + +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; + +public final class FileSearcher { + + private static final ClassLoader CLASS_LOADER = ClassLoader.getSystemClassLoader(); + + private FileSearcher() { + // utility class + } + + public static List<URL> loadResources(final String name) throws IOException { + final List<URL> list = new ArrayList<URL>(); + + final Enumeration<URL> systemRes = CLASS_LOADER.getResources(name); + while (systemRes.hasMoreElements()) { // NOPMD + list.add(systemRes.nextElement()); // NOPMD + } + return list; + } +} diff --git a/src/main/java/teetime/framework/HeadPipeline.java b/src/main/java/teetime/framework/HeadPipeline.java deleted file mode 100644 index 293700a045013be308290e984687897a35a0d03f..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/framework/HeadPipeline.java +++ /dev/null @@ -1,18 +0,0 @@ -package teetime.framework; - -public class HeadPipeline<FirstStage extends HeadStage, LastStage extends Stage> extends OldPipeline<FirstStage, LastStage> implements HeadStage { - - public HeadPipeline() {} - - public HeadPipeline(final String name) {} - - @Override - public boolean shouldBeTerminated() { - return this.firstStage.shouldBeTerminated(); - } - - @Override - public void terminate() { - this.firstStage.terminate(); - } -} diff --git a/src/main/java/teetime/framework/pipe/PipeFactoryLoader.java b/src/main/java/teetime/framework/pipe/PipeFactoryLoader.java index 365918f0421275421c294533d8d99832e89b3fc2..2e129e2f2fa760b93111452a73848da0f33a697b 100644 --- a/src/main/java/teetime/framework/pipe/PipeFactoryLoader.java +++ b/src/main/java/teetime/framework/pipe/PipeFactoryLoader.java @@ -1,14 +1,19 @@ package teetime.framework.pipe; import java.io.BufferedReader; -import java.io.FileReader; import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import teetime.framework.FileSearcher; + public class PipeFactoryLoader { private static final Logger LOGGER = LoggerFactory.getLogger(PipeFactoryLoader.class); @@ -17,10 +22,10 @@ public class PipeFactoryLoader { // utility class } - public static List<IPipeFactory> loadFromFile(final String fileName) throws IOException { + public static List<IPipeFactory> loadFromStream(final InputStream stream) throws IOException { List<IPipeFactory> pipeFactories = new LinkedList<IPipeFactory>(); - BufferedReader bufferedReader = new BufferedReader(new FileReader(fileName)); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(stream)); try { String line; while (null != (line = bufferedReader.readLine())) { @@ -46,4 +51,31 @@ public class PipeFactoryLoader { return pipeFactories; } + + public static List<IPipeFactory> loadPipeFactoriesFromClasspath(final String configFileName) { + + List<URL> files = null; + + try { + files = FileSearcher.loadResources(configFileName); + } catch (IOException e) { + throw new IllegalStateException(e); + } + return mergeFiles(files); + } + + public static List<IPipeFactory> mergeFiles(final List<URL> files) { + ArrayList<IPipeFactory> list = new ArrayList<IPipeFactory>(); + for (URL url : files) { + try { + InputStream is = url.openStream(); + list.addAll(loadFromStream(is)); + is.close(); + } catch (IOException e) { + throw new IllegalStateException(e); + } + + } + return list; + } } diff --git a/src/main/java/teetime/framework/pipe/PipeFactoryRegistry.java b/src/main/java/teetime/framework/pipe/PipeFactoryRegistry.java index 44c209205e7a49b025ca61bb7a484dcc073c13a6..bd91f95548782164bd9ce2750a2a4b680d4b2068 100644 --- a/src/main/java/teetime/framework/pipe/PipeFactoryRegistry.java +++ b/src/main/java/teetime/framework/pipe/PipeFactoryRegistry.java @@ -1,6 +1,5 @@ package teetime.framework.pipe; -import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -15,7 +14,7 @@ import org.slf4j.LoggerFactory; * To get a PipeFactory instance, call {@link #getPipeFactory(ThreadCommunication, PipeOrdering, boolean)}. * */ -public class PipeFactoryRegistry { +public final class PipeFactoryRegistry { private static final Logger LOGGER = LoggerFactory.getLogger(PipeFactoryRegistry.class); @@ -46,16 +45,12 @@ public class PipeFactoryRegistry { /** * The singleton instance of PipeFactoryRegistry */ - public static PipeFactoryRegistry INSTANCE = new PipeFactoryRegistry(); + public static PipeFactoryRegistry INSTANCE = new PipeFactoryRegistry("pipe-factories.conf"); - private PipeFactoryRegistry() { - try { - List<IPipeFactory> pipeFactories = PipeFactoryLoader.loadFromFile("conf/pipe-factories.conf"); - for (IPipeFactory pipeFactory : pipeFactories) { - this.register(pipeFactory); - } - } catch (IOException e) { - LOGGER.warn("Could not load pipe factories from file", e); + private PipeFactoryRegistry(final String configFileName) { + List<IPipeFactory> pipeFactories = PipeFactoryLoader.loadPipeFactoriesFromClasspath(configFileName); + for (IPipeFactory pipeFactory : pipeFactories) { + this.register(pipeFactory); } } diff --git a/src/main/java/teetime/stage/io/ByteArrayFileWriter.java b/src/main/java/teetime/stage/io/ByteArrayFileWriter.java index 3df492b430963d2258bb98cfb5173f5e52a625c2..5af9644c7690f481323ff8e68ad637bc947b0061 100644 --- a/src/main/java/teetime/stage/io/ByteArrayFileWriter.java +++ b/src/main/java/teetime/stage/io/ByteArrayFileWriter.java @@ -11,25 +11,34 @@ import com.google.common.io.Files; public class ByteArrayFileWriter extends ConsumerStage<byte[]> { private final File file; + private FileOutputStream fo; public ByteArrayFileWriter(final File file) { this.file = file; try { Files.touch(file); + fo = new FileOutputStream(this.file); } catch (IOException e) { - e.printStackTrace(); + throw new IllegalStateException(e); } } @Override protected void execute(final byte[] element) { - FileOutputStream fo; + try { - fo = new FileOutputStream(this.file); fo.write(element); - fo.close(); } catch (Exception e) { throw new IllegalStateException(e); } } + + @Override + public void onTerminating() { + try { + fo.close(); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } } diff --git a/src/main/java/teetime/util/ArrayWrapper.java b/src/main/java/teetime/util/ArrayWrapper.java index 96e17fb56c51fe01b1b4a172d29a25ec59beab77..d3f84db4507efb8233d4812e5fde2a55a14e1d12 100644 --- a/src/main/java/teetime/util/ArrayWrapper.java +++ b/src/main/java/teetime/util/ArrayWrapper.java @@ -12,15 +12,15 @@ public final class ArrayWrapper<T> { this.elements = (T[]) new Object[initialCapacity]; } - public final T get(final int index) { + public T get(final int index) { return this.elements[index]; } - public final void put(final int index, final T element) { + public void put(final int index, final T element) { this.elements[index] = element; } - public final int getCapacity() { + public int getCapacity() { return this.elements.length; } diff --git a/src/main/java/teetime/util/classpath/CachedClassForNameResolver.java b/src/main/java/teetime/util/classpath/CachedClassForNameResolver.java new file mode 100644 index 0000000000000000000000000000000000000000..5989981fa45ec1ef784c0f0b5ceae9abbd357f69 --- /dev/null +++ b/src/main/java/teetime/util/classpath/CachedClassForNameResolver.java @@ -0,0 +1,59 @@ +/*************************************************************************** + * Copyright 2014 Kieker Project (http://kieker-monitoring.net) + * + * 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 teetime.util.classpath; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * @param <T> + * the type that is used to cast a type that was found in the class path + * + * @author Christian Wulf + * @since 1.11 + */ +public class CachedClassForNameResolver<T> { + + private final ConcurrentMap<String, Class<? extends T>> cachedClasses = new ConcurrentHashMap<String, Class<? extends T>>(); // NOCS + private final ClassForNameResolver<T> classForNameResolver; + + public CachedClassForNameResolver(final ClassForNameResolver<T> classForNameResolver) { + this.classForNameResolver = classForNameResolver; + } + + /** + * This method tries to find a class with the given name. + * + * @param classname + * The name of the class. + * + * @return A {@link Class} instance corresponding to the given name, if it exists. + * + * @throws ClassNotFoundException + */ + public final Class<? extends T> classForName(final String classname) throws ClassNotFoundException { + Class<? extends T> clazz = this.cachedClasses.get(classname); + if (clazz == null) { + clazz = this.classForNameResolver.classForName(classname); + final Class<? extends T> previousClass = this.cachedClasses.putIfAbsent(classname, clazz); + if (null != previousClass) { + clazz = previousClass; + } + } + return clazz; + } +} diff --git a/src/main/java/teetime/util/classpath/ClassForNameResolver.java b/src/main/java/teetime/util/classpath/ClassForNameResolver.java new file mode 100644 index 0000000000000000000000000000000000000000..86c340e2a97406e94a6e1bf5ecd7032415018217 --- /dev/null +++ b/src/main/java/teetime/util/classpath/ClassForNameResolver.java @@ -0,0 +1,48 @@ +/*************************************************************************** + * Copyright 2014 Kieker Project (http://kieker-monitoring.net) + * + * 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 teetime.util.classpath; + +/** + * @param <T> + * the type that is used to cast a type that was found in the class path + * + * @author Christian Wulf + * @since 1.11 + */ +public class ClassForNameResolver<T> { + + private final Class<T> classToCast; + + public ClassForNameResolver(final Class<T> classToCast) { + this.classToCast = classToCast; + } + + /** + * This method tries to find a class with the given name. + * + * @param classname + * The name of the class. + * + * @return A {@link Class} instance corresponding to the given name, if it exists. + * @throws ClassNotFoundException + * + */ + public final Class<? extends T> classForName(final String classname) throws ClassNotFoundException { + final Class<?> clazz = Class.forName(classname); + return clazz.asSubclass(this.classToCast); + } +} diff --git a/src/performancetest/java/teetime/examples/experiment09/MethodCallThroughputAnalysis9.java b/src/performancetest/java/teetime/examples/experiment09/MethodCallThroughputAnalysis9.java index cd600de665c628cf1a4f7915d288173ff6c2780c..882af15ee9f929163877da0ce189d88c7bb99c95 100644 --- a/src/performancetest/java/teetime/examples/experiment09/MethodCallThroughputAnalysis9.java +++ b/src/performancetest/java/teetime/examples/experiment09/MethodCallThroughputAnalysis9.java @@ -17,7 +17,7 @@ package teetime.examples.experiment09; import java.util.List; -import teetime.framework.HeadPipeline; +import teetime.framework.OldHeadPipeline; import teetime.framework.HeadStage; import teetime.framework.RunnableStage; import teetime.framework.pipe.CommittablePipe; @@ -52,7 +52,7 @@ public class MethodCallThroughputAnalysis9 { * @return * @since 1.10 */ - private HeadPipeline<ObjectProducer<TimestampObject>, CollectorSink<TimestampObject>> buildPipeline() { + private OldHeadPipeline<ObjectProducer<TimestampObject>, CollectorSink<TimestampObject>> buildPipeline() { @SuppressWarnings("unchecked") final NoopFilter<TimestampObject>[] noopFilters = new NoopFilter[this.numNoopFilters]; // create stages @@ -64,7 +64,7 @@ public class MethodCallThroughputAnalysis9 { final StopTimestampFilter stopTimestampFilter = new StopTimestampFilter(); final CollectorSink<TimestampObject> collectorSink = new CollectorSink<TimestampObject>(this.timestampObjects); - final HeadPipeline<ObjectProducer<TimestampObject>, CollectorSink<TimestampObject>> pipeline = new HeadPipeline<ObjectProducer<TimestampObject>, CollectorSink<TimestampObject>>(); + final OldHeadPipeline<ObjectProducer<TimestampObject>, CollectorSink<TimestampObject>> pipeline = new OldHeadPipeline<ObjectProducer<TimestampObject>, CollectorSink<TimestampObject>>(); pipeline.setFirstStage(objectProducer); pipeline.setLastStage(collectorSink); diff --git a/src/performancetest/java/teetime/examples/experiment10/MethodCallThroughputAnalysis10.java b/src/performancetest/java/teetime/examples/experiment10/MethodCallThroughputAnalysis10.java index 82a31ff2bcdb706b0b67aec457fee9b82880636b..6fac51591452feca40044f9f7ca6d77b5023b8b7 100644 --- a/src/performancetest/java/teetime/examples/experiment10/MethodCallThroughputAnalysis10.java +++ b/src/performancetest/java/teetime/examples/experiment10/MethodCallThroughputAnalysis10.java @@ -17,7 +17,7 @@ package teetime.examples.experiment10; import java.util.List; -import teetime.framework.HeadPipeline; +import teetime.framework.OldHeadPipeline; import teetime.framework.RunnableStage; import teetime.framework.pipe.SingleElementPipe; import teetime.stage.CollectorSink; @@ -61,7 +61,7 @@ public class MethodCallThroughputAnalysis10 { final StopTimestampFilter stopTimestampFilter = new StopTimestampFilter(); final CollectorSink<TimestampObject> collectorSink = new CollectorSink<TimestampObject>(this.timestampObjects); - final HeadPipeline<ObjectProducer<TimestampObject>, CollectorSink<TimestampObject>> pipeline = new HeadPipeline<ObjectProducer<TimestampObject>, CollectorSink<TimestampObject>>(); + final OldHeadPipeline<ObjectProducer<TimestampObject>, CollectorSink<TimestampObject>> pipeline = new OldHeadPipeline<ObjectProducer<TimestampObject>, CollectorSink<TimestampObject>>(); pipeline.setFirstStage(objectProducer); pipeline.setLastStage(collectorSink); diff --git a/src/performancetest/java/teetime/examples/experiment11/MethodCallThroughputAnalysis11.java b/src/performancetest/java/teetime/examples/experiment11/MethodCallThroughputAnalysis11.java index 07b681ab9d9dd7bee6ce09a3eb9f045d880eb5fd..e24c7d487f0c37e794583a33dcad8338f9ee1d12 100644 --- a/src/performancetest/java/teetime/examples/experiment11/MethodCallThroughputAnalysis11.java +++ b/src/performancetest/java/teetime/examples/experiment11/MethodCallThroughputAnalysis11.java @@ -17,7 +17,7 @@ package teetime.examples.experiment11; import java.util.List; -import teetime.framework.HeadPipeline; +import teetime.framework.OldHeadPipeline; import teetime.framework.HeadStage; import teetime.framework.RunnableStage; import teetime.framework.pipe.UnorderedGrowablePipe; @@ -47,7 +47,7 @@ public class MethodCallThroughputAnalysis11 { this.runnable = new RunnableStage(pipeline); } - private HeadPipeline<ObjectProducer<TimestampObject>, CollectorSink<TimestampObject>> buildPipeline(final long numInputObjects, + private OldHeadPipeline<ObjectProducer<TimestampObject>, CollectorSink<TimestampObject>> buildPipeline(final long numInputObjects, final ConstructorClosure<TimestampObject> inputObjectCreator) { @SuppressWarnings("unchecked") final NoopFilter<TimestampObject>[] noopFilters = new NoopFilter[this.numNoopFilters]; @@ -62,7 +62,7 @@ public class MethodCallThroughputAnalysis11 { final StopTimestampFilter stopTimestampFilter = new StopTimestampFilter(); final CollectorSink<TimestampObject> collectorSink = new CollectorSink<TimestampObject>(this.timestampObjects); - final HeadPipeline<ObjectProducer<TimestampObject>, CollectorSink<TimestampObject>> pipeline = new HeadPipeline<ObjectProducer<TimestampObject>, CollectorSink<TimestampObject>>(); + final OldHeadPipeline<ObjectProducer<TimestampObject>, CollectorSink<TimestampObject>> pipeline = new OldHeadPipeline<ObjectProducer<TimestampObject>, CollectorSink<TimestampObject>>(); pipeline.setFirstStage(objectProducer); pipeline.setLastStage(collectorSink); diff --git a/src/performancetest/java/teetime/examples/experiment14/MethodCallThroughputAnalysis14.java b/src/performancetest/java/teetime/examples/experiment14/MethodCallThroughputAnalysis14.java index e229ebc555801dfd1a1b3cf1f5ea1c93863351b0..01de043b0a339896b44c16264095174723711afa 100644 --- a/src/performancetest/java/teetime/examples/experiment14/MethodCallThroughputAnalysis14.java +++ b/src/performancetest/java/teetime/examples/experiment14/MethodCallThroughputAnalysis14.java @@ -17,7 +17,7 @@ package teetime.examples.experiment14; import java.util.List; -import teetime.framework.HeadPipeline; +import teetime.framework.OldHeadPipeline; import teetime.framework.HeadStage; import teetime.framework.RunnableStage; import teetime.framework.pipe.IPipeFactory; @@ -56,7 +56,7 @@ public class MethodCallThroughputAnalysis14 { * @return * @since 1.10 */ - private HeadPipeline<ObjectProducer<TimestampObject>, CollectorSink<TimestampObject>> buildPipeline() { + private OldHeadPipeline<ObjectProducer<TimestampObject>, CollectorSink<TimestampObject>> buildPipeline() { @SuppressWarnings("unchecked") final NoopFilter<TimestampObject>[] noopFilters = new NoopFilter[this.numNoopFilters]; // create stages @@ -68,7 +68,7 @@ public class MethodCallThroughputAnalysis14 { final StopTimestampFilter stopTimestampFilter = new StopTimestampFilter(); final CollectorSink<TimestampObject> collectorSink = new CollectorSink<TimestampObject>(this.timestampObjects); - final HeadPipeline<ObjectProducer<TimestampObject>, CollectorSink<TimestampObject>> pipeline = new HeadPipeline<ObjectProducer<TimestampObject>, CollectorSink<TimestampObject>>(); + final OldHeadPipeline<ObjectProducer<TimestampObject>, CollectorSink<TimestampObject>> pipeline = new OldHeadPipeline<ObjectProducer<TimestampObject>, CollectorSink<TimestampObject>>(); pipeline.setFirstStage(objectProducer); pipeline.setLastStage(collectorSink); diff --git a/src/performancetest/java/teetime/examples/experiment15/MethodCallThroughputAnalysis15.java b/src/performancetest/java/teetime/examples/experiment15/MethodCallThroughputAnalysis15.java index 6850f50cabddee7841602aa3179097f4ebced016..6b92bec5038741b7f4356ae676f6d6c187e0ad37 100644 --- a/src/performancetest/java/teetime/examples/experiment15/MethodCallThroughputAnalysis15.java +++ b/src/performancetest/java/teetime/examples/experiment15/MethodCallThroughputAnalysis15.java @@ -17,7 +17,7 @@ package teetime.examples.experiment15; import java.util.List; -import teetime.framework.HeadPipeline; +import teetime.framework.OldHeadPipeline; import teetime.framework.HeadStage; import teetime.framework.RunnableStage; import teetime.framework.pipe.OrderedGrowableArrayPipe; @@ -55,20 +55,20 @@ public class MethodCallThroughputAnalysis15 { public void init() { - HeadPipeline<Clock, Sink<Long>> clockPipeline = this.buildClockPipeline(); + OldHeadPipeline<Clock, Sink<Long>> clockPipeline = this.buildClockPipeline(); this.clockRunnable = new RunnableStage(clockPipeline); HeadStage pipeline = this.buildPipeline(this.clock); this.runnable = new RunnableStage(pipeline); } - private HeadPipeline<Clock, Sink<Long>> buildClockPipeline() { + private OldHeadPipeline<Clock, Sink<Long>> buildClockPipeline() { this.clock = new Clock(); this.clock.setInitialDelayInMs(100); this.clock.setIntervalDelayInMs(100); - final HeadPipeline<Clock, Sink<Long>> pipeline = new HeadPipeline<Clock, Sink<Long>>(); + final OldHeadPipeline<Clock, Sink<Long>> pipeline = new OldHeadPipeline<Clock, Sink<Long>>(); pipeline.setFirstStage(this.clock); pipeline.setLastStage(new Sink<Long>()); @@ -80,7 +80,7 @@ public class MethodCallThroughputAnalysis15 { * @return * @since 1.10 */ - private HeadPipeline<ObjectProducer<TimestampObject>, CollectorSink<TimestampObject>> buildPipeline(final Clock clock) { + private OldHeadPipeline<ObjectProducer<TimestampObject>, CollectorSink<TimestampObject>> buildPipeline(final Clock clock) { @SuppressWarnings("unchecked") final NoopFilter<TimestampObject>[] noopFilters = new NoopFilter[this.numNoopFilters]; // create stages @@ -93,7 +93,7 @@ public class MethodCallThroughputAnalysis15 { final StopTimestampFilter stopTimestampFilter = new StopTimestampFilter(); final CollectorSink<TimestampObject> collectorSink = new CollectorSink<TimestampObject>(this.timestampObjects); - final HeadPipeline<ObjectProducer<TimestampObject>, CollectorSink<TimestampObject>> pipeline = new HeadPipeline<ObjectProducer<TimestampObject>, CollectorSink<TimestampObject>>(); + final OldHeadPipeline<ObjectProducer<TimestampObject>, CollectorSink<TimestampObject>> pipeline = new OldHeadPipeline<ObjectProducer<TimestampObject>, CollectorSink<TimestampObject>>(); pipeline.setFirstStage(objectProducer); pipeline.setLastStage(collectorSink); diff --git a/src/performancetest/java/teetime/examples/experiment16/MethodCallThroughputAnalysis16.java b/src/performancetest/java/teetime/examples/experiment16/MethodCallThroughputAnalysis16.java index c84c2bad7ded7a93e6fbfe3449afe0e922966751..b48c2378c5a20ad410dd6975e8737f8f7d3697d5 100644 --- a/src/performancetest/java/teetime/examples/experiment16/MethodCallThroughputAnalysis16.java +++ b/src/performancetest/java/teetime/examples/experiment16/MethodCallThroughputAnalysis16.java @@ -19,7 +19,7 @@ import java.util.ArrayList; import java.util.LinkedList; import java.util.List; -import teetime.framework.HeadPipeline; +import teetime.framework.OldHeadPipeline; import teetime.framework.RunnableStage; import teetime.framework.pipe.SingleElementPipe; import teetime.framework.pipe.SpScPipe; @@ -56,7 +56,7 @@ public class MethodCallThroughputAnalysis16 { private int numWorkerThreads; public void init() { - HeadPipeline<ObjectProducer<TimestampObject>, Distributor<TimestampObject>> producerPipeline = this.buildProducerPipeline(this.numInputObjects, + OldHeadPipeline<ObjectProducer<TimestampObject>, Distributor<TimestampObject>> producerPipeline = this.buildProducerPipeline(this.numInputObjects, this.inputObjectCreator); this.producerThread = new Thread(new RunnableStage(producerPipeline)); @@ -67,17 +67,17 @@ public class MethodCallThroughputAnalysis16 { List<TimestampObject> resultList = new ArrayList<TimestampObject>(this.numInputObjects); this.timestampObjectsList.add(resultList); - HeadPipeline<Relay<TimestampObject>, CollectorSink<TimestampObject>> workerPipeline = this.buildPipeline(producerPipeline, resultList); + OldHeadPipeline<Relay<TimestampObject>, CollectorSink<TimestampObject>> workerPipeline = this.buildPipeline(producerPipeline, resultList); this.workerThreads[i] = new Thread(new RunnableStage(workerPipeline)); } } - private HeadPipeline<ObjectProducer<TimestampObject>, Distributor<TimestampObject>> buildProducerPipeline(final int numInputObjects, + private OldHeadPipeline<ObjectProducer<TimestampObject>, Distributor<TimestampObject>> buildProducerPipeline(final int numInputObjects, final ConstructorClosure<TimestampObject> inputObjectCreator) { final ObjectProducer<TimestampObject> objectProducer = new ObjectProducer<TimestampObject>(numInputObjects, inputObjectCreator); Distributor<TimestampObject> distributor = new Distributor<TimestampObject>(); - final HeadPipeline<ObjectProducer<TimestampObject>, Distributor<TimestampObject>> pipeline = new HeadPipeline<ObjectProducer<TimestampObject>, Distributor<TimestampObject>>(); + final OldHeadPipeline<ObjectProducer<TimestampObject>, Distributor<TimestampObject>> pipeline = new OldHeadPipeline<ObjectProducer<TimestampObject>, Distributor<TimestampObject>>(); pipeline.setFirstStage(objectProducer); pipeline.setLastStage(distributor); @@ -90,8 +90,8 @@ public class MethodCallThroughputAnalysis16 { * @param numNoopFilters * @since 1.10 */ - private HeadPipeline<Relay<TimestampObject>, CollectorSink<TimestampObject>> buildPipeline( - final HeadPipeline<ObjectProducer<TimestampObject>, Distributor<TimestampObject>> previousStage, + private OldHeadPipeline<Relay<TimestampObject>, CollectorSink<TimestampObject>> buildPipeline( + final OldHeadPipeline<ObjectProducer<TimestampObject>, Distributor<TimestampObject>> previousStage, final List<TimestampObject> timestampObjects) { Relay<TimestampObject> relay = new Relay<TimestampObject>(); @SuppressWarnings("unchecked") @@ -104,7 +104,7 @@ public class MethodCallThroughputAnalysis16 { final StopTimestampFilter stopTimestampFilter = new StopTimestampFilter(); final CollectorSink<TimestampObject> collectorSink = new CollectorSink<TimestampObject>(timestampObjects); - final HeadPipeline<Relay<TimestampObject>, CollectorSink<TimestampObject>> pipeline = new HeadPipeline<Relay<TimestampObject>, CollectorSink<TimestampObject>>(); + final OldHeadPipeline<Relay<TimestampObject>, CollectorSink<TimestampObject>> pipeline = new OldHeadPipeline<Relay<TimestampObject>, CollectorSink<TimestampObject>>(); pipeline.setFirstStage(relay); pipeline.setLastStage(collectorSink); diff --git a/src/performancetest/java/teetime/examples/experiment17/MethodCallThroughputAnalysis17.java b/src/performancetest/java/teetime/examples/experiment17/MethodCallThroughputAnalysis17.java index 62345de3f6f43209dc3f5cb5f16eccb87dfdaf65..3496e46c608438f44abdd369a4e5496d9a51d7c4 100644 --- a/src/performancetest/java/teetime/examples/experiment17/MethodCallThroughputAnalysis17.java +++ b/src/performancetest/java/teetime/examples/experiment17/MethodCallThroughputAnalysis17.java @@ -19,7 +19,7 @@ import java.util.ArrayList; import java.util.LinkedList; import java.util.List; -import teetime.framework.HeadPipeline; +import teetime.framework.OldHeadPipeline; import teetime.framework.RunnableStage; import teetime.framework.Stage; import teetime.framework.pipe.DummyPipe; @@ -60,7 +60,7 @@ public class MethodCallThroughputAnalysis17 { private Thread[] workerThreads; public void init() { - HeadPipeline<ObjectProducer<TimestampObject>, Distributor<TimestampObject>> producerPipeline = this.buildProducerPipeline(this.numInputObjects, + OldHeadPipeline<ObjectProducer<TimestampObject>, Distributor<TimestampObject>> producerPipeline = this.buildProducerPipeline(this.numInputObjects, this.inputObjectCreator); this.producerThread = new Thread(new RunnableStage(producerPipeline)); @@ -71,7 +71,7 @@ public class MethodCallThroughputAnalysis17 { List<TimestampObject> resultList = new ArrayList<TimestampObject>(this.numInputObjects); this.timestampObjectsList.add(resultList); - HeadPipeline<?, ?> pipeline = this.buildPipeline(null, resultList); + OldHeadPipeline<?, ?> pipeline = this.buildPipeline(null, resultList); this.workerThreads[i] = new Thread(new RunnableStage(pipeline)); } @@ -108,7 +108,7 @@ public class MethodCallThroughputAnalysis17 { } @SuppressWarnings("unchecked") - private HeadPipeline<ObjectProducer<TimestampObject>, Distributor<TimestampObject>> buildProducerPipeline(final int numInputObjects, + private OldHeadPipeline<ObjectProducer<TimestampObject>, Distributor<TimestampObject>> buildProducerPipeline(final int numInputObjects, final ConstructorClosure<TimestampObject> inputObjectCreator) { final ObjectProducer<TimestampObject> objectProducer = new ObjectProducer<TimestampObject>(numInputObjects, inputObjectCreator); Distributor<TimestampObject> distributor = new Distributor<TimestampObject>(); @@ -119,7 +119,7 @@ public class MethodCallThroughputAnalysis17 { UnorderedGrowablePipe.connect(objectProducer.getOutputPort(), distributor.getInputPort()); distributor.getNewOutputPort().setPipe(new DummyPipe()); - final HeadPipeline<ObjectProducer<TimestampObject>, Distributor<TimestampObject>> pipeline = new HeadPipeline<ObjectProducer<TimestampObject>, Distributor<TimestampObject>>(); + final OldHeadPipeline<ObjectProducer<TimestampObject>, Distributor<TimestampObject>> pipeline = new OldHeadPipeline<ObjectProducer<TimestampObject>, Distributor<TimestampObject>>(); pipeline.setFirstStage(objectProducer); // pipeline.setFirstStage(sink); // pipeline.setFirstStage(endStage); @@ -133,7 +133,7 @@ public class MethodCallThroughputAnalysis17 { * @param numNoopFilters * @since 1.10 */ - private HeadPipeline<Relay<TimestampObject>, CollectorSink<TimestampObject>> buildPipeline(final Stage previousStage, + private OldHeadPipeline<Relay<TimestampObject>, CollectorSink<TimestampObject>> buildPipeline(final Stage previousStage, final List<TimestampObject> timestampObjects) { // create stages Relay<TimestampObject> relay = new Relay<TimestampObject>(); @@ -158,7 +158,7 @@ public class MethodCallThroughputAnalysis17 { UnorderedGrowablePipe.connect(noopFilters[noopFilters.length - 1].getOutputPort(), stopTimestampFilter.getInputPort()); UnorderedGrowablePipe.connect(stopTimestampFilter.getOutputPort(), collectorSink.getInputPort()); - final HeadPipeline<Relay<TimestampObject>, CollectorSink<TimestampObject>> pipeline = new HeadPipeline<Relay<TimestampObject>, CollectorSink<TimestampObject>>(); + final OldHeadPipeline<Relay<TimestampObject>, CollectorSink<TimestampObject>> pipeline = new OldHeadPipeline<Relay<TimestampObject>, CollectorSink<TimestampObject>>(); pipeline.setFirstStage(relay); pipeline.setLastStage(collectorSink); return pipeline; diff --git a/src/performancetest/java/teetime/examples/experiment19/MethodCallThroughputAnalysis19.java b/src/performancetest/java/teetime/examples/experiment19/MethodCallThroughputAnalysis19.java index b91a703bc3f61df66be2ccb72a2f174c34b9b7a9..f38312f5d2c1e3a69a68eb6325057db434fea19a 100644 --- a/src/performancetest/java/teetime/examples/experiment19/MethodCallThroughputAnalysis19.java +++ b/src/performancetest/java/teetime/examples/experiment19/MethodCallThroughputAnalysis19.java @@ -19,7 +19,7 @@ import java.util.ArrayList; import java.util.LinkedList; import java.util.List; -import teetime.framework.HeadPipeline; +import teetime.framework.OldHeadPipeline; import teetime.framework.RunnableStage; import teetime.framework.pipe.OrderedGrowableArrayPipe; import teetime.framework.pipe.SpScPipe; @@ -56,7 +56,7 @@ public class MethodCallThroughputAnalysis19 { private int numWorkerThreads; public void init() { - HeadPipeline<ObjectProducer<TimestampObject>, Distributor<TimestampObject>> producerPipeline = this.buildProducerPipeline(this.numInputObjects, + OldHeadPipeline<ObjectProducer<TimestampObject>, Distributor<TimestampObject>> producerPipeline = this.buildProducerPipeline(this.numInputObjects, this.inputObjectCreator); this.producerThread = new Thread(new RunnableStage(producerPipeline)); @@ -67,18 +67,18 @@ public class MethodCallThroughputAnalysis19 { List<TimestampObject> resultList = new ArrayList<TimestampObject>(this.numInputObjects); this.timestampObjectsList.add(resultList); - HeadPipeline<?, ?> pipeline = this.buildPipeline(producerPipeline.getLastStage(), resultList); + OldHeadPipeline<?, ?> pipeline = this.buildPipeline(producerPipeline.getLastStage(), resultList); this.workerThreads[i] = new Thread(new RunnableStage(pipeline)); } } - private HeadPipeline<ObjectProducer<TimestampObject>, Distributor<TimestampObject>> buildProducerPipeline(final int numInputObjects, + private OldHeadPipeline<ObjectProducer<TimestampObject>, Distributor<TimestampObject>> buildProducerPipeline(final int numInputObjects, final ConstructorClosure<TimestampObject> inputObjectCreator) { final ObjectProducer<TimestampObject> objectProducer = new ObjectProducer<TimestampObject>(numInputObjects, inputObjectCreator); Distributor<TimestampObject> distributor = new Distributor<TimestampObject>(); - final HeadPipeline<ObjectProducer<TimestampObject>, Distributor<TimestampObject>> pipeline = new HeadPipeline<ObjectProducer<TimestampObject>, Distributor<TimestampObject>>(); + final OldHeadPipeline<ObjectProducer<TimestampObject>, Distributor<TimestampObject>> pipeline = new OldHeadPipeline<ObjectProducer<TimestampObject>, Distributor<TimestampObject>>(); pipeline.setFirstStage(objectProducer); pipeline.setLastStage(distributor); @@ -87,7 +87,7 @@ public class MethodCallThroughputAnalysis19 { return pipeline; } - private HeadPipeline<?, ?> buildPipeline(final Distributor<TimestampObject> previousStage, final List<TimestampObject> timestampObjects) { + private OldHeadPipeline<?, ?> buildPipeline(final Distributor<TimestampObject> previousStage, final List<TimestampObject> timestampObjects) { Relay<TimestampObject> relay = new Relay<TimestampObject>(); @SuppressWarnings("unchecked") final NoopFilter<TimestampObject>[] noopFilters = new NoopFilter[this.numNoopFilters]; @@ -99,7 +99,7 @@ public class MethodCallThroughputAnalysis19 { final StopTimestampFilter stopTimestampFilter = new StopTimestampFilter(); final CollectorSink<TimestampObject> collectorSink = new CollectorSink<TimestampObject>(timestampObjects); - final HeadPipeline<Relay<TimestampObject>, CollectorSink<TimestampObject>> pipeline = new HeadPipeline<Relay<TimestampObject>, CollectorSink<TimestampObject>>(); + final OldHeadPipeline<Relay<TimestampObject>, CollectorSink<TimestampObject>> pipeline = new OldHeadPipeline<Relay<TimestampObject>, CollectorSink<TimestampObject>>(); pipeline.setFirstStage(relay); pipeline.setLastStage(collectorSink); diff --git a/src/performancetest/java/teetime/framework/OldHeadPipeline.java b/src/performancetest/java/teetime/framework/OldHeadPipeline.java new file mode 100644 index 0000000000000000000000000000000000000000..d3dd64147f40dc4a77f07ba5008aa1b542a35dfd --- /dev/null +++ b/src/performancetest/java/teetime/framework/OldHeadPipeline.java @@ -0,0 +1,19 @@ +package teetime.framework; + +@Deprecated +public class OldHeadPipeline<FirstStage extends HeadStage, LastStage extends Stage> extends OldPipeline<FirstStage, LastStage> implements HeadStage { + + public OldHeadPipeline() {} + + public OldHeadPipeline(final String name) {} + + @Override + public boolean shouldBeTerminated() { + return this.firstStage.shouldBeTerminated(); + } + + @Override + public void terminate() { + this.firstStage.terminate(); + } +} diff --git a/src/main/java/teetime/framework/OldPipeline.java b/src/performancetest/java/teetime/framework/OldPipeline.java similarity index 99% rename from src/main/java/teetime/framework/OldPipeline.java rename to src/performancetest/java/teetime/framework/OldPipeline.java index 77b70577e9c3ec38d49747253d5ead7c22722ec8..11ff018d9957535db87d6ac2d45ce099ab074b81 100644 --- a/src/main/java/teetime/framework/OldPipeline.java +++ b/src/performancetest/java/teetime/framework/OldPipeline.java @@ -5,6 +5,7 @@ import java.util.List; import teetime.framework.signal.ISignal; import teetime.framework.validation.InvalidPortConnection; +@Deprecated public class OldPipeline<FirstStage extends Stage, LastStage extends Stage> implements Stage { protected FirstStage firstStage; diff --git a/src/performancetest/java/teetime/util/concurrent/workstealing/alternative/ExceptionalCircularWorkStealingDequeTest.java b/src/performancetest/java/teetime/util/concurrent/workstealing/alternative/ExceptionalCircularWorkStealingDequeTest.java index 21858b035af37dc26059cb6b4eb4d44d868aafa3..679ab97612b270f9d5d380434eaa69c1fd96eb06 100644 --- a/src/performancetest/java/teetime/util/concurrent/workstealing/alternative/ExceptionalCircularWorkStealingDequeTest.java +++ b/src/performancetest/java/teetime/util/concurrent/workstealing/alternative/ExceptionalCircularWorkStealingDequeTest.java @@ -30,6 +30,7 @@ public class ExceptionalCircularWorkStealingDequeTest { deque.popBottom(); } catch (final DequeIsEmptyException e) { // do not handle; we just want to compare the performance of throwing a preallocated exception vs. returning special values + throw new IllegalStateException(e); } } this.stopWatch.end(); diff --git a/src/test/java/teetime/framework/FileSearcherTest.java b/src/test/java/teetime/framework/FileSearcherTest.java new file mode 100644 index 0000000000000000000000000000000000000000..69e43e9b7ff6068b3174e605eb01b386504d2051 --- /dev/null +++ b/src/test/java/teetime/framework/FileSearcherTest.java @@ -0,0 +1,30 @@ +package teetime.framework; + +import java.io.IOException; +import java.net.URL; +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; + +public class FileSearcherTest { + + @Test + public void fileInClasspath() throws IOException { + List<URL> list = FileSearcher.loadResources("pipe-factories.conf"); + Assert.assertEquals(false, list.isEmpty());// NOPMD + } + + @Test + public void multipleFiles() throws IOException { + List<URL> list = FileSearcher.loadResources("LICENSE.txt"); + Assert.assertEquals(true, list.size() > 1);// NOPMD + } + + @Test + public void missingFile() throws IOException { + List<URL> list = FileSearcher.loadResources("filethatdoesnotexistinanyproject.nope"); + Assert.assertEquals(true, list.isEmpty());// NOPMD + } + +} diff --git a/src/test/java/teetime/framework/pipe/DummyFactory.java b/src/test/java/teetime/framework/pipe/DummyFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..e4a40def390d22ac9bb8ff907e13b15438a220fb --- /dev/null +++ b/src/test/java/teetime/framework/pipe/DummyFactory.java @@ -0,0 +1,5 @@ +package teetime.framework.pipe; + +public class DummyFactory extends SpScPipeFactory { + +} diff --git a/src/test/java/teetime/framework/pipe/PipeFactoryLoaderTest.java b/src/test/java/teetime/framework/pipe/PipeFactoryLoaderTest.java new file mode 100644 index 0000000000000000000000000000000000000000..1c350635e85ddb0317a0aa8cb06c6dea8f335ac3 --- /dev/null +++ b/src/test/java/teetime/framework/pipe/PipeFactoryLoaderTest.java @@ -0,0 +1,72 @@ +package teetime.framework.pipe; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; + +import teetime.util.classpath.ClassForNameResolver; + +import com.google.common.base.Charsets; +import com.google.common.io.Files; + +public class PipeFactoryLoaderTest { + + @Test + public void emptyConfig() throws IOException { + List<IPipeFactory> list = PipeFactoryLoader.loadPipeFactoriesFromClasspath("data/empty-test.conf"); + Assert.assertEquals(true, list.isEmpty()); + } + + @Test + public void singleConfig() throws IOException { + List<IPipeFactory> list = PipeFactoryLoader.loadPipeFactoriesFromClasspath("pipe-factories.conf"); + int lines = Files.readLines(new File("conf/pipe-factories.conf"), Charsets.UTF_8).size(); + Assert.assertEquals(lines, list.size()); + } + + @Test + public void multipleConfigs() throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException { + List<URL> files = new ArrayList<URL>(); + File pipeConfig = new File("conf/pipe-factories.conf"); + File testConfig = new File("src/test/resources/data/normal-test.conf"); + files.add(testConfig.toURI().toURL()); + files.add(pipeConfig.toURI().toURL()); + List<IPipeFactory> pipeFactories = PipeFactoryLoader.mergeFiles(files); + + List<String> contents = Files.readLines(pipeConfig, Charsets.UTF_8); + contents.addAll(Files.readLines(testConfig, Charsets.UTF_8)); + + // Check if all read factories are contained in one of the files + for (IPipeFactory iPipeFactory : pipeFactories) { + Assert.assertTrue(contents.indexOf(iPipeFactory.getClass().getCanonicalName()) != -1); + } + + // Second part of the test: PipeFactoryRegistry + PipeFactoryRegistry pipeRegistry = PipeFactoryRegistry.INSTANCE; + ClassForNameResolver<IPipeFactory> classResolver = new ClassForNameResolver<IPipeFactory>(IPipeFactory.class); + + // Look for the "normal" pipes + for (String className : Files.readLines(pipeConfig, Charsets.UTF_8)) { + IPipeFactory pipeFactory = classResolver.classForName(className).newInstance(); + IPipeFactory returnedFactory = pipeRegistry.getPipeFactory(pipeFactory.getThreadCommunication(), pipeFactory.getOrdering(), pipeFactory.isGrowable()); + Assert.assertEquals(pipeFactory.getClass().getCanonicalName(), returnedFactory.getClass().getCanonicalName()); + } + // Second "and a half" part + for (String className : Files.readLines(testConfig, Charsets.UTF_8)) { + IPipeFactory pipeFactory = classResolver.classForName(className).newInstance(); + // Still old factory + IPipeFactory returnedFactory = pipeRegistry.getPipeFactory(pipeFactory.getThreadCommunication(), pipeFactory.getOrdering(), pipeFactory.isGrowable()); + Assert.assertNotEquals(pipeFactory.getClass().getCanonicalName(), returnedFactory.getClass().getCanonicalName()); + // Overload factory and check for the new one + pipeRegistry.register(pipeFactory); + returnedFactory = pipeRegistry.getPipeFactory(pipeFactory.getThreadCommunication(), pipeFactory.getOrdering(), pipeFactory.isGrowable()); + Assert.assertEquals(pipeFactory.getClass().getCanonicalName(), returnedFactory.getClass().getCanonicalName()); + } + } + +} diff --git a/src/test/resources/data/empty-test.conf b/src/test/resources/data/empty-test.conf new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/test/resources/data/normal-test.conf b/src/test/resources/data/normal-test.conf new file mode 100644 index 0000000000000000000000000000000000000000..6d95eb2d6c422d03c98078f8849b3c1c39886416 --- /dev/null +++ b/src/test/resources/data/normal-test.conf @@ -0,0 +1 @@ +teetime.framework.pipe.DummyFactory \ No newline at end of file