diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml deleted file mode 100644 index 578da31dee62dccaca8dd4f17da10a45723c6d9b..0000000000000000000000000000000000000000 --- a/dependency-reduced-pom.xml +++ /dev/null @@ -1,69 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<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/maven-v4_0_0.xsd"> - <modelVersion>4.0.0</modelVersion> - <groupId>net.sourceforge.teetime</groupId> - <artifactId>teetime</artifactId> - <name>teetime</name> - <version>1.0-SNAPSHOT</version> - <url>http://maven.apache.org</url> - <build> - <plugins> - <plugin> - <artifactId>maven-compiler-plugin</artifactId> - <configuration> - <source>1.6</source> - <target>1.6</target> - </configuration> - </plugin> - <plugin> - <groupId>org.codehaus.mojo</groupId> - <artifactId>versions-maven-plugin</artifactId> - <version>2.1</version> - </plugin> - <plugin> - <artifactId>maven-shade-plugin</artifactId> - <executions> - <execution> - <phase>package</phase> - <goals> - <goal>shade</goal> - </goals> - </execution> - </executions> - <configuration> - <finalName>${project.artifactId}-${project.version}</finalName> - </configuration> - </plugin> - </plugins> - </build> - <repositories> - <repository> - <id>sonatype.oss.snapshots</id> - <url>https://oss.sonatype.org/content/repositories/snapshots/</url> - </repository> - </repositories> - <dependencies> - <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - <version>4.11</version> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.hamcrest</groupId> - <artifactId>hamcrest-core</artifactId> - <version>1.3</version> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.hamcrest</groupId> - <artifactId>hamcrest-library</artifactId> - <version>1.3</version> - <scope>test</scope> - </dependency> - </dependencies> - <properties> - <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> - </properties> -</project> - diff --git a/pom.xml b/pom.xml index 4d1acb81827cc8aef564740c50a7a90f8875938f..10a5797ca03b3ddea34b45d7fefc7bf7a005d7cd 100644 --- a/pom.xml +++ b/pom.xml @@ -157,7 +157,7 @@ <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>versions-maven-plugin</artifactId> - <version>2.1</version> + <version>2.2</version> </plugin> <!-- goals to build a jar with binaries: jar:jar, jar:test-jar --> @@ -433,7 +433,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-gpg-plugin</artifactId> - <version>1.5</version> + <version>1.6</version> <executions> <execution> <id>sign-artifacts</id> diff --git a/src/main/java/teetime/framework/AbstractIntraThreadPipe.java b/src/main/java/teetime/framework/AbstractIntraThreadPipe.java index ebeccd1c4b592bf55cedd1074a0c13f9874bbbff..ccfce741b2945ac94d707b34d6a48a0eaf399f3b 100644 --- a/src/main/java/teetime/framework/AbstractIntraThreadPipe.java +++ b/src/main/java/teetime/framework/AbstractIntraThreadPipe.java @@ -31,8 +31,8 @@ public abstract class AbstractIntraThreadPipe extends AbstractPipe { } @Override + // getTargetPort is always non-null since the framework adds dummy ports if necessary public final void sendSignal(final ISignal signal) { - // getTargetPort is always non-null since the framework adds dummy ports if necessary this.cachedTargetStage.onSignal(signal, this.getTargetPort()); } diff --git a/src/main/java/teetime/framework/Analysis.java b/src/main/java/teetime/framework/Analysis.java index 578ea97408db2c5747090c348793061e4598a2f2..c65916e440d9b045128d2ac9923a9571535048d1 100644 --- a/src/main/java/teetime/framework/Analysis.java +++ b/src/main/java/teetime/framework/Analysis.java @@ -96,8 +96,8 @@ public final class Analysis<T extends AnalysisConfiguration> implements Uncaught init(); } + // BETTER validate concurrently private void validateStages() { - // BETTER validate concurrently final List<Stage> threadableStageJobs = this.configuration.getThreadableStageJobs(); for (Stage stage : threadableStageJobs) { // // portConnectionValidator.validate(stage); @@ -190,7 +190,6 @@ public final class Analysis<T extends AnalysisConfiguration> implements Uncaught * @since 1.1 */ public void waitForTermination() { - try { for (Thread thread : this.finiteProducerThreads) { thread.join(); diff --git a/src/main/java/teetime/framework/Traversor.java b/src/main/java/teetime/framework/Traversor.java index 82ac218e31b10d93a25de53ead1f845b94a333c5..39ebed6e43ec796831c79c04b300ea5286dd7c62 100644 --- a/src/main/java/teetime/framework/Traversor.java +++ b/src/main/java/teetime/framework/Traversor.java @@ -24,14 +24,14 @@ import teetime.framework.pipe.IPipe; public class Traversor { private final IPipeVisitor pipeVisitor; - private final Set<Stage> visitedStage = new HashSet<Stage>(); + private final Set<Stage> visitedStages = new HashSet<Stage>(); public Traversor(final IPipeVisitor pipeVisitor) { this.pipeVisitor = pipeVisitor; } public void traverse(final Stage stage) { - if (!visitedStage.add(stage)) { + if (!visitedStages.add(stage)) { return; } @@ -46,6 +46,6 @@ public class Traversor { } public Set<Stage> getVisitedStage() { - return visitedStage; + return visitedStages; } } diff --git a/src/main/java/teetime/framework/pipe/CommittablePipe.java b/src/main/java/teetime/framework/pipe/CommittablePipe.java deleted file mode 100644 index 09ba2627d0fefbc6ca912277d839b88066b0d6bb..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/framework/pipe/CommittablePipe.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.framework.pipe; - -import teetime.framework.AbstractIntraThreadPipe; -import teetime.framework.InputPort; -import teetime.framework.OutputPort; -import teetime.util.list.CommittableResizableArrayQueue; - -final class CommittablePipe extends AbstractIntraThreadPipe { - - private final CommittableResizableArrayQueue<Object> elements = new CommittableResizableArrayQueue<Object>(null, 4); - - <T> CommittablePipe(final OutputPort<? extends T> sourcePort, final InputPort<T> targetPort) { - super(sourcePort, targetPort); - } - - @Deprecated - public static <T> void connect(final OutputPort<? extends T> sourcePort, final InputPort<T> targetPort) { - final IPipe pipe = new CommittablePipe(null, null); - pipe.connectPorts(sourcePort, targetPort); - } - - @Override - public boolean add(final Object element) { - this.elements.addToTailUncommitted(element); - this.elements.commit(); - return true; - } - - @Override - public Object removeLast() { - final Object element = this.elements.removeFromHeadUncommitted(); - this.elements.commit(); - return element; - } - - @Override - public boolean isEmpty() { - return this.elements.isEmpty(); - } - - public CommittableResizableArrayQueue<?> getElements() { - return this.elements; - } - - @Override - public int size() { - return this.elements.size(); - } - -} diff --git a/src/main/java/teetime/framework/pipe/CommittablePipeFactory.java b/src/main/java/teetime/framework/pipe/CommittablePipeFactory.java deleted file mode 100644 index 8589642d33ecca57300acbd4ca481d65d28a0973..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/framework/pipe/CommittablePipeFactory.java +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.framework.pipe; - -import teetime.framework.InputPort; -import teetime.framework.OutputPort; -import teetime.framework.pipe.PipeFactoryRegistry.PipeOrdering; -import teetime.framework.pipe.PipeFactoryRegistry.ThreadCommunication; - -public final class CommittablePipeFactory implements IPipeFactory { - - @Override - public <T> IPipe create(final OutputPort<? extends T> sourcePort, final InputPort<T> targetPort) { - return this.create(sourcePort, targetPort, 1); - } - - @Override - public <T> IPipe create(final OutputPort<? extends T> sourcePort, final InputPort<T> targetPort, final int capacity) { - return new CommittablePipe(sourcePort, targetPort); - } - - @Override - public ThreadCommunication getThreadCommunication() { - return ThreadCommunication.INTRA; - } - - @Override - public PipeOrdering getOrdering() { - return PipeOrdering.STACK_BASED; - } - - @Override - public boolean isGrowable() { - return true; - } - -} diff --git a/src/main/java/teetime/framework/pipe/ConcurrentBlockingIntraThreadPipe.java b/src/main/java/teetime/framework/pipe/ConcurrentBlockingIntraThreadPipe.java deleted file mode 100644 index 5df2677f36d574caf2e54ebbb5ce267a3c972b81..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/framework/pipe/ConcurrentBlockingIntraThreadPipe.java +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.framework.pipe; - -import java.util.concurrent.ConcurrentLinkedQueue; - -import teetime.framework.AbstractIntraThreadPipe; -import teetime.framework.InputPort; -import teetime.framework.OutputPort; - -final class ConcurrentBlockingIntraThreadPipe<T> extends AbstractIntraThreadPipe { - - private final ConcurrentLinkedQueue<Object> queue; - - ConcurrentBlockingIntraThreadPipe(final OutputPort<? extends T> sourcePort, final InputPort<T> targetPort) { - super(sourcePort, targetPort); - queue = new ConcurrentLinkedQueue<Object>(); - } - - @Override - public boolean add(final Object element) { - return queue.add(element); - } - - @Override - public boolean isEmpty() { - return queue.isEmpty(); - } - - @Override - public int size() { - return queue.size(); - } - - @Override - public Object removeLast() { - return queue.poll(); - } - -} diff --git a/src/main/java/teetime/framework/pipe/ConcurrentBlockingIntraThreadPipeFactory.java b/src/main/java/teetime/framework/pipe/ConcurrentBlockingIntraThreadPipeFactory.java deleted file mode 100644 index f62aee8e5367cb721b5ddf563439501fa2918103..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/framework/pipe/ConcurrentBlockingIntraThreadPipeFactory.java +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.framework.pipe; - -import teetime.framework.InputPort; -import teetime.framework.OutputPort; -import teetime.framework.pipe.PipeFactoryRegistry.PipeOrdering; -import teetime.framework.pipe.PipeFactoryRegistry.ThreadCommunication; - -public final class ConcurrentBlockingIntraThreadPipeFactory implements IPipeFactory { - - @Override - public <T> IPipe create(final OutputPort<? extends T> sourcePort, final InputPort<T> targetPort) { - return this.create(sourcePort, targetPort, 4); - } - - @Override - public <T> IPipe create(final OutputPort<? extends T> sourcePort, final InputPort<T> targetPort, final int capacity) { - return new ConcurrentBlockingIntraThreadPipe<T>(sourcePort, targetPort); - } - - @Override - public ThreadCommunication getThreadCommunication() { - return ThreadCommunication.INTRA; - } - - @Override - public PipeOrdering getOrdering() { - return PipeOrdering.QUEUE_BASED; - } - - @Override - public boolean isGrowable() { - return true; - } - -} diff --git a/src/main/java/teetime/framework/pipe/OrderedGrowableArrayPipe.java b/src/main/java/teetime/framework/pipe/OrderedGrowableArrayPipe.java deleted file mode 100644 index db2c09c2304154f21afb9bd578d2d9dc7c44084f..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/framework/pipe/OrderedGrowableArrayPipe.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.framework.pipe; - -import teetime.framework.AbstractIntraThreadPipe; -import teetime.framework.InputPort; -import teetime.framework.OutputPort; -import teetime.util.concurrent.workstealing.CircularArray; - -final class OrderedGrowableArrayPipe extends AbstractIntraThreadPipe { - - private final CircularArray<Object> elements; - private int head; - private int tail; - - <T> OrderedGrowableArrayPipe(final OutputPort<? extends T> sourcePort, final InputPort<T> targetPort, final int capacity) { - super(sourcePort, targetPort); - this.elements = new CircularArray<Object>(capacity); - } - - @Deprecated - public static <T> void connect(final OutputPort<? extends T> sourcePort, final InputPort<T> targetPort) { - final IPipe pipe = new OrderedGrowableArrayPipe(sourcePort, targetPort, 4); - pipe.connectPorts(sourcePort, targetPort); - } - - @Override - public boolean add(final Object element) { - this.elements.put(this.tail++, element); - return true; - } - - @Override - public Object removeLast() { - if (this.head < this.tail) { - return this.elements.get(this.head++); - } else { - return null; - } - } - - @Override - public boolean isEmpty() { - return this.size() == 0; - } - - @Override - public int size() { - return this.tail - this.head; - } - -} diff --git a/src/main/java/teetime/framework/pipe/OrderedGrowableArrayPipeFactory.java b/src/main/java/teetime/framework/pipe/OrderedGrowableArrayPipeFactory.java deleted file mode 100644 index d37082fb14d4f62f3f3f42896d246e49960a78c9..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/framework/pipe/OrderedGrowableArrayPipeFactory.java +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.framework.pipe; - -import teetime.framework.InputPort; -import teetime.framework.OutputPort; -import teetime.framework.pipe.PipeFactoryRegistry.PipeOrdering; -import teetime.framework.pipe.PipeFactoryRegistry.ThreadCommunication; - -public final class OrderedGrowableArrayPipeFactory implements IPipeFactory { - - @Override - public <T> IPipe create(final OutputPort<? extends T> sourcePort, final InputPort<T> targetPort) { - return this.create(sourcePort, targetPort, 4); - } - - @Override - public <T> IPipe create(final OutputPort<? extends T> sourcePort, final InputPort<T> targetPort, final int capacity) { - return new OrderedGrowableArrayPipe(sourcePort, targetPort, capacity); - } - - @Override - public ThreadCommunication getThreadCommunication() { - return ThreadCommunication.INTRA; - } - - @Override - public PipeOrdering getOrdering() { - return PipeOrdering.QUEUE_BASED; - } - - @Override - public boolean isGrowable() { - return true; - } - -} diff --git a/src/main/java/teetime/framework/pipe/OrderedGrowablePipe.java b/src/main/java/teetime/framework/pipe/OrderedGrowablePipe.java deleted file mode 100644 index c51d67ec6fd6a363bc90cf7559307f8fb4bcf65d..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/framework/pipe/OrderedGrowablePipe.java +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.framework.pipe; - -import java.util.LinkedList; - -import teetime.framework.AbstractIntraThreadPipe; -import teetime.framework.InputPort; -import teetime.framework.OutputPort; - -class OrderedGrowablePipe extends AbstractIntraThreadPipe { - - private final LinkedList<Object> elements; - - <T> OrderedGrowablePipe(final OutputPort<? extends T> sourcePort, final InputPort<T> targetPort, final int capacity) { - super(sourcePort, targetPort); - this.elements = new LinkedList<Object>(); - } - - @Deprecated - public static <T> void connect(final OutputPort<? extends T> sourcePort, final InputPort<T> targetPort) { - final IPipe pipe = new OrderedGrowablePipe(null, null, 100000); - pipe.connectPorts(sourcePort, targetPort); - } - - @Override - public boolean add(final Object element) { - return this.elements.offer(element); - } - - @Override - public Object removeLast() { - return this.elements.poll(); - } - - @Override - public boolean isEmpty() { - return this.elements.isEmpty(); - } - - @Override - public int size() { - return this.elements.size(); - } - -} diff --git a/src/main/java/teetime/framework/pipe/PipeFactoryLoader.java b/src/main/java/teetime/framework/pipe/PipeFactoryLoader.java index 1c75785c41ee6999a11f09aaef36dc240850b2b3..bfd041890d8bc8ed7054374700054cd00bcbaf9c 100644 --- a/src/main/java/teetime/framework/pipe/PipeFactoryLoader.java +++ b/src/main/java/teetime/framework/pipe/PipeFactoryLoader.java @@ -29,7 +29,7 @@ import org.slf4j.LoggerFactory; import teetime.util.classpath.FileSearcher; -public final class PipeFactoryLoader { +final class PipeFactoryLoader { private static final Logger LOGGER = LoggerFactory.getLogger(PipeFactoryLoader.class); @@ -70,7 +70,6 @@ public final class PipeFactoryLoader { } public static List<IPipeFactory> loadPipeFactoriesFromClasspath(final String configFileName) { - List<URL> files = null; try { diff --git a/src/main/java/teetime/framework/pipe/PipeFactoryRegistry.java b/src/main/java/teetime/framework/pipe/PipeFactoryRegistry.java index 1f5291c55ed47cdd48cd5ca62c82acdfb236820a..2b3a024aa4da61fe523adf88687dfb6690242471 100644 --- a/src/main/java/teetime/framework/pipe/PipeFactoryRegistry.java +++ b/src/main/java/teetime/framework/pipe/PipeFactoryRegistry.java @@ -28,7 +28,9 @@ import org.slf4j.LoggerFactory; * <p> * To get a PipeFactory instance, call {@link #getPipeFactory(ThreadCommunication, PipeOrdering, boolean)}. * + * @Deprecated since 1.2 */ +@Deprecated public final class PipeFactoryRegistry { private static final Logger LOGGER = LoggerFactory.getLogger(PipeFactoryRegistry.class); diff --git a/src/main/java/teetime/framework/pipe/SpScIntraThreadPipe.java b/src/main/java/teetime/framework/pipe/SpScIntraThreadPipe.java deleted file mode 100644 index bae82ce7c34448d5592c68dcdbbd71e1597fb3fa..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/framework/pipe/SpScIntraThreadPipe.java +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.framework.pipe; - -import java.util.Queue; - -import org.jctools.queues.QueueFactory; -import org.jctools.queues.spec.ConcurrentQueueSpec; - -import teetime.framework.AbstractIntraThreadPipe; -import teetime.framework.InputPort; -import teetime.framework.OutputPort; - -/** - * Represents a less efficient implementation of an intra-thread pipe. - * - * @author Christian Wulf - * - * @param <T> - */ -final class SpScIntraThreadPipe<T> extends AbstractIntraThreadPipe { - - private final Queue<Object> queue; - - SpScIntraThreadPipe(final OutputPort<? extends T> sourcePort, final InputPort<T> targetPort) { - super(sourcePort, targetPort); - queue = QueueFactory.newQueue(ConcurrentQueueSpec.createBoundedSpsc(1)); - } - - @Override - public boolean add(final Object element) { - return queue.offer(element); - } - - @Override - public boolean isEmpty() { - return queue.isEmpty(); - } - - @Override - public int size() { - return queue.size(); - } - - @Override - public Object removeLast() { - return queue.poll(); - } - -} diff --git a/src/main/java/teetime/framework/pipe/SpScIntraThreadPipeFactory.java b/src/main/java/teetime/framework/pipe/SpScIntraThreadPipeFactory.java deleted file mode 100644 index 0fae0a6853632cc81e65a949063dc9a535f90431..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/framework/pipe/SpScIntraThreadPipeFactory.java +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.framework.pipe; - -import teetime.framework.InputPort; -import teetime.framework.OutputPort; -import teetime.framework.pipe.PipeFactoryRegistry.PipeOrdering; -import teetime.framework.pipe.PipeFactoryRegistry.ThreadCommunication; - -public final class SpScIntraThreadPipeFactory implements IPipeFactory { - - @Override - public <T> IPipe create(final OutputPort<? extends T> sourcePort, final InputPort<T> targetPort) { - return this.create(sourcePort, targetPort, 4); - } - - @Override - public <T> IPipe create(final OutputPort<? extends T> sourcePort, final InputPort<T> targetPort, final int capacity) { - return new SpScIntraThreadPipe<T>(sourcePort, targetPort); - } - - @Override - public ThreadCommunication getThreadCommunication() { - return ThreadCommunication.INTRA; - } - - @Override - public PipeOrdering getOrdering() { - return PipeOrdering.QUEUE_BASED; - } - - @Override - public boolean isGrowable() { - return false; - } - -} diff --git a/src/main/java/teetime/framework/pipe/SpScPipe.java b/src/main/java/teetime/framework/pipe/SpScPipe.java index 4c1e52ae7edb9fce65bfe349314afb5b379e4f34..7d68aafb9af1ffdefcb242f1eb1d042bcfe493d3 100644 --- a/src/main/java/teetime/framework/pipe/SpScPipe.java +++ b/src/main/java/teetime/framework/pipe/SpScPipe.java @@ -41,9 +41,9 @@ final class SpScPipe extends AbstractInterThreadPipe implements IMonitorablePipe return pipe; } + // BETTER introduce a QueueIsFullStrategy @Override public boolean add(final Object element) { - // BETTER introduce a QueueIsFullStrategy while (!this.queue.offer(element)) { // Thread.yield(); if (this.cachedTargetStage.getCurrentState() == StageState.TERMINATED) { diff --git a/src/main/java/teetime/framework/pipe/UnorderedGrowablePipe.java b/src/main/java/teetime/framework/pipe/UnorderedGrowablePipe.java deleted file mode 100644 index 9baa545f3a0788ac384df2cd4ae5768cced97d55..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/framework/pipe/UnorderedGrowablePipe.java +++ /dev/null @@ -1,91 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.framework.pipe; - -import teetime.framework.AbstractIntraThreadPipe; -import teetime.framework.InputPort; -import teetime.framework.OutputPort; - -final class UnorderedGrowablePipe extends AbstractIntraThreadPipe { - - private Object[] elements; - // private final ArrayWrapper2<T> elements = new ArrayWrapper2<T>(2); - private int lastFreeIndex; - - <T> UnorderedGrowablePipe(final OutputPort<? extends T> sourcePort, final InputPort<T> targetPort, final int capacity) { - super(sourcePort, targetPort); - this.elements = new Object[capacity]; - } - - @Deprecated - public static <T> void connect(final OutputPort<? extends T> sourcePort, final InputPort<T> targetPort) { - final IPipe pipe = new UnorderedGrowablePipe(null, null, 4); - pipe.connectPorts(sourcePort, targetPort); - } - - @Override - public boolean add(final Object element) { - if (this.lastFreeIndex == this.elements.length) { - // if (this.lastFreeIndex == this.elements.getCapacity()) { - this.elements = this.grow(); - } - this.elements[this.lastFreeIndex++] = element; - // this.elements.put(this.lastFreeIndex++, element); - return true; - } - - @Override - public Object removeLast() { - // if (this.lastFreeIndex == 0) { - // return null; - // } - final Object element = this.elements[--this.lastFreeIndex]; - this.elements[this.lastFreeIndex] = null; - // T element = this.elements.get(--this.lastFreeIndex); - return element; - } - - @Override - public boolean isEmpty() { - return this.lastFreeIndex == 0; - } - - @Override - public int size() { - return this.lastFreeIndex; - } - - private Object[] grow() { - final int newSize = this.elements.length * 2; - // System.out.println("growing to " + newSize); - return this.newArray(newSize); - } - - // we do not support shrink since it causes too much overhead due to the capacity checks - // private T[] shrink() { - // int newSize = this.elements.length / 2; - // return this.newArray(newSize); - // } - - private Object[] newArray(final int newSize) { - final Object[] newElements = new Object[newSize]; - - System.arraycopy(this.elements, 0, newElements, 0, this.elements.length); - - return newElements; - } - -} diff --git a/src/main/java/teetime/framework/pipe/UnorderedGrowablePipeFactory.java b/src/main/java/teetime/framework/pipe/UnorderedGrowablePipeFactory.java deleted file mode 100644 index f1e314e789f18822707c0d091beb2e4cf5e9e22f..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/framework/pipe/UnorderedGrowablePipeFactory.java +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.framework.pipe; - -import teetime.framework.InputPort; -import teetime.framework.OutputPort; -import teetime.framework.pipe.PipeFactoryRegistry.PipeOrdering; -import teetime.framework.pipe.PipeFactoryRegistry.ThreadCommunication; - -public final class UnorderedGrowablePipeFactory implements IPipeFactory { - - @Override - public <T> IPipe create(final OutputPort<? extends T> sourcePort, final InputPort<T> targetPort) { - return this.create(sourcePort, targetPort, 4); - } - - @Override - public <T> IPipe create(final OutputPort<? extends T> sourcePort, final InputPort<T> targetPort, final int capacity) { - return new UnorderedGrowablePipe(sourcePort, targetPort, capacity); - } - - @Override - public ThreadCommunication getThreadCommunication() { - return ThreadCommunication.INTRA; - } - - @Override - public PipeOrdering getOrdering() { - return PipeOrdering.STACK_BASED; - } - - @Override - public boolean isGrowable() { - return true; - } - -} diff --git a/src/main/java/teetime/stage/CipherStage.java b/src/main/java/teetime/stage/CipherStage.java index 78d2ef2ade608c214bf9be7e06a643c22f6aebba..143e907698d26deb73996244325bd704147c8ae5 100644 --- a/src/main/java/teetime/stage/CipherStage.java +++ b/src/main/java/teetime/stage/CipherStage.java @@ -82,8 +82,8 @@ public final class CipherStage extends AbstractConsumerStage<byte[]> { @Override protected void execute(final byte[] element) { try { - byte[] output = this.cipher.doFinal(element); - this.outputPort.send(output); + byte[] outputBytes = this.cipher.doFinal(element); + this.outputPort.send(outputBytes); } catch (IllegalBlockSizeException e) { throw new IllegalStateException(e); } catch (BadPaddingException e) { diff --git a/src/main/java/teetime/stage/ZipByteArray.java b/src/main/java/teetime/stage/ZipByteArray.java index b59e4e26c14e4d81e6bb627eec88b53ebb2b5eb9..0d92875d46095c03899d7ade6a3994886abf52e1 100644 --- a/src/main/java/teetime/stage/ZipByteArray.java +++ b/src/main/java/teetime/stage/ZipByteArray.java @@ -45,17 +45,17 @@ public final class ZipByteArray extends AbstractConsumerStage<byte[]> { @Override protected void execute(final byte[] element) { - byte[] cache = null; + byte[] streamBytes = null; try { if (mode == ZipMode.COMP) { - cache = compress(element); + streamBytes = compress(element); } else { - cache = decompress(element); + streamBytes = decompress(element); } } catch (Exception e) { e.printStackTrace(); } - outputPort.send(cache); + outputPort.send(streamBytes); } private byte[] compress(final byte[] data) throws IOException { @@ -65,17 +65,17 @@ public final class ZipByteArray extends AbstractConsumerStage<byte[]> { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length); deflater.finish(); - byte[] buffer = new byte[1024]; + byte[] buffer = new byte[1024]; // NOPMD while (!deflater.finished()) { int count = deflater.deflate(buffer); // returns the generated code... index outputStream.write(buffer, 0, count); } outputStream.close(); - byte[] output = outputStream.toByteArray(); + byte[] outputBytes = outputStream.toByteArray(); deflater.end(); - return output; + return outputBytes; } private byte[] decompress(final byte[] data) throws IOException, DataFormatException { @@ -83,17 +83,17 @@ public final class ZipByteArray extends AbstractConsumerStage<byte[]> { inflater.setInput(data); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length); - byte[] buffer = new byte[1024]; + byte[] buffer = new byte[1024]; // NOPMD while (!inflater.finished()) { int count = inflater.inflate(buffer); outputStream.write(buffer, 0, count); } outputStream.close(); - byte[] output = outputStream.toByteArray(); + byte[] outputBytes = outputStream.toByteArray(); inflater.end(); - return output; + return outputBytes; } public OutputPort<? extends byte[]> getOutputPort() { diff --git a/src/main/java/teetime/stage/basic/distributor/RoundRobinStrategy2.java b/src/main/java/teetime/stage/basic/distributor/RoundRobinStrategy2.java index e62f221b4fb3e9317d31239710045cb3f78af0c7..829e9f7eb797d54d5070805449fe3e94ffd6643e 100644 --- a/src/main/java/teetime/stage/basic/distributor/RoundRobinStrategy2.java +++ b/src/main/java/teetime/stage/basic/distributor/RoundRobinStrategy2.java @@ -38,14 +38,7 @@ public final class RoundRobinStrategy2 implements IDistributorStrategy { success = outputPort.sendNonBlocking(element); if (0 == numLoops) { numWaits++; - // Thread.yield(); - try { - Thread.sleep(1); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - + backoff(); numLoops = numOutputPorts; } numLoops--; @@ -54,6 +47,16 @@ public final class RoundRobinStrategy2 implements IDistributorStrategy { return true; } + private void backoff() { + try { + Thread.sleep(1); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + // Thread.yield(); + } + private <T> OutputPort<T> getNextPortInRoundRobinOrder(final OutputPort<T>[] outputPorts) { final OutputPort<T> outputPort = outputPorts[this.index]; diff --git a/src/main/java/teetime/stage/io/ByteArrayFileWriter.java b/src/main/java/teetime/stage/io/ByteArrayFileWriter.java index 93375cd7d877cbbcbb516d7f6570776b83074efe..abebaeab55c8fd83757ec4a7903a6e5be60eeee1 100644 --- a/src/main/java/teetime/stage/io/ByteArrayFileWriter.java +++ b/src/main/java/teetime/stage/io/ByteArrayFileWriter.java @@ -40,7 +40,6 @@ public final class ByteArrayFileWriter extends AbstractConsumerStage<byte[]> { @Override protected void execute(final byte[] element) { - try { fo.write(element); } catch (Exception e) { diff --git a/src/main/java/teetime/stage/io/File2ByteArray.java b/src/main/java/teetime/stage/io/File2ByteArray.java index 387a999746f6df0247be3e7ffd65775fedfa8cf1..caa51fb5f5b608ee6d3525e7d323469ee82e5eae 100644 --- a/src/main/java/teetime/stage/io/File2ByteArray.java +++ b/src/main/java/teetime/stage/io/File2ByteArray.java @@ -30,8 +30,8 @@ public final class File2ByteArray extends AbstractConsumerStage<File> { @Override protected void execute(final File element) { try { - byte[] cache = Files.toByteArray(element); - outputPort.send(cache); + byte[] fileBytes = Files.toByteArray(element); + outputPort.send(fileBytes); } catch (IOException e) { throw new IllegalStateException(e); } diff --git a/src/main/java/teetime/stage/io/File2SeqOfWords.java b/src/main/java/teetime/stage/io/File2SeqOfWords.java index 389fd1610365b34b346b0cc24fb7ad86fb9a2ff9..76062e4a833ff6ed31f4243c08dd7916b16fbe68 100644 --- a/src/main/java/teetime/stage/io/File2SeqOfWords.java +++ b/src/main/java/teetime/stage/io/File2SeqOfWords.java @@ -47,6 +47,10 @@ public final class File2SeqOfWords extends AbstractConsumerStage<File> { this("UTF-8", 1024); } + public File2SeqOfWords(final int bufferCapacity) { + this("UTF-8", bufferCapacity); + } + public File2SeqOfWords(final String charset, final int bufferCapacity) { super(); this.charset = charset; diff --git a/src/main/java/teetime/stage/string/buffer/StringBufferFilter.java b/src/main/java/teetime/stage/string/buffer/StringBufferFilter.java deleted file mode 100644 index cd187eff2679e60fff5a7312b88c35b585d24064..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/stage/string/buffer/StringBufferFilter.java +++ /dev/null @@ -1,86 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.stage.string.buffer; - -import java.util.Collection; -import java.util.LinkedList; - -import teetime.framework.AbstractConsumerStage; -import teetime.framework.OutputPort; -import teetime.stage.string.buffer.handler.AbstractDataTypeHandler; -import teetime.stage.string.buffer.util.KiekerHashMap; - -/** - * @author Christian Wulf - * - * @since 1.10 - */ -public final class StringBufferFilter<T> extends AbstractConsumerStage<T> { - - private final OutputPort<T> outputPort = this.createOutputPort(); - - // BETTER use a non shared data structure to avoid synchronization between threads - private KiekerHashMap kiekerHashMap = new KiekerHashMap(); - - private Collection<AbstractDataTypeHandler<?>> dataTypeHandlers = new LinkedList<AbstractDataTypeHandler<?>>(); - - @Override - protected void execute(final T element) { - final T returnedElement = this.handle(element); - outputPort.send(returnedElement); - } - - @Override - public void onStarting() throws Exception { - super.onStarting(); - for (final AbstractDataTypeHandler<?> handler : this.dataTypeHandlers) { - handler.setLogger(this.logger); - handler.setStringRepository(this.kiekerHashMap); - } - } - - private T handle(final T object) { - for (final AbstractDataTypeHandler<?> handler : this.dataTypeHandlers) { - if (handler.canHandle(object)) { - @SuppressWarnings("unchecked") - final T returnedObject = ((AbstractDataTypeHandler<T>) handler).handle(object); - return returnedObject; - } - } - return object; // else relay given object - } - - public KiekerHashMap getKiekerHashMap() { - return this.kiekerHashMap; - } - - public void setKiekerHashMap(final KiekerHashMap kiekerHashMap) { - this.kiekerHashMap = kiekerHashMap; - } - - public Collection<AbstractDataTypeHandler<?>> getDataTypeHandlers() { - return this.dataTypeHandlers; - } - - public void setDataTypeHandlers(final Collection<AbstractDataTypeHandler<?>> dataTypeHandlers) { - this.dataTypeHandlers = dataTypeHandlers; - } - - public OutputPort<T> getOutputPort() { - return outputPort; - } - -} diff --git a/src/main/java/teetime/stage/string/buffer/handler/AbstractDataTypeHandler.java b/src/main/java/teetime/stage/string/buffer/handler/AbstractDataTypeHandler.java deleted file mode 100644 index 6f4540cdfd1040c94e2971142543a29d4f4a2a59..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/stage/string/buffer/handler/AbstractDataTypeHandler.java +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.stage.string.buffer.handler; - -import org.slf4j.Logger; - -import teetime.stage.string.buffer.util.KiekerHashMap; - -/** - * @author Christian Wulf - * - * @since 1.10 - */ -public abstract class AbstractDataTypeHandler<T> { - - protected Logger logger; - protected KiekerHashMap stringRepository; - - /** - * @since 1.10 - */ - public abstract boolean canHandle(Object object); - - /** - * @since 1.10 - */ - public abstract T handle(T object); - - /** - * @since 1.10 - */ - public void setLogger(final Logger logger) { - this.logger = logger; - } - - /** - * @since 1.10 - */ - public void setStringRepository(final KiekerHashMap stringRepository) { - this.stringRepository = stringRepository; - } - -} diff --git a/src/main/java/teetime/stage/string/buffer/handler/StringHandler.java b/src/main/java/teetime/stage/string/buffer/handler/StringHandler.java deleted file mode 100644 index bef40e5d09b74761661ad93725f3342d902c0edc..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/stage/string/buffer/handler/StringHandler.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.stage.string.buffer.handler; - -/** - * @author Christian Wulf - * - * @since 1.10 - */ -public class StringHandler extends AbstractDataTypeHandler<String> { - - @Override - public boolean canHandle(final Object object) { - return object instanceof String; - } - - @Override - public String handle(final String object) { - return this.stringRepository.get(object); - } - -} diff --git a/src/main/java/teetime/stage/string/buffer/util/KiekerHashMap.java b/src/main/java/teetime/stage/string/buffer/util/KiekerHashMap.java deleted file mode 100644 index 1806abe5718cf67b3c6bf714ea30c741b82348db..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/stage/string/buffer/util/KiekerHashMap.java +++ /dev/null @@ -1,291 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.stage.string.buffer.util; - -import java.lang.ref.SoftReference; -import java.util.concurrent.locks.ReentrantLock; - -/** - * @author Christian Wulf - * - * @since 1.10 - */ -public class KiekerHashMap { - - private static final int INITIAL_CAPACITY = 16; - private static final double LOAD_FACTOR = 0.75d; - private static final int CONCURRENCY_LEVEL = 16; - private static final int MAXIMUM_CAPACITY = 1 << 30; - - /** - * Mask value for indexing into segments. The upper bits of a key's hash code are used to choose the segment. - */ - private final int segmentMask; - - /** - * Shift value for indexing within segments. - */ - private final int segmentShift; - - /** - * The segments, each of which is a specialized hash table. - */ - private final Segment[] segments; - - /** - * @since 1.10 - */ - public KiekerHashMap() { - // Find power-of-two sizes best matching arguments - int sshift = 0; - int ssize = 1; - while (ssize < CONCURRENCY_LEVEL) { - ++sshift; - ssize <<= 1; - } - this.segmentShift = 32 - sshift; - this.segmentMask = ssize - 1; - this.segments = new Segment[ssize]; - int c = INITIAL_CAPACITY / ssize; - if ((c * ssize) < INITIAL_CAPACITY) { - ++c; - } - int cap = 1; - while (cap < c) { - cap <<= 1; - } - for (int i = 0; i < this.segments.length; ++i) { - this.segments[i] = new Segment(cap, LOAD_FACTOR); - } - } - - /** - * Applies a supplemental hash function to a given hashCode, which defends against poor quality hash functions. This is critical because ConcurrentHashMap uses - * power-of-two length hash tables, that otherwise encounter collisions for hashCodes that do not differ in lower or upper bits. - */ - private static final int hash(final String value) { - // Spread bits to regularize both segment and index locations, using variant of single-word Wang/Jenkins hash. - int h = value.hashCode(); - h += (h << 15) ^ 0xffffcd7d; - h ^= h >>> 10; - h += h << 3; - h ^= h >>> 6; - h += (h << 2) + (h << 14); - return h ^ (h >>> 16); - } - - public final String get(final String value) { - final int hash = KiekerHashMap.hash(value); - Segment segment = this.segments[(hash >>> this.segmentShift) & this.segmentMask]; - return segment.get(value, hash); - } - - // ---------------- Inner Classes -------------- - - /** - * StringBuffer entry. - */ - private static final class HashEntry extends SoftReference<String> { - final int hash; - final HashEntry next; - - protected HashEntry(final String value, final int hash, final HashEntry next) { - super(value); - this.hash = hash; - this.next = next; - } - } - - /** - * Segments are specialized versions of hash tables. This subclasses from ReentrantLock opportunistically, just to simplify some locking and avoid separate - * construction. - * - * Segments maintain a table of entry lists that are ALWAYS kept in a consistent state, so can be read without locking. Next fields of nodes are immutable - * (final). All list additions are performed at the front of each bin. This makes it easy to check changes, and also fast to traverse. When nodes would - * otherwise be changed, new nodes are created to replace them. This works well for hash tables since the bin lists tend to be short. (The average length is - * less than two for the default load factor threshold.) - * - * Read operations can thus proceed without locking, but rely on selected uses of volatiles to ensure that completed write operations performed by other - * threads are noticed. For most purposes, the "count" field, tracking the number of elements, serves as that volatile variable ensuring visibility. This is - * convenient because this field needs to be read in many read operations anyway: - * - * - All (unsynchronized) read operations must first read the "count" field, and should not look at table entries if it is 0. - * - * - All (synchronized) write operations should write to the "count" field after structurally changing any bin. The operations must not take any action that - * could even momentarily cause a concurrent read operation to see inconsistent data. This is made easier by the nature of the read operations in Map. For - * example, no operation can reveal that the table has grown but the threshold has not yet been updated, so there are no atomicity requirements for this with - * respect to reads. - * - * As a guide, all critical volatile reads and writes to the count field are marked in code comments. - */ - private static final class Segment extends ReentrantLock { - - private static final long serialVersionUID = 1L; - - /** - * The number of elements in this segment's region. - */ - private volatile int count; - - /** - * The per-segment table. - */ - private HashEntry[] table; - - /** - * The table is rehashed when its size exceeds this threshold. (The value of this field is always <tt>(int)(capacity * loadFactor)</tt>.) - */ - private int threshold; - - protected Segment(final int initialCapacity, final double lf) { - this.table = new HashEntry[initialCapacity]; - this.threshold = (int) (initialCapacity * lf); - this.count = 0; - } - - protected final String get(final String value, final int hash) { - HashEntry e = null; - String cachedString; - if (this.count != 0) { // volatile read! search for entry without locking - final HashEntry[] tab = this.table; - final int index = hash & (tab.length - 1); - final HashEntry first = tab[index]; - e = first; - while (e != null) { - if (e.hash == hash) { - cachedString = e.get(); - if (value.equals(cachedString)) { - return cachedString; - } - } - e = e.next; - } - } - this.lock(); - try { - final int c = this.count + 1; - if (c >= this.threshold) { - this.cleanup(); - if (c >= this.threshold) { // if still full - this.rehash(); - } - this.count = c; // write volatile - } - final HashEntry[] tab = this.table; - final int index = hash & (tab.length - 1); - final HashEntry first = tab[index]; // the bin the value may be inside - e = first; - while (e != null) { - if (e.hash == hash) { - cachedString = e.get(); - if (value.equals(cachedString)) { - return cachedString; - } - } - e = e.next; - } - tab[index] = new HashEntry(value, hash, first); - this.count = c; // write-volatile - return value; // return now cached string - } finally { - this.unlock(); - } - } - - private final void cleanup() { - int c = this.count; - final HashEntry[] tab = this.table; - for (int index = 0; index < tab.length; index++) { - // find first remaining entry - HashEntry e = tab[index]; - while ((e != null) && (e.get() == null)) { - e = e.next; - c--; - } - if (e == null) { - tab[index] = null; - } else { - // find more existing entries and enqueue before this one - HashEntry first = new HashEntry(e.get(), e.hash, null); - e = e.next; - while (e != null) { - final String s = e.get(); - if (s != null) { - first = new HashEntry(s, e.hash, first); - } else { - c--; - } - e = e.next; - } - tab[index] = first; - } - } - c--; - this.count = c; // write-volatile - } - - /** - * Reclassify nodes in each list to new Map. Because we are using power-of-two expansion, the elements from each bin must either stay at same index, or - * move with a power of two offset. We eliminate unnecessary node creation by catching cases where old nodes can be reused because their next fields - * won't change. Statistically, at the default threshold, only about one-sixth of them need cloning when a table doubles. The nodes they replace will be - * garbage collectable as soon as they are no longer referenced by any reader thread that may be in the midst of traversing table right now. - */ - private final void rehash() { - final HashEntry[] oldTable = this.table; - final int oldCapacity = oldTable.length; - if (oldCapacity >= MAXIMUM_CAPACITY) { - return; - } - final HashEntry[] newTable = new HashEntry[oldCapacity << 1]; - this.threshold = (int) (newTable.length * LOAD_FACTOR); - final int sizeMask = newTable.length - 1; - for (int i = 0; i < oldCapacity; i++) { - // We need to guarantee that any existing reads of old Map can proceed. So we cannot yet null out each bin. - final HashEntry e = oldTable[i]; - - if (e != null) { - final HashEntry next = e.next; - final int idx = e.hash & sizeMask; - - // Single node on list - if (next == null) { - newTable[idx] = e; - } else { - // Reuse trailing consecutive sequence at same slot - HashEntry lastRun = e; - int lastIdx = idx; - for (HashEntry last = next; last != null; last = last.next) { // find end of bin - final int k = last.hash & sizeMask; - if (k != lastIdx) { // NOCS (nested if) - lastIdx = k; - lastRun = last; - } - } - newTable[lastIdx] = lastRun; - - // Clone all remaining nodes - for (HashEntry p = e; p != lastRun; p = p.next) { - final int k = p.hash & sizeMask; - final HashEntry n = newTable[k]; - newTable[k] = new HashEntry(p.get(), p.hash, n); - } - } - } - } - this.table = newTable; - } - } -} diff --git a/src/main/java/teetime/util/CyclicListIterator.java b/src/main/java/teetime/util/CyclicListIterator.java index 1579d5d3c7f2966800fa2e9bd791e046037fb73c..7f7ca993af80ebea4c166ec0887b06c4cc84b869 100644 --- a/src/main/java/teetime/util/CyclicListIterator.java +++ b/src/main/java/teetime/util/CyclicListIterator.java @@ -44,6 +44,10 @@ public final class CyclicListIterator<T> implements Iterator<T> { @Override public T next() { + this.currentIndex = this.getCurrentIndex(); + final T element = this.elements.get(this.currentIndex); + this.currentIndex++; + return element; // if (!this.iterator.hasNext()) { // this.iterator = this.list.iterator(); // } @@ -52,17 +56,13 @@ public final class CyclicListIterator<T> implements Iterator<T> { // the size of the list could have been changed due to // <li>an index overflow (then restart from index 0), or // <li>an add() or a remove(), so update the index - this.currentIndex = this.getCurrentIndex(); - final T element = this.elements.get(this.currentIndex); - this.currentIndex++; - return element; } @Override public void remove() { - // this.iterator.remove(); this.currentIndex = this.getCurrentIndex(); this.elements.remove(this.currentIndex); + // this.iterator.remove(); } private int getCurrentIndex() { diff --git a/src/main/java/teetime/util/HashMapWithDefault.java b/src/main/java/teetime/util/HashMapWithDefault.java deleted file mode 100644 index a54a1b81c896fed14360a546583cb8b26b4b7053..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/util/HashMapWithDefault.java +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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; - -import java.util.HashMap; - -import teetime.util.concurrent.hashmap.ValueFactory; - -/** - * @author Christian Wulf - * - * @since 1.10 - */ -public final class HashMapWithDefault<K, V> extends HashMap<K, V> { - - private static final long serialVersionUID = -7958038532219740472L; - - private final ValueFactory<V> valueFactory; - - /** - * @since 1.10 - */ - public HashMapWithDefault(final ValueFactory<V> valueFactory) { - this.valueFactory = valueFactory; - } - - /** - * @return the corresponding value if the key exists. Otherwise, it creates, - * inserts, and returns a new default value. - */ - @SuppressWarnings("unchecked") - @Override - public V get(final Object key) { - V value = super.get(key); - if (value == null) { - value = this.valueFactory.create(); - super.put((K) key, value); - } - return value; - } -} diff --git a/src/main/java/teetime/util/classpath/FileSearcher.java b/src/main/java/teetime/util/classpath/FileSearcher.java index be1af8218d7da5f61cc4bcea543a42234e24e743..413bcf4dbf9037f5fb9a0ec91d1a2a59224266dc 100644 --- a/src/main/java/teetime/util/classpath/FileSearcher.java +++ b/src/main/java/teetime/util/classpath/FileSearcher.java @@ -30,12 +30,12 @@ public final class FileSearcher { } public static List<URL> loadResources(final String name) throws IOException { - final List<URL> list = new ArrayList<URL>(); + final List<URL> urls = new ArrayList<URL>(); final Enumeration<URL> systemRes = CLASS_LOADER.getResources(name); while (systemRes.hasMoreElements()) { - list.add(systemRes.nextElement()); + urls.add(systemRes.nextElement()); } - return list; + return urls; } } diff --git a/src/main/java/teetime/util/concurrent/hashmap/ConcurrentHashMapWithDefault.java b/src/main/java/teetime/util/concurrent/hashmap/ConcurrentHashMapWithDefault.java deleted file mode 100644 index 98bdf02708294e10de5aca0c2da05af8b8a277bc..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/util/concurrent/hashmap/ConcurrentHashMapWithDefault.java +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.concurrent.hashmap; - -import java.util.concurrent.ConcurrentHashMap; - -public final class ConcurrentHashMapWithDefault<K, V> extends ConcurrentHashMap<K, V> { - - private static final long serialVersionUID = 199185976241037967L; - - private final ValueFactory<V> valueFactory; - - private int maxElements; - - public ConcurrentHashMapWithDefault(final ValueFactory<V> valueFactory) { - this.valueFactory = valueFactory; - } - - public V getOrCreate(final K key) { - V value = this.get(key); - if (value == null) { - synchronized (this) { - value = this.get(key); - if (value == null) { // NOCS (DCL) - value = this.valueFactory.create(); - this.put(key, value); - this.maxElements++; - } - } - } - return value; - } - - public int getMaxElements() { - return this.maxElements; - } -} diff --git a/src/main/java/teetime/util/concurrent/hashmap/ValueFactory.java b/src/main/java/teetime/util/concurrent/hashmap/ValueFactory.java deleted file mode 100644 index 543cf5952e90479ca45720a56579a1524805f3be..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/util/concurrent/hashmap/ValueFactory.java +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.concurrent.hashmap; - -/** - * @author Christian Wulf - * - * @since 1.10 - */ -public interface ValueFactory<T> { - - /** - * Create a new instance of the type <code>T</code>. - * - * @since 1.10 - */ - public T create(); -} diff --git a/src/main/java/teetime/util/concurrent/queue/takestrategy/SCParkTakeStrategy.java b/src/main/java/teetime/util/concurrent/queue/takestrategy/SCParkTakeStrategy.java index 6875d3815e8cb4d910288275b3bb8dcfa493e95e..ad8148120ca4272b1da09cc3d54fa12b71e66f78 100644 --- a/src/main/java/teetime/util/concurrent/queue/takestrategy/SCParkTakeStrategy.java +++ b/src/main/java/teetime/util/concurrent/queue/takestrategy/SCParkTakeStrategy.java @@ -26,9 +26,9 @@ public final class SCParkTakeStrategy<E> implements TakeStrategy<E> { private final AtomicReference<Thread> t = new AtomicReference<Thread>(null); @Override + // Make sure the offer is visible before unpark public void signal() { - // Make sure the offer is visible before unpark storeFence = 1; // store barrier LockSupport.unpark(t.get()); // t.get() load barrier diff --git a/src/main/java/teetime/util/concurrent/workstealing/CircularArray.java b/src/main/java/teetime/util/concurrent/workstealing/CircularArray.java deleted file mode 100644 index 7f1e10a5ff9897a3962a07dc71445cea732e0095..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/util/concurrent/workstealing/CircularArray.java +++ /dev/null @@ -1,87 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.concurrent.workstealing; - -import java.util.Arrays; - -/** - * - * @author Christian Wulf - * - * @see "Dynamic Circular WorkStealing Deque" - * - * @since 1.10 - * - * @param <T> - */ -public final class CircularArray<T> { - - private final long logSize; - private final T[] segment; - private final long mask; - private long currentIndex; - - /** - * - * @param logSize - * The initial size of this array in log2, i.e., the number of bits to use - */ - @SuppressWarnings("unchecked") - public CircularArray(final long logSize) { - this.logSize = logSize; - this.segment = (T[]) new Object[1 << this.logSize]; - this.mask = this.getCapacity() - 1; // mask = 0..01..1 - } - - public long getCapacity() { - return this.segment.length; - } - - public T get(final long i) { - return this.segment[(int) (i & this.mask)]; // risk of overflow - } - - public T getNext() { - long index = this.currentIndex; - this.currentIndex = (this.currentIndex + 1) & this.mask; - return this.segment[(int) index]; - } - - public void put(final long i, final T o) { - this.segment[(int) (i & this.mask)] = o; // risk of overflow - } - - public CircularArray<T> grow(final long b, final long t) { - final CircularArray<T> a = new CircularArray<T>(this.logSize + 1); - for (long i = t; i < b; i++) { - a.put(i, this.get(i)); - } - return a; - } - - public CircularArray<T> shrink(final long b, final long t) { - final CircularArray<T> a = new CircularArray<T>(this.logSize - 1); - for (long i = t; i < b; i++) { - a.put(i, this.get(i)); - } - return a; - } - - @Override - public String toString() { - return Arrays.toString(this.segment); - } -} diff --git a/src/main/java/teetime/util/concurrent/workstealing/CircularIntArray.java b/src/main/java/teetime/util/concurrent/workstealing/CircularIntArray.java deleted file mode 100644 index a4f4eda9def04fd06cc27b0f541bd9b51f13195b..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/util/concurrent/workstealing/CircularIntArray.java +++ /dev/null @@ -1,87 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.concurrent.workstealing; - -import java.util.Arrays; - -/** - * - * @author Christian Wulf - * - * @see "Dynamic Circular WorkStealing Deque" - * - * @since 1.10 - * - * @param <T> - */ -public final class CircularIntArray<T> { - - private final int logSize; - private final T[] segment; - private final int mask; - private int currentIndex; - - /** - * - * @param logSize - * The initial size of this array in log2, i.e., the number of bits to use - */ - @SuppressWarnings("unchecked") - public CircularIntArray(final int logSize) { - this.logSize = logSize; - this.segment = (T[]) new Object[1 << this.logSize]; - this.mask = this.getCapacity() - 1; // mask = 0..01..1 - } - - public int getCapacity() { - return this.segment.length; - } - - public T get(final int i) { - return this.segment[i & this.mask]; // risk of overflow - } - - public T getNext() { - int index = this.currentIndex; - this.currentIndex = (this.currentIndex + 1) & this.mask; - return this.segment[index]; - } - - public void put(final int i, final T o) { - this.segment[i & this.mask] = o; // risk of overflow - } - - public CircularIntArray<T> grow(final int b, final int t) { - final CircularIntArray<T> a = new CircularIntArray<T>(this.logSize + 1); - for (int i = t; i < b; i++) { - a.put(i, this.get(i)); - } - return a; - } - - public CircularIntArray<T> shrink(final int b, final int t) { - final CircularIntArray<T> a = new CircularIntArray<T>(this.logSize - 1); - for (int i = t; i < b; i++) { - a.put(i, this.get(i)); - } - return a; - } - - @Override - public String toString() { - return Arrays.toString(this.segment); - } -} diff --git a/src/main/java/teetime/util/concurrent/workstealing/CircularModIntArray.java b/src/main/java/teetime/util/concurrent/workstealing/CircularModIntArray.java deleted file mode 100644 index a44239c5de9e33706a1ef8910e1a9efbb8332444..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/util/concurrent/workstealing/CircularModIntArray.java +++ /dev/null @@ -1,88 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.concurrent.workstealing; - -import java.util.Arrays; - -/** - * - * @author Christian Wulf - * - * @see "Dynamic Circular WorkStealing Deque" - * - * @since 1.10 - * - * @param <T> - */ -public final class CircularModIntArray<T> { - - private final int logSize; - private final T[] segment; - private final int size; - - private int currentIndex; - - /** - * - * @param logSize - * The initial size of this array in log2, i.e., the number of bits to use - */ - @SuppressWarnings("unchecked") - public CircularModIntArray(final int logSize) { - this.logSize = logSize; - this.segment = (T[]) new Object[1 << this.logSize]; - this.size = this.segment.length; - } - - public int getCapacity() { - return this.segment.length; - } - - public T get(final int i) { - return this.segment[i % this.size]; // risk of overflow - } - - public T getNext() { - int index = this.currentIndex; - this.currentIndex = (this.currentIndex + 1) % this.size; - return this.segment[index]; - } - - public void put(final int i, final T o) { - this.segment[i % this.size] = o; // risk of overflow - } - - public CircularModIntArray<T> grow(final int b, final int t) { - final CircularModIntArray<T> a = new CircularModIntArray<T>(this.logSize + 1); - for (int i = t; i < b; i++) { - a.put(i, this.get(i)); - } - return a; - } - - public CircularModIntArray<T> shrink(final int b, final int t) { - final CircularModIntArray<T> a = new CircularModIntArray<T>(this.logSize - 1); - for (int i = t; i < b; i++) { - a.put(i, this.get(i)); - } - return a; - } - - @Override - public String toString() { - return Arrays.toString(this.segment); - } -} diff --git a/src/main/java/teetime/util/concurrent/workstealing/CircularWorkStealingDeque.java b/src/main/java/teetime/util/concurrent/workstealing/CircularWorkStealingDeque.java deleted file mode 100644 index cbab820ee86422b8087b13a458c0c2e4b3445806..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/util/concurrent/workstealing/CircularWorkStealingDeque.java +++ /dev/null @@ -1,305 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.concurrent.workstealing; - -import java.util.List; -import java.util.concurrent.atomic.AtomicLong; - -import teetime.util.concurrent.workstealing.exception.DequeIsEmptyException; -import teetime.util.concurrent.workstealing.exception.OperationAbortedException; - -/** - * - * @author Christian Wulf - * - * @see "Dynamic Circular WorkStealing Deque" - * - * @since 1.10 - */ -public final class CircularWorkStealingDeque<T> { - - public static final DequeIsEmptyException DEQUE_IS_EMPTY_EXCEPTION = new DequeIsEmptyException(); - - public static final OperationAbortedException OPERATION_ABORTED_EXCEPTION = new OperationAbortedException(); - - private static final long LOG_INITIAL_SIZE = 10; - - private volatile long bottom = 0; - private final AtomicLong top = new AtomicLong(); - private volatile CircularArray<T> activeArray = new CircularArray<T>(LOG_INITIAL_SIZE); - - private final boolean casTop(final long oldVal, final long newVal) { - return this.top.compareAndSet(oldVal, newVal); - } - - /** - * - * @param o - * a non-<code>null</code> element - */ - public void pushBottom(final T o) { - final long b = this.bottom; - final long t = this.top.get(); - CircularArray<T> a = this.activeArray; - final int numElementsToPush = 1; - final long currentSize = b - t; - final long newSize = currentSize + numElementsToPush; - if (newSize > a.getCapacity()) { - a = a.grow(b, t); - this.activeArray = a; - } - a.put(b, o); - this.bottom = b + numElementsToPush; - } - - /** - * - * @param elements - * a non-<code>null</code> list - */ - public void pushBottomMultiple(final List<T> elements) { - final long b = this.bottom; - final long t = this.top.get(); - CircularArray<T> a = this.activeArray; - final int numElementsToPush = elements.size(); - final long currentSize = b - t; - final long newSize = currentSize + numElementsToPush; - if (newSize > a.getCapacity()) { - a = a.grow(b, t); - this.activeArray = a; - } - - for (final T elem : elements) { - a.put(b, elem); - } - - this.bottom = b + numElementsToPush; - } - - /** - * Returns and removes the latest element from this deque. - * - * @return - * <ul> - * <li><code>null</code> if the deque contains no elements, - * <li><i>the latest element</i> otherwise - * </ul> - */ - public T popBottom() { - long b = this.bottom; - final CircularArray<T> a = this.activeArray; - b = b - 1; - this.bottom = b; - final long t = this.top.get(); - final long size = b - t; - if (size < 0) { - this.bottom = t; - return this.empty(); - } - T o = this.regular(a.get(b)); - if (size > 0) { - this.perhapsShrink(b, t); - return o; - } - if (!this.casTop(t, t + 1)) { - o = this.empty(); - } - this.bottom = t + 1; - return o; - } - - /** - * Returns and removes the latest element from this deque. - * - * @return <i>the latest element</i>, otherwise it throws a <code>DequeIsEmptyException</code> - * - * @throws DequeIsEmptyException - */ - public T popBottomEx() { - long b = this.bottom; - final CircularArray<T> a = this.activeArray; - b = b - 1; - this.bottom = b; - final long t = this.top.get(); - final long size = b - t; - if (size < 0) { - this.bottom = t; - return this.emptyEx(); - } - T o = this.regular(a.get(b)); - if (size > 0) { - this.perhapsShrink(b, t); - return o; - } - if (!this.casTop(t, t + 1)) { - o = this.emptyEx(); - } - this.bottom = t + 1; - return o; - } - - private void perhapsShrink(final long b, final long t) { - long temp = t; - final CircularArray<T> a = this.activeArray; - if ((b - temp) < (a.getCapacity() / 4)) { - final CircularArray<T> aa = a.shrink(b, temp); - this.activeArray = aa; - final long ss = aa.getCapacity(); - this.bottom = b + ss; - temp = this.top.get(); - if (!this.casTop(temp, temp + ss)) { - this.bottom = b; - // a.free(); - } - } - } - - /** - * Tries to steal (return & remove) the oldest element from this deque. - * - * @return - * <ul> - * <li><code>null</code> if the deque contains no elements, - * <li>(and also) <code>null</code> if the deque is currently being stolen by another thread, - * <li><i>the oldest element</i> otherwise - * </ul> - */ - public T steal() { - final long t = this.top.get(); - final CircularArray<T> oldArr = this.activeArray; - final long b = this.bottom; - final CircularArray<T> a = this.activeArray; - final long size = b - t; - if (size <= 0) { - return this.empty(); - } - if ((size % a.getCapacity()) == 0) { - if ((oldArr == a) && (t == this.top.get())) { - return this.empty(); - } else { - return this.abort(); - } - } - final T o = this.regular(a.get(t)); - if (!this.casTop(t, t + 1)) { - return this.abort(); - } - return o; - } - - /** - * Tries to steal (return & remove) the oldest element from this deque. - * - * @return <i>the oldest element</i>, otherwise it throws a <code>DequeIsEmptyException</code> or a <code>OperationAbortedException</code> - * - * @throws DequeIsEmptyException - * @throws OperationAbortedException - */ - public T stealEx() { - final long t = this.top.get(); - final CircularArray<T> oldArr = this.activeArray; - final long b = this.bottom; - final CircularArray<T> a = this.activeArray; - final long size = b - t; - if (size <= 0) { - return this.emptyEx(); - } - if ((size % a.getCapacity()) == 0) { - if ((oldArr == a) && (t == this.top.get())) { - return this.emptyEx(); - } else { - return this.abortEx(); - } - } - final T o = this.regular(a.get(t)); - if (!this.casTop(t, t + 1)) { - return this.abortEx(); - } - return o; - } - - private T empty() { - return null; - } - - private T emptyEx() { - throw DEQUE_IS_EMPTY_EXCEPTION; - } - - private T abort() { - return null; - } - - private T abortEx() { - throw OPERATION_ABORTED_EXCEPTION; - } - - private T regular(final T value) { - return value; - } - - /** - * Returns but does not remove the latest element from this deque.<br> - * <i>For debugging purposes</i> - * - * @return <ul> - * <li><code>null</code> if the deque contains no elements, - * <li><i>the latest element</i> otherwise - * </ul> - */ - public T readBottom() { - final long b = this.bottom; - final CircularArray<T> a = this.activeArray; - final T o = a.get(b); - return o; - } - - // bottom: 4093 - // bottom: 66429 - // bottom: 29993 - // bottom: 29992 - // - // - // bottom: 4093 - // bottom: 66429 - // bottom: 30008 - // bottom: 30007 - - public boolean isEmpty() { - final long t = this.top.get(); - final long b = this.bottom; - return t >= b; - } - - /** - * For debugging purposes - * - * @return the number of elements this deque contains - */ - public long size(final Object sourceStage) { - final long t = this.top.get(); - final long b = this.bottom; - final long size = b - t; - System.out.println("sourceStage=" + sourceStage + ", " + "bottom: " + this.bottom); - return size; - } - - @Override - public String toString() { - return this.activeArray.toString(); - } - -} diff --git a/src/main/java/teetime/util/concurrent/workstealing/alternative/CircularWorkStealingDequeWithSentinel.java b/src/main/java/teetime/util/concurrent/workstealing/alternative/CircularWorkStealingDequeWithSentinel.java deleted file mode 100644 index 3eabf1f6824eaca45bee788a21a8a13bf1fa3913..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/util/concurrent/workstealing/alternative/CircularWorkStealingDequeWithSentinel.java +++ /dev/null @@ -1,201 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.concurrent.workstealing.alternative; - -import java.util.concurrent.atomic.AtomicLong; - -import teetime.util.concurrent.workstealing.CircularArray; - -/** - * - * @author Christian Wulf - * - * @see "Dynamic Circular WorkStealing Deque" - * - * @since 1.10 - */ -public final class CircularWorkStealingDequeWithSentinel<T> { - - public static enum State { - REGULAR, EMPTY, ABORT - } - - public static class ReturnValue<T> { - private final State state; - private final T value; - - public ReturnValue(final State state, final T value) { - this.state = state; - this.value = value; - } - - public T getValue() { - return this.value; - } - - public State getState() { - return this.state; - } - } - - private static final long LOG_INITIAL_SIZE = 10; - - private volatile long bottom = 0; - // private volatile long top = 0; - private final AtomicLong top = new AtomicLong(); - private volatile CircularArray<T> activeArray = new CircularArray<T>(LOG_INITIAL_SIZE); - - private boolean casTop(final long oldVal, final long newVal) { - // boolean preCond; - // synchronized (this) { - // preCond = (this.top == oldVal); - // if (preCond) { - // this.top = newVal; - // } - // } - // return preCond; - return this.top.compareAndSet(oldVal, newVal); - } - - public void pushBottom(final T o) { - final long b = this.bottom; - final long t = this.top.get(); - CircularArray<T> a = this.activeArray; - final long size = b - t; - if (size > (a.getCapacity() - 1)) { - a = a.grow(b, t); - this.activeArray = a; - } - a.put(b, o); - this.bottom = b + 1; - } - - /** - * - * @return - * <ul> - * <li><code>empty()</code> if the deque contains no elements, - * <li><i>the latest element</i> otherwise - * </ul> - */ - public ReturnValue<T> popBottom() { - long b = this.bottom; - final CircularArray<T> a = this.activeArray; - b = b - 1; - this.bottom = b; - final long t = this.top.get(); - final long size = b - t; - if (size < 0) { - this.bottom = t; - return new ReturnValue<T>(State.EMPTY, null); - } - ReturnValue<T> o = new ReturnValue<T>(State.REGULAR, a.get(b)); - if (size > 0) { - this.perhapsShrink(b, t); - return o; - } - if (!this.casTop(t, t + 1)) { - o = new ReturnValue<T>(State.EMPTY, null); - } - this.bottom = t + 1; - return o; - } - - void perhapsShrink(final long b, final long t) { - long temp = t; - final CircularArray<T> a = this.activeArray; - if ((b - temp) < (a.getCapacity() / 4)) { - final CircularArray<T> aa = a.shrink(b, temp); - this.activeArray = aa; - final long ss = aa.getCapacity(); - this.bottom = b + ss; - temp = this.top.get(); - if (!this.casTop(temp, temp + ss)) { - this.bottom = b; - // a.free(); - } - } - } - - /** - * Tries to steal (return & remove) the oldest element from this deque. - * - * @return - * <ul> - * <li><code>empty()</code> if the deque contains no elements, - * <li><code>abort()</code> if the deque is currently being stolen by another thread, - * <li><i>the oldest element</i> otherwise - * </ul> - */ - public ReturnValue<T> steal() { - final long t = this.top.get(); - final CircularArray<T> oldArr = this.activeArray; - final long b = this.bottom; - final CircularArray<T> a = this.activeArray; - final long size = b - t; - if (size <= 0) { - return new ReturnValue<T>(State.EMPTY, null); - } - if ((size % a.getCapacity()) == 0) { - if ((oldArr == a) && (t == this.top.get())) { - return new ReturnValue<T>(State.EMPTY, null); - } else { - return new ReturnValue<T>(State.ABORT, null); - } - } - final ReturnValue<T> o = new ReturnValue<T>(State.REGULAR, a.get(t)); - if (!this.casTop(t, t + 1)) { - return new ReturnValue<T>(State.ABORT, null); - } - return o; - } - - /** - * For debugging purposes - * - * @return but does not remove the bottom element from this deque - */ - public T readBottom() { - final long b = this.bottom; - final CircularArray<T> a = this.activeArray; - final T o = a.get(b); - return o; - } - - // bottom: 4093 - // bottom: 66429 - // bottom: 29993 - // bottom: 29992 - // - // - // bottom: 4093 - // bottom: 66429 - // bottom: 30008 - // bottom: 30007 - - /** - * For debugging purposes - * - * @return the number of elements this deque contains - */ - public long size(final Object sourceStage) { - final long t = this.top.get(); - final long b = this.bottom; - final long size = b - t; - System.out.println("sourceStage=" + sourceStage + ", " + "bottom: " + this.bottom); - return size; - } -} diff --git a/src/main/java/teetime/util/concurrent/workstealing/alternative/CircularWorkStealingDequeWithThreadLocalSentinel.java b/src/main/java/teetime/util/concurrent/workstealing/alternative/CircularWorkStealingDequeWithThreadLocalSentinel.java deleted file mode 100644 index 5cec666e37a44423a4e2aa1d580fd370f14e2977..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/util/concurrent/workstealing/alternative/CircularWorkStealingDequeWithThreadLocalSentinel.java +++ /dev/null @@ -1,225 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.concurrent.workstealing.alternative; - -import java.util.concurrent.atomic.AtomicLong; - -import teetime.util.concurrent.workstealing.CircularArray; - -/** - * - * @author Christian Wulf - * - * @see "Dynamic Circular WorkStealing Deque" - * - * @since 1.10 - */ -public final class CircularWorkStealingDequeWithThreadLocalSentinel<T> { - - public static enum State { - REGULAR, EMPTY, ABORT - } - - public static class ReturnValue<T> { - private State state; - private T value; - - public State getState() { - return this.state; - } - - public T getValue() { - return this.value; - } - - public ReturnValue<T> setState(final State state) { - this.state = state; - return this; - } - - public ReturnValue<T> setStateAndValue(final State state, final T value) { - this.state = state; - this.value = value; - return this; - } - } - - private final ThreadLocal<ReturnValue<T>> returnValue = new ThreadLocal<ReturnValue<T>>(); - - private static final long LOG_INITIAL_SIZE = 10; - - private volatile long bottom = 0; - // private volatile long top = 0; - private final AtomicLong top = new AtomicLong(); - private volatile CircularArray<T> activeArray = new CircularArray<T>(LOG_INITIAL_SIZE); - - public CircularWorkStealingDequeWithThreadLocalSentinel() { - this.returnValue.set(new ReturnValue<T>()); - } - - private boolean casTop(final long oldVal, final long newVal) { - // boolean preCond; - // synchronized (this) { - // preCond = (this.top == oldVal); - // if (preCond) { - // this.top = newVal; - // } - // } - // return preCond; - return this.top.compareAndSet(oldVal, newVal); - } - - public void pushBottom(final T o) { - final long b = this.bottom; - final long t = this.top.get(); - CircularArray<T> a = this.activeArray; - final long size = b - t; - if (size > (a.getCapacity() - 1)) { - a = a.grow(b, t); - this.activeArray = a; - } - a.put(b, o); - this.bottom = b + 1; - } - - /** - * - * @return - * <ul> - * <li><code>empty()</code> if the deque contains no elements, - * <li><i>the latest element</i> otherwise - * </ul> - */ - public ReturnValue<T> popBottom() { - long b = this.bottom; - final CircularArray<T> a = this.activeArray; - b = b - 1; - this.bottom = b; - final long t = this.top.get(); - final long size = b - t; - if (size < 0) { - this.bottom = t; - return this.empty(); - } - ReturnValue<T> o = this.regular(a.get(b)); - if (size > 0) { - this.perhapsShrink(b, t); - return o; - } - if (!this.casTop(t, t + 1)) { - o = this.empty(); - } - this.bottom = t + 1; - return o; - } - - void perhapsShrink(final long b, final long t) { - long temp = t; - final CircularArray<T> a = this.activeArray; - if ((b - temp) < (a.getCapacity() / 4)) { - final CircularArray<T> aa = a.shrink(b, temp); - this.activeArray = aa; - final long ss = aa.getCapacity(); - this.bottom = b + ss; - temp = this.top.get(); - if (!this.casTop(temp, temp + ss)) { - this.bottom = b; - // a.free(); - } - } - } - - /** - * Tries to steal (return & remove) the oldest element from this deque. - * - * @return - * <ul> - * <li><code>empty()</code> if the deque contains no elements, - * <li><code>abort()</code> if the deque is currently being stolen by another thread, - * <li><i>the oldest element</i> otherwise - * </ul> - */ - public ReturnValue<T> steal() { - final long t = this.top.get(); - final CircularArray<T> oldArr = this.activeArray; - final long b = this.bottom; - final CircularArray<T> a = this.activeArray; - final long size = b - t; - if (size <= 0) { - return this.empty(); - } - if ((size % a.getCapacity()) == 0) { - if ((oldArr == a) && (t == this.top.get())) { - return this.empty(); - } else { - return this.abort(); - } - } - final ReturnValue<T> o = this.regular(a.get(t)); - if (!this.casTop(t, t + 1)) { - return this.abort(); - } - return o; - } - - private ReturnValue<T> empty() { - return this.returnValue.get().setState(State.EMPTY); - } - - private ReturnValue<T> abort() { - return this.returnValue.get().setState(State.ABORT); - } - - private ReturnValue<T> regular(final T value) { - return this.returnValue.get().setStateAndValue(State.REGULAR, value); - } - - /** - * For debugging purposes - * - * @return but does not remove the bottom element from this deque - */ - public T readBottom() { - final long b = this.bottom; - final CircularArray<T> a = this.activeArray; - final T o = a.get(b); - return o; - } - - // bottom: 4093 - // bottom: 66429 - // bottom: 29993 - // bottom: 29992 - // - // - // bottom: 4093 - // bottom: 66429 - // bottom: 30008 - // bottom: 30007 - - /** - * For debugging purposes - * - * @return the number of elements this deque contains - */ - public long size(final Object sourceStage) { - final long t = this.top.get(); - final long b = this.bottom; - final long size = b - t; - System.out.println("sourceStage=" + sourceStage + ", " + "bottom: " + this.bottom); - return size; - } -} diff --git a/src/main/java/teetime/util/concurrent/workstealing/alternative/ExceptionalCircularWorkStealingDeque.java b/src/main/java/teetime/util/concurrent/workstealing/alternative/ExceptionalCircularWorkStealingDeque.java deleted file mode 100644 index 4dc084bf7c8a2ec5a726941e70928f0cdf088ab1..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/util/concurrent/workstealing/alternative/ExceptionalCircularWorkStealingDeque.java +++ /dev/null @@ -1,187 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.concurrent.workstealing.alternative; - -import java.util.concurrent.atomic.AtomicLong; - -import teetime.util.concurrent.workstealing.CircularArray; -import teetime.util.concurrent.workstealing.exception.DequeIsEmptyException; -import teetime.util.concurrent.workstealing.exception.OperationAbortedException; - -/** - * - * @author Christian Wulf - * - * @see "Dynamic Circular WorkStealing Deque" - * - * @since 1.10 - */ -public final class ExceptionalCircularWorkStealingDeque<T> { - - public static final DequeIsEmptyException DEQUE_IS_EMPTY_EXCEPTION = new DequeIsEmptyException(); - - public static final OperationAbortedException OPERATION_ABORTED_EXCEPTION = new OperationAbortedException(); - - private static final long LOG_INITIAL_SIZE = 10; - - private volatile long bottom = 0; - // private volatile long top = 0; - private final AtomicLong top = new AtomicLong(); - private volatile CircularArray<T> activeArray = new CircularArray<T>(LOG_INITIAL_SIZE); - - private boolean casTop(final long oldVal, final long newVal) { - // boolean preCond; - // synchronized (this) { - // preCond = (this.top == oldVal); - // if (preCond) { - // this.top = newVal; - // } - // } - // return preCond; - return this.top.compareAndSet(oldVal, newVal); - } - - public void pushBottom(final T o) { - final long b = this.bottom; - final long t = this.top.get(); - CircularArray<T> a = this.activeArray; - final long size = b - t; - if (size > (a.getCapacity() - 1)) { - a = a.grow(b, t); - this.activeArray = a; - } - a.put(b, o); - this.bottom = b + 1; - } - - /** - * - * @return <ul> - * <li><code>EMPTY</code> if the deque contains no elements, - * <li><i>the latest element</i> otherwise - * </ul> - * @throws DequeIsEmptyException - */ - public T popBottom() throws DequeIsEmptyException { - long b = this.bottom; - final CircularArray<T> a = this.activeArray; - b = b - 1; - this.bottom = b; - final long t = this.top.get(); - final long size = b - t; - if (size < 0) { - this.bottom = t; - throw DEQUE_IS_EMPTY_EXCEPTION; - } - final T o = a.get(b); - if (size > 0) { - this.perhapsShrink(b, t); - return o; - } - final boolean success = this.casTop(t, t + 1); - this.bottom = t + 1; - if (!success) { - throw DEQUE_IS_EMPTY_EXCEPTION; - } - return o; - } - - void perhapsShrink(final long b, final long t) { - long temp = t; - final CircularArray<T> a = this.activeArray; - if ((b - temp) < (a.getCapacity() / 4)) { - final CircularArray<T> aa = a.shrink(b, temp); - this.activeArray = aa; - final long ss = aa.getCapacity(); - this.bottom = b + ss; - temp = this.top.get(); - if (!this.casTop(temp, temp + ss)) { - this.bottom = b; - // a.free(); - } - } - } - - /** - * Tries to steal (return & remove) the oldest element from this deque. - * - * @return <ul> - * <li><code>EMPTY</code> if the deque contains no elements, - * <li><code>ABORT</code> if the deque is currently being stolen by another thread, - * <li><i>the oldest element</i> otherwise - * </ul> - * @throws DequeIsEmptyException - * @throws OperationAbortedException - */ - public T steal() throws DequeIsEmptyException, OperationAbortedException { - final long t = this.top.get(); - final CircularArray<T> oldArr = this.activeArray; - final long b = this.bottom; - final CircularArray<T> a = this.activeArray; - final long size = b - t; - if (size <= 0) { - throw DEQUE_IS_EMPTY_EXCEPTION; - } - if ((size % a.getCapacity()) == 0) { - if ((oldArr == a) && (t == this.top.get())) { - throw DEQUE_IS_EMPTY_EXCEPTION; - } else { - throw OPERATION_ABORTED_EXCEPTION; - } - } - final T o = a.get(t); - if (!this.casTop(t, t + 1)) { - throw OPERATION_ABORTED_EXCEPTION; - } - return o; - } - - /** - * For debugging purposes - * - * @return but does not remove the bottom element from this deque - */ - public T readBottom() { - final long b = this.bottom; - final CircularArray<T> a = this.activeArray; - final T o = a.get(b); - return o; - } - - // bottom: 4093 - // bottom: 66429 - // bottom: 29993 - // bottom: 29992 - // - // - // bottom: 4093 - // bottom: 66429 - // bottom: 30008 - // bottom: 30007 - - /** - * For debugging purposes - * - * @return the number of elements this deque contains - */ - public long size(final Object sourceStage) { - final long t = this.top.get(); - final long b = this.bottom; - final long size = b - t; - System.out.println("sourceStage=" + sourceStage + ", " + "bottom: " + this.bottom); - return size; - } -} diff --git a/src/main/java/teetime/util/concurrent/workstealing/alternative/UntypedCircularWorkStealingDeque.java b/src/main/java/teetime/util/concurrent/workstealing/alternative/UntypedCircularWorkStealingDeque.java deleted file mode 100644 index e5518e7c8db6bfc80dbbf5f3a803ba1e3747cadb..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/util/concurrent/workstealing/alternative/UntypedCircularWorkStealingDeque.java +++ /dev/null @@ -1,181 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.concurrent.workstealing.alternative; - -import java.util.concurrent.atomic.AtomicLong; - -import teetime.util.concurrent.workstealing.CircularArray; - -/** - * - * @author Christian Wulf - * - * @see "Dynamic Circular WorkStealing Deque" - * - * @since 1.10 - */ -public final class UntypedCircularWorkStealingDeque { - public static final Object EMPTY = new Object(); - public static final Object ABORT = new Object(); - - private static final long LOG_INITIAL_SIZE = 10; - - private volatile long bottom = 0; - // private volatile long top = 0; - private final AtomicLong top = new AtomicLong(); - private volatile CircularArray<Object> activeArray = new CircularArray<Object>(LOG_INITIAL_SIZE); - - private boolean casTop(final long oldVal, final long newVal) { - // boolean preCond; - // synchronized (this) { - // preCond = (this.top == oldVal); - // if (preCond) { - // this.top = newVal; - // } - // } - // return preCond; - return this.top.compareAndSet(oldVal, newVal); - } - - public void pushBottom(final Object o) { - final long b = this.bottom; - final long t = this.top.get(); - CircularArray<Object> a = this.activeArray; - final long size = b - t; - if (size > (a.getCapacity() - 1)) { - a = a.grow(b, t); - this.activeArray = a; - } - a.put(b, o); - this.bottom = b + 1; - } - - /** - * - * @return - * <ul> - * <li><code>EMPTY</code> if the deque contains no elements, - * <li><i>the latest element</i> otherwise - * </ul> - */ - public Object popBottom() { - long b = this.bottom; - final CircularArray<Object> a = this.activeArray; - b = b - 1; - this.bottom = b; // reserve (avoid stealing) the current bottom element - final long t = this.top.get(); - final long size = b - t; - if (size < 0) { - this.bottom = t; - return EMPTY; - } - Object o = a.get(b); - if (size > 0) { - this.perhapsShrink(b, t); - return o; - } - if (!this.casTop(t, t + 1)) { - o = EMPTY; - } - this.bottom = t + 1; - return o; - } - - void perhapsShrink(final long b, final long t) { - long temp = t; - final CircularArray<Object> a = this.activeArray; - if ((b - temp) < (a.getCapacity() / 4)) { - final CircularArray<Object> aa = a.shrink(b, temp); - this.activeArray = aa; - final long ss = aa.getCapacity(); - this.bottom = b + ss; - temp = this.top.get(); - if (!this.casTop(temp, temp + ss)) { - this.bottom = b; - // a.free(); - } - } - } - - /** - * Tries to steal (return & remove) the oldest element from this deque. - * - * @return - * <ul> - * <li><code>EMPTY</code> if the deque contains no elements, - * <li><code>ABORT</code> if the deque is currently being stolen by another thread, - * <li><i>the oldest element</i> otherwise - * </ul> - */ - public Object steal() { - final long t = this.top.get(); - final CircularArray<Object> oldArr = this.activeArray; - final long b = this.bottom; - final CircularArray<Object> a = this.activeArray; - final long size = b - t; - if (size <= 0) { - return EMPTY; - } - if ((size % a.getCapacity()) == 0) { - if ((oldArr == a) && (t == this.top.get())) { - return EMPTY; - } else { - return ABORT; - } - } - final Object o = a.get(t); - if (!this.casTop(t, t + 1)) { - return ABORT; - } - return o; - } - - /** - * For debugging purposes - * - * @return but does not remove the bottom element from this deque - */ - public Object readBottom() { - final long b = this.bottom; - final CircularArray<Object> a = this.activeArray; - final Object o = a.get(b); - return o; - } - - // bottom: 4093 - // bottom: 66429 - // bottom: 29993 - // bottom: 29992 - // - // - // bottom: 4093 - // bottom: 66429 - // bottom: 30008 - // bottom: 30007 - - /** - * For debugging purposes - * - * @return the number of elements this deque contains - */ - public long size(final Object sourceStage) { - final long t = this.top.get(); - final long b = this.bottom; - final long size = b - t; - System.out.println("sourceStage=" + sourceStage + ", " + "bottom: " + this.bottom); - return size; - } -} diff --git a/src/main/java/teetime/util/concurrent/workstealing/alternative/UntypedExceptionalCircularWorkStealingDeque.java b/src/main/java/teetime/util/concurrent/workstealing/alternative/UntypedExceptionalCircularWorkStealingDeque.java deleted file mode 100644 index f5d37b94e7f6d652dd098e282e5ad19e1499f32d..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/util/concurrent/workstealing/alternative/UntypedExceptionalCircularWorkStealingDeque.java +++ /dev/null @@ -1,189 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.concurrent.workstealing.alternative; - -import java.util.concurrent.atomic.AtomicLong; - -import teetime.util.concurrent.workstealing.CircularArray; -import teetime.util.concurrent.workstealing.exception.DequeIsEmptyException; -import teetime.util.concurrent.workstealing.exception.DequePopException; -import teetime.util.concurrent.workstealing.exception.OperationAbortedException; - -/** - * - * @author Christian Wulf - * - * @see "Dynamic Circular WorkStealing Deque" - * - * @since 1.10 - */ -public final class UntypedExceptionalCircularWorkStealingDeque { - - public static final DequeIsEmptyException DEQUE_IS_EMPTY_EXCEPTION = new DequeIsEmptyException(); - - public static final OperationAbortedException OPERATION_ABORTED_EXCEPTION = new OperationAbortedException(); - - private static final long LOG_INITIAL_SIZE = 10; - - private volatile long bottom = 0; - // private volatile long top = 0; - private final AtomicLong top = new AtomicLong(); - private volatile CircularArray<Object> activeArray = new CircularArray<Object>(LOG_INITIAL_SIZE); - - private boolean casTop(final long oldVal, final long newVal) { - // boolean preCond; - // synchronized (this) { - // preCond = (this.top == oldVal); - // if (preCond) { - // this.top = newVal; - // } - // } - // return preCond; - return this.top.compareAndSet(oldVal, newVal); - } - - public void pushBottom(final Object o) { - final long b = this.bottom; - final long t = this.top.get(); - CircularArray<Object> a = this.activeArray; - final long size = b - t; - if (size > (a.getCapacity() - 1)) { - a = a.grow(b, t); - this.activeArray = a; - } - a.put(b, o); - this.bottom = b + 1; - } - - /** - * - * @return - * <ul> - * <li><code>EMPTY</code> if the deque contains no elements, - * <li><i>the latest element</i> otherwise - * </ul> - * @throws DequeIsEmptyException - */ - public Object popBottom() throws DequePopException { - long b = this.bottom; - final CircularArray<Object> a = this.activeArray; - b = b - 1; - this.bottom = b; - final long t = this.top.get(); - final long size = b - t; - if (size < 0) { - this.bottom = t; - throw DEQUE_IS_EMPTY_EXCEPTION; - } - final Object o = a.get(b); - if (size > 0) { - this.perhapsShrink(b, t); - return o; - } - final boolean success = this.casTop(t, t + 1); - this.bottom = t + 1; - if (!success) { - throw DEQUE_IS_EMPTY_EXCEPTION; - } - return o; - } - - void perhapsShrink(final long b, final long t) { - long temp = t; - final CircularArray<Object> a = this.activeArray; - if ((b - temp) < (a.getCapacity() / 4)) { - final CircularArray<Object> aa = a.shrink(b, temp); - this.activeArray = aa; - final long ss = aa.getCapacity(); - this.bottom = b + ss; - temp = this.top.get(); - if (!this.casTop(temp, temp + ss)) { - this.bottom = b; - // a.free(); - } - } - } - - /** - * Tries to steal (return & remove) the oldest element from this deque. - * - * @return - * <ul> - * <li><code>EMPTY</code> if the deque contains no elements, - * <li><code>ABORT</code> if the deque is currently being stolen by another thread, - * <li><i>the oldest element</i> otherwise - * </ul> - * @throws DequePopException - */ - public Object steal() throws DequePopException { - final long t = this.top.get(); - final CircularArray<Object> oldArr = this.activeArray; - final long b = this.bottom; - final CircularArray<Object> a = this.activeArray; - final long size = b - t; - if (size <= 0) { - throw DEQUE_IS_EMPTY_EXCEPTION; - } - if ((size % a.getCapacity()) == 0) { - if ((oldArr == a) && (t == this.top.get())) { - throw DEQUE_IS_EMPTY_EXCEPTION; - } else { - throw OPERATION_ABORTED_EXCEPTION; - } - } - final Object o = a.get(t); - if (!this.casTop(t, t + 1)) { - throw OPERATION_ABORTED_EXCEPTION; - } - return o; - } - - /** - * For debugging purposes - * - * @return but does not remove the bottom element from this deque - */ - public Object readBottom() { - final long b = this.bottom; - final CircularArray<Object> a = this.activeArray; - final Object o = a.get(b); - return o; - } - - // bottom: 4093 - // bottom: 66429 - // bottom: 29993 - // bottom: 29992 - // - // - // bottom: 4093 - // bottom: 66429 - // bottom: 30008 - // bottom: 30007 - - /** - * For debugging purposes - * - * @return the number of elements this deque contains - */ - public long size(final Object sourceStage) { - final long t = this.top.get(); - final long b = this.bottom; - final long size = b - t; - System.out.println("sourceStage=" + sourceStage + ", " + "bottom: " + this.bottom); - return size; - } -} diff --git a/src/main/java/teetime/util/concurrent/workstealing/exception/DequeIsEmptyException.java b/src/main/java/teetime/util/concurrent/workstealing/exception/DequeIsEmptyException.java deleted file mode 100644 index 08c58f6147e2045330d084682de060a2004e19e4..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/util/concurrent/workstealing/exception/DequeIsEmptyException.java +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.concurrent.workstealing.exception; - -public final class DequeIsEmptyException extends DequePopException { - private static final long serialVersionUID = -6685406255103741724L; -} diff --git a/src/main/java/teetime/util/concurrent/workstealing/exception/DequePopException.java b/src/main/java/teetime/util/concurrent/workstealing/exception/DequePopException.java deleted file mode 100644 index e4ff1860c00ad1cc958298720074e981d8923f40..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/util/concurrent/workstealing/exception/DequePopException.java +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.concurrent.workstealing.exception; - -import teetime.util.StacklessException; - -public class DequePopException extends StacklessException { - private static final long serialVersionUID = 496512683536868149L; - -} diff --git a/src/main/java/teetime/util/concurrent/workstealing/exception/OperationAbortedException.java b/src/main/java/teetime/util/concurrent/workstealing/exception/OperationAbortedException.java deleted file mode 100644 index f814ac5fda2919eb4f32d9cb39f0edd77e790a57..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/util/concurrent/workstealing/exception/OperationAbortedException.java +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.concurrent.workstealing.exception; - -public final class OperationAbortedException extends DequePopException { - private static final long serialVersionUID = 2983001853326344073L; -} diff --git a/src/main/java/teetime/util/list/CommittableResizableArrayQueue.java b/src/main/java/teetime/util/list/CommittableResizableArrayQueue.java index 4349a2ae49a07462c6278948c91d8e70a7039cd2..709d22d7d76c14c307a68d3f219719b99609afd5 100644 --- a/src/main/java/teetime/util/list/CommittableResizableArrayQueue.java +++ b/src/main/java/teetime/util/list/CommittableResizableArrayQueue.java @@ -51,16 +51,16 @@ public final class CommittableResizableArrayQueue<T> implements CommittableQueue @Override public T removeFromHeadUncommitted() { + T element = this.get(--this.lastFreeIndexUncommitted); // if (this.capacity() > this.MIN_CAPACITY && this.lastFreeIndexUncommitted < this.capacity() / 2) { // TODO uncomment // this.shrink(); // } - T element = this.get(--this.lastFreeIndexUncommitted); return element; } @Override + // TODO set elements to null to help the gc public void commit() { - // TODO set elements to null to help the gc this.lastFreeIndex = this.lastFreeIndexUncommitted; } @@ -109,10 +109,10 @@ public final class CommittableResizableArrayQueue<T> implements CommittableQueue } private final void copyArray(final T[] elements, final T[] newElements) { + System.arraycopy(elements, 0, newElements, 0, this.lastFreeIndexUncommitted + 1); // for (int i = 0; i < this.lastFreeIndexUncommitted; i++) { // newElements[i] = elements[i]; // } - System.arraycopy(elements, 0, newElements, 0, this.lastFreeIndexUncommitted + 1); } private final void put(final int index, final T element) { diff --git a/src/main/java/teetime/util/list/ListContainerPool.java b/src/main/java/teetime/util/list/ListContainerPool.java index d470a3ef1314a30407e4250511ffb365c6288d2d..8d1d7f943106d73b16433a5613a30cf40655bab6 100644 --- a/src/main/java/teetime/util/list/ListContainerPool.java +++ b/src/main/java/teetime/util/list/ListContainerPool.java @@ -20,7 +20,7 @@ import java.util.List; public final class ListContainerPool<T> implements ObjectPool<ListContainer<T>> { - private final List<ListContainer<T>> pool = new ArrayList<ListContainer<T>>(); + private final List<ListContainer<T>> pool = new ArrayList<ListContainer<T>>(); // NOPMD public ListContainerPool(int initialPoolSize) { while (initialPoolSize-- > 0) { diff --git a/src/main/java/teetime/util/test/eval/BucketTimingsReader.java b/src/main/java/teetime/util/test/eval/BucketTimingsReader.java deleted file mode 100644 index dcfcd8c72bd1e67cd84c6a94af6e3d471cc08927..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/util/test/eval/BucketTimingsReader.java +++ /dev/null @@ -1,74 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.test.eval; - -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.base.Charsets; -import com.google.common.io.CharSource; -import com.google.common.io.Files; - -public final class BucketTimingsReader { - - private static final Logger LOGGER = LoggerFactory.getLogger(BucketTimingsReader.class); - - private BucketTimingsReader() {} - - public static void main(final String[] args) throws IOException { - final String fileName = args[0]; - - final Long[] currentTimings = new Long[10000]; - int processedLines = 0; - final List<Long> buckets = new LinkedList<Long>(); - - LOGGER.trace("Reading " + fileName); - final CharSource charSource = Files.asCharSource(new File(fileName), Charsets.UTF_8); - final BufferedReader bufferedStream = charSource.openBufferedStream(); - String line; - while (null != (line = bufferedStream.readLine())) { - final String[] strings = line.split(";"); - final Long timing = new Long(strings[1]); - currentTimings[processedLines] = timing; - processedLines++; - if (currentTimings.length == processedLines) { - // Long aggregatedTimings = StatisticsUtil.calculateQuintiles(Arrays.asList(currentTimings)).get(0.5); - final Long aggregatedTimings = StatisticsUtil.calculateAverage(Arrays.asList(currentTimings)); - buckets.add(aggregatedTimings); - processedLines = 0; - } - } - - LOGGER.trace("#buckets: " + buckets.size()); - - final List<Long> durationsInNs = buckets.subList(buckets.size() / 2, buckets.size()); - - LOGGER.trace("Calculating quantiles..."); - final Map<Double, Long> quintiles = StatisticsUtil.calculateQuintiles(durationsInNs); - LOGGER.info(StatisticsUtil.getQuantilesString(quintiles)); - - final long confidenceWidth = StatisticsUtil.calculateConfidenceWidth(durationsInNs); - LOGGER.info("Confidence width: " + confidenceWidth); - } -} diff --git a/src/main/java/teetime/util/test/eval/MathUtil.java b/src/main/java/teetime/util/test/eval/MathUtil.java deleted file mode 100644 index b42f18e237d63ce813d6d115f9e9ee0d42822dc4..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/util/test/eval/MathUtil.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.test.eval; - -import java.util.List; - -/** - * @author Christian Wulf - * - * @since 1.10 - */ -public final class MathUtil { - - private MathUtil() { - // utility class - } - - public static double getVariance(final List<Long> values, final long avgValue) { - double sum = 0; - for (final long val : values) { - final long diff = val - avgValue; - sum += (diff * diff) / (values.size() - 1); - } - return sum; - } - - public static double getConfidenceWidth(final double z, final double variance, final long n) { - return z * Math.sqrt(variance / n); - } - - public static double getConfidenceWidth(final double z, final List<Long> values, final long avgValue) { - final double variance = MathUtil.getVariance(values, avgValue); - final double confidenceWidth = MathUtil.getConfidenceWidth(z, variance, values.size()); - return confidenceWidth; - } -} diff --git a/src/main/java/teetime/util/test/eval/PerformanceResult.java b/src/main/java/teetime/util/test/eval/PerformanceResult.java deleted file mode 100644 index 41e7443cef29e00dbaa1a4c0df39ef42680ee9ca..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/util/test/eval/PerformanceResult.java +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.test.eval; - -import java.util.Map; - -public class PerformanceResult { - - public long overallDurationInNs; - public long sumInNs; - public Map<Double, Long> quantiles; - public long avgDurInNs; - public long confidenceWidthInNs; - - public PerformanceResult() {} - - @Override - public String toString() { - final StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append("overallDurationInNs: "); - stringBuilder.append(this.overallDurationInNs); - stringBuilder.append("\n"); - - stringBuilder.append("sumInNs: "); - stringBuilder.append(this.sumInNs); - stringBuilder.append("\n"); - - stringBuilder.append("avgDurInNs: "); - stringBuilder.append(this.avgDurInNs); - stringBuilder.append("\n"); - - stringBuilder.append("confidenceWidthInNs: "); - stringBuilder.append(this.confidenceWidthInNs); - stringBuilder.append("\n"); - - stringBuilder.append(StatisticsUtil.getQuantilesString(this.quantiles)); - - return stringBuilder.toString(); - } -} diff --git a/src/main/java/teetime/util/test/eval/StatisticsUtil.java b/src/main/java/teetime/util/test/eval/StatisticsUtil.java deleted file mode 100644 index c49c187d70189c996e1fab7f9701545c21c665ff..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/util/test/eval/StatisticsUtil.java +++ /dev/null @@ -1,125 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.test.eval; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.concurrent.TimeUnit; - -import teetime.util.TimestampObject; - -/** - * @author Christian Wulf - * - * @since 1.10 - */ -public final class StatisticsUtil { - - /** - * @since 1.10 - */ - private StatisticsUtil() { - // utility class - } - - public static PerformanceResult computeStatistics(final long overallDurationInNs, final List<TimestampObject> timestampObjects) { - final PerformanceResult performanceResult = new PerformanceResult(); - - performanceResult.overallDurationInNs = overallDurationInNs; - - final List<Long> sortedDurationsInNs = new ArrayList<Long>(timestampObjects.size() / 2); - long sumInNs = 0; - for (int i = timestampObjects.size() / 2; i < timestampObjects.size(); i++) { - final TimestampObject timestampObject = timestampObjects.get(i); - final long durationInNs = timestampObject.getStopTimestamp() - timestampObject.getStartTimestamp(); - // sortedDurationsInNs.set(i - (timestampObjects.size() / 2), durationInNs); - sortedDurationsInNs.add(durationInNs); - sumInNs += durationInNs; - } - - performanceResult.sumInNs = sumInNs; - - final Map<Double, Long> quintileValues = StatisticsUtil.calculateQuintiles(sortedDurationsInNs); - performanceResult.quantiles = quintileValues; - - final long avgDurInNs = sumInNs / (timestampObjects.size() / 2); - performanceResult.avgDurInNs = avgDurInNs; - - final long confidenceWidthInNs = StatisticsUtil.calculateConfidenceWidth(sortedDurationsInNs, avgDurInNs); - performanceResult.confidenceWidthInNs = confidenceWidthInNs; - - return performanceResult; - } - - public static String getQuantilesString(final Map<Double, Long> quantilesValues) { - final StringBuilder builder = new StringBuilder(); - for (final Entry<Double, Long> entry : quantilesValues.entrySet()) { - final String quantile = (entry.getKey() * 100) + " % : " + TimeUnit.NANOSECONDS.toNanos(entry.getValue()) + " ns"; - builder.append(quantile); - builder.append("\n"); - } - return builder.toString(); - } - - public static long calculateConfidenceWidth(final List<Long> durations, final long avgDurInNs) { - final double z = 1.96; // for alpha = 0.05 - final double variance = MathUtil.getVariance(durations, avgDurInNs); - final long confidenceWidthInNs = (long) MathUtil.getConfidenceWidth(z, variance, durations.size()); - return confidenceWidthInNs; - } - - public static long calculateConfidenceWidth(final List<Long> durations) { - return StatisticsUtil.calculateConfidenceWidth(durations, StatisticsUtil.calculateAverage(durations)); - } - - public static long calculateAverage(final List<Long> durations) { - long sumNs = 0; - for (final Long value : durations) { - sumNs += value; - } - - return sumNs / durations.size(); - } - - public static Map<Double, Long> calculateQuintiles(final List<Long> durationsInNs) { - Collections.sort(durationsInNs); - - final Map<Double, Long> quintileValues = new LinkedHashMap<Double, Long>(); - final double[] quintiles = { 0.00, 0.25, 0.50, 0.75, 1.00 }; - for (final double quintile : quintiles) { - final int index = (int) ((durationsInNs.size() - 1) * quintile); - quintileValues.put(quintile, durationsInNs.get(index)); - } - return quintileValues; - } - - public static void removeLeadingZeroThroughputs(final List<Long> throughputs) { - final Iterator<Long> iterator = throughputs.iterator(); - while (iterator.hasNext()) { - if (iterator.next() == 0) { - iterator.remove(); - } else { - break; - } - } - } - -} diff --git a/src/main/java/teetime/util/test/framework/AbstractProfiledPerformanceAssertion.java b/src/main/java/teetime/util/test/framework/AbstractProfiledPerformanceAssertion.java deleted file mode 100644 index 60afa855fee84d54148bc44569b5ff2e9ccbd1f1..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/util/test/framework/AbstractProfiledPerformanceAssertion.java +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.test.framework; - -public abstract class AbstractProfiledPerformanceAssertion { - - public abstract String getCorrespondingPerformanceProfile(); - - public abstract void check(); -} diff --git a/src/main/java/teetime/util/test/framework/MeasurementRepository.java b/src/main/java/teetime/util/test/framework/MeasurementRepository.java deleted file mode 100644 index be3552b876a1a3317d91cadae0576d941e8fed43..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/util/test/framework/MeasurementRepository.java +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.test.framework; - -import java.util.HashMap; -import java.util.Map; - -import teetime.util.test.eval.PerformanceResult; - -public class MeasurementRepository { - - public final Map<String, PerformanceResult> performanceResults = new HashMap<String, PerformanceResult>(); - - public MeasurementRepository() {} - - public static final String buildTestMethodIdentifier(final Class<?> testClass, final String methodName) { - return testClass.getName() + "(" + methodName + ")"; - } -} diff --git a/src/main/java/teetime/util/test/framework/PerformanceCheckProfileRepository.java b/src/main/java/teetime/util/test/framework/PerformanceCheckProfileRepository.java deleted file mode 100644 index a3ee2c7195b066e6695784ed2d3d4ce0b91b9868..0000000000000000000000000000000000000000 --- a/src/main/java/teetime/util/test/framework/PerformanceCheckProfileRepository.java +++ /dev/null @@ -1,73 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.test.framework; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.HashMap; -import java.util.Map; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class PerformanceCheckProfileRepository { - - private static final Logger LOGGER = LoggerFactory.getLogger(PerformanceCheckProfileRepository.class); - - public static final PerformanceCheckProfileRepository INSTANCE = new PerformanceCheckProfileRepository(); - - private final Map<Class<?>, AbstractProfiledPerformanceAssertion> performanceCheckProfiles = new HashMap<Class<?>, AbstractProfiledPerformanceAssertion>(); - private String currentProfile; - - public PerformanceCheckProfileRepository() { - String hostName = getHostName(); - // this.currentProfile = System.getProperty("TestProfile", "ChwWork"); - currentProfile = hostName; - LOGGER.info("Using test profile '" + this.currentProfile + "'"); - } - - private String getHostName() { - String hostname = "Unknown"; - - try - { - InetAddress addr = InetAddress.getLocalHost(); - hostname = addr.getHostName(); - } catch (UnknownHostException ex) { - LOGGER.warn("Hostname can not be resolved"); - } - - return hostname; - } - - public void setCurrentProfile(final String currentProfile) { - this.currentProfile = currentProfile; - } - - public String getCurrentProfile() { - return this.currentProfile; - } - - public void register(final Class<?> testClass, final AbstractProfiledPerformanceAssertion profile) { - if (profile.getCorrespondingPerformanceProfile().equals(this.currentProfile)) { - this.performanceCheckProfiles.put(testClass, profile); - } - } - - public AbstractProfiledPerformanceAssertion get(final Class<?> clazz) { - return this.performanceCheckProfiles.get(clazz); - } -} diff --git a/src/main/resources/pipe-factories.conf b/src/main/resources/pipe-factories.conf index 3e3db90425d5917ac090618d0e2f7b53f398c62b..05d552cb6a9a4121d75462fa1a5d7de5e602c9b7 100644 --- a/src/main/resources/pipe-factories.conf +++ b/src/main/resources/pipe-factories.conf @@ -1,5 +1,3 @@ teetime.framework.pipe.SingleElementPipeFactory -teetime.framework.pipe.OrderedGrowableArrayPipeFactory -teetime.framework.pipe.UnorderedGrowablePipeFactory teetime.framework.pipe.SpScPipeFactory -teetime.framework.pipe.UnboundedSpScPipeFactory +teetime.framework.pipe.UnboundedSpScPipeFactory \ No newline at end of file diff --git a/src/test/java/teetime/examples/tokenizer/TokenizerTest.java b/src/test/java/teetime/examples/tokenizer/TokenizerTest.java index b1396eae30773290f18e1a5aa0a511c63d1280dc..070c722444cec08e8870f05a6eb0e8512ba4e024 100644 --- a/src/test/java/teetime/examples/tokenizer/TokenizerTest.java +++ b/src/test/java/teetime/examples/tokenizer/TokenizerTest.java @@ -38,8 +38,7 @@ public class TokenizerTest { @Test public void executeTest() throws IOException { - // Encrypted lorem ipsum - final String inputFile = "src/test/resources/data/cipherInput.txt"; + final String inputFile = "src/test/resources/data/cipherInput.txt"; // Encrypted lorem ipsum final String password = "Password"; final TokenizerConfiguration configuration = new TokenizerConfiguration(inputFile, password); diff --git a/src/test/java/teetime/framework/TraversorTest.java b/src/test/java/teetime/framework/TraversorTest.java index 9f4ef25077219463a7ea4c4df72ba4082b89f94d..35a7826b5800186a72416d97e18a58f8662292b9 100644 --- a/src/test/java/teetime/framework/TraversorTest.java +++ b/src/test/java/teetime/framework/TraversorTest.java @@ -41,11 +41,11 @@ public class TraversorTest { public void traverse() { TestConfiguration tc = new TestConfiguration(); traversor.traverse(tc.init); - Set<Stage> comparingSet = new HashSet<Stage>(); - comparingSet.add(tc.init); - comparingSet.add(tc.f2b); - comparingSet.add(tc.distributor); - assertTrue(comparingSet.equals(traversor.getVisitedStage())); + Set<Stage> comparingStages = new HashSet<Stage>(); + comparingStages.add(tc.init); + comparingStages.add(tc.f2b); + comparingStages.add(tc.distributor); + assertTrue(comparingStages.equals(traversor.getVisitedStage())); } // WordCounterConfiguration diff --git a/src/test/java/teetime/framework/pipe/PipeFactoryLoaderTest.java b/src/test/java/teetime/framework/pipe/PipeFactoryLoaderTest.java index f6418cc01c8b19a660c997129a57819e9396c45b..6ca257a8995f333386703af90d5313bb2dab7602 100644 --- a/src/test/java/teetime/framework/pipe/PipeFactoryLoaderTest.java +++ b/src/test/java/teetime/framework/pipe/PipeFactoryLoaderTest.java @@ -35,15 +35,15 @@ public class PipeFactoryLoaderTest { @Test public void emptyConfig() throws IOException { - final List<IPipeFactory> list = PipeFactoryLoader.loadPipeFactoriesFromClasspath("data/empty-test.conf"); - Assert.assertEquals(true, list.isEmpty()); + final List<IPipeFactory> pipeFactories = PipeFactoryLoader.loadPipeFactoriesFromClasspath("data/empty-test.conf"); + Assert.assertEquals(true, pipeFactories.isEmpty()); } @Test public void singleConfig() throws IOException { - final List<IPipeFactory> list = PipeFactoryLoader.loadPipeFactoriesFromClasspath("pipe-factories.conf"); + final List<IPipeFactory> pipeFactories = PipeFactoryLoader.loadPipeFactoriesFromClasspath("pipe-factories.conf"); final int lines = Files.readLines(new File("target/classes/pipe-factories.conf"), Charsets.UTF_8).size(); - Assert.assertEquals(lines, list.size()); + Assert.assertEquals(lines, pipeFactories.size()); } @Test diff --git a/src/test/java/teetime/framework/pipe/SpScPipeTest.java b/src/test/java/teetime/framework/pipe/SpScPipeTest.java index 37c2e9647842bd7a653654d33a7aea610f54b044..c7a2db5b4ddd36feee67a09fb80d84f1a57559da 100644 --- a/src/test/java/teetime/framework/pipe/SpScPipeTest.java +++ b/src/test/java/teetime/framework/pipe/SpScPipeTest.java @@ -15,6 +15,7 @@ */ package teetime.framework.pipe; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import java.util.ArrayList; @@ -26,28 +27,34 @@ import teetime.framework.AbstractInterThreadPipe; import teetime.framework.InputPort; import teetime.framework.OutputPort; import teetime.framework.signal.ISignal; +import teetime.framework.signal.InitializingSignal; import teetime.framework.signal.StartingSignal; import teetime.framework.signal.TerminatingSignal; import teetime.framework.signal.ValidatingSignal; +import teetime.stage.basic.merger.Merger; public class SpScPipeTest { // @Ignore // ignore as long as this test passes null ports to SpScPipe - // @Test + @Test public void testSignalOrdering() throws Exception { - OutputPort<Object> sourcePort = null; - InputPort<Object> targetPort = null; + Merger<Object> portSource = new Merger<Object>(); + OutputPort<Object> sourcePort = portSource.getOutputPort(); + InputPort<Object> targetPort = portSource.getNewInputPort(); AbstractInterThreadPipe pipe = new SpScPipe(sourcePort, targetPort, 1); // IPipe does not provide getSignal method List<ISignal> signals = new ArrayList<ISignal>(); signals.add(new StartingSignal()); signals.add(new TerminatingSignal()); + signals.add(new InitializingSignal()); signals.add(new ValidatingSignal()); signals.add(new StartingSignal()); signals.add(new TerminatingSignal()); + signals.add(new InitializingSignal()); signals.add(new ValidatingSignal()); signals.add(new StartingSignal()); + signals.add(new InitializingSignal()); signals.add(new TerminatingSignal()); signals.add(new ValidatingSignal()); @@ -63,7 +70,7 @@ public class SpScPipeTest { } secondSignals.add(temp); } - // Assert.assertEquals(list, secondList); + assertEquals(signals, secondSignals); } @Test(expected = NullPointerException.class) diff --git a/src/test/java/teetime/stage/CipherStageTest.java b/src/test/java/teetime/stage/CipherStageTest.java index 4f2d8799d3fc17f8c41662563c7a4f3609c54505..d1a28829815331f1a92a2267cced8da6d46d9f79 100644 --- a/src/test/java/teetime/stage/CipherStageTest.java +++ b/src/test/java/teetime/stage/CipherStageTest.java @@ -36,14 +36,14 @@ public class CipherStageTest { final CipherStage encryptStage = new CipherStage("somePassword", CipherMode.ENCRYPT); final CipherStage decryptStage = new CipherStage("somePassword", CipherMode.DECRYPT); - final byte[] input = new byte[] { 1, 2, 3, 4, 5 }; - final List<byte[]> encryptedResult = new ArrayList<byte[]>(); - final List<byte[]> decryptedResult = new ArrayList<byte[]>(); + final byte[] inputBytes = new byte[] { 1, 2, 3, 4, 5 }; + final List<byte[]> encryptedBytes = new ArrayList<byte[]>(); + final List<byte[]> decryptedBytes = new ArrayList<byte[]>(); - test(encryptStage).and().send(input).to(encryptStage.getInputPort()).and().receive(encryptedResult).from(encryptStage.getOutputPort()).start(); - test(decryptStage).and().send(encryptedResult).to(decryptStage.getInputPort()).and().receive(decryptedResult).from(decryptStage.getOutputPort()).start(); + test(encryptStage).and().send(inputBytes).to(encryptStage.getInputPort()).and().receive(encryptedBytes).from(encryptStage.getOutputPort()).start(); + test(decryptStage).and().send(encryptedBytes).to(decryptStage.getInputPort()).and().receive(decryptedBytes).from(decryptStage.getOutputPort()).start(); - assertThat(decryptedResult, contains(input)); + assertThat(decryptedBytes, contains(inputBytes)); } } diff --git a/src/test/java/teetime/stage/InitialElementProducerTest.java b/src/test/java/teetime/stage/InitialElementProducerTest.java index 5667be30ab0836949341b7e260fbbf7b5f99cca7..9f15e2af0b3fc5e0b09189337e83b6628f637b22 100644 --- a/src/test/java/teetime/stage/InitialElementProducerTest.java +++ b/src/test/java/teetime/stage/InitialElementProducerTest.java @@ -87,11 +87,11 @@ public class InitialElementProducerTest { @Test public void instantiateWithIterable() { - List<Integer> test = new ArrayList<Integer>(); - test.add(1); - test.add(2); - test.add(3); - producer = new InitialElementProducer<Integer>(test); + List<Integer> testIntegers = new ArrayList<Integer>(); + testIntegers.add(1); + testIntegers.add(2); + testIntegers.add(3); + producer = new InitialElementProducer<Integer>(testIntegers); List<Integer> results = new ArrayList<Integer>(); test(producer).and().receive(results).from(producer.getOutputPort()).start(); diff --git a/src/test/java/teetime/stage/InstanceCounterTest.java b/src/test/java/teetime/stage/InstanceCounterTest.java index 65ee1b09187a408a444ec8da4f61157c49df9329..e8286613c074330e1e5e10508dd35ee78c4c3445 100644 --- a/src/test/java/teetime/stage/InstanceCounterTest.java +++ b/src/test/java/teetime/stage/InstanceCounterTest.java @@ -66,15 +66,15 @@ public class InstanceCounterTest { @Test public void filterShouldWorkWithMultipleInput() { - final List<Object> input = new ArrayList<Object>(); + final List<Object> inputObjects = new ArrayList<Object>(); - input.add(new Object()); - input.add(new Clazz()); - input.add(new Object()); - input.add(new SubClazz()); - input.add(new Object()); + inputObjects.add(new Object()); + inputObjects.add(new Clazz()); + inputObjects.add(new Object()); + inputObjects.add(new SubClazz()); + inputObjects.add(new Object()); - test(this.filter).and().send(input).to(this.filter.getInputPort()).start(); + test(this.filter).and().send(inputObjects).to(this.filter.getInputPort()).start(); assertThat(this.filter.getCounter(), is(2)); } diff --git a/src/test/java/teetime/stage/InstanceOfFilterTest.java b/src/test/java/teetime/stage/InstanceOfFilterTest.java index 186ce0c44fe7017f5bfd2be494f67d539f254db0..8abd3018b5122f409e023e936f30dd6a1377892a 100644 --- a/src/test/java/teetime/stage/InstanceOfFilterTest.java +++ b/src/test/java/teetime/stage/InstanceOfFilterTest.java @@ -88,16 +88,16 @@ public class InstanceOfFilterTest { @Test public void filterShouldWorkWithMultipleInput() { final List<Clazz> results = new ArrayList<InstanceOfFilterTest.Clazz>(); - final List<Object> input = new ArrayList<Object>(); + final List<Object> inputObjects = new ArrayList<Object>(); - input.add(new Object()); - input.add(new Clazz()); - input.add(new Object()); - input.add(new SubClazz()); - input.add(new Object()); + inputObjects.add(new Object()); + inputObjects.add(new Clazz()); + inputObjects.add(new Object()); + inputObjects.add(new SubClazz()); + inputObjects.add(new Object()); test(filter) - .and().send(input).to(filter.getInputPort()) + .and().send(inputObjects).to(filter.getInputPort()) .and().receive(results).from(filter.getMatchedOutputPort()) .start(); diff --git a/src/test/java/teetime/stage/MultipleInstanceOfFilterTest.java b/src/test/java/teetime/stage/MultipleInstanceOfFilterTest.java index 6221ba7733486296626f1b55ea5fb486d2db96c6..a1b8577b6f4a3abe172b89723c49dc8354de2a7d 100644 --- a/src/test/java/teetime/stage/MultipleInstanceOfFilterTest.java +++ b/src/test/java/teetime/stage/MultipleInstanceOfFilterTest.java @@ -39,24 +39,24 @@ public class MultipleInstanceOfFilterTest { @SuppressWarnings("unchecked") public void filteringForSingleTypeShouldWork() { final MultipleInstanceOfFilter<Object> filter = new MultipleInstanceOfFilter<Object>(); - final List<Object> input = new ArrayList<Object>(Arrays.asList("1", 1.5f, "2", 2.5f, "3", 3.5f)); - final List<String> result = new ArrayList<String>(); + final List<Object> inputObjects = new ArrayList<Object>(Arrays.asList("1", 1.5f, "2", 2.5f, "3", 3.5f)); + final List<String> receivedStrings = new ArrayList<String>(); - StageTester.test(filter).and().send(input).to(filter.getInputPort()).and().receive(result).from(filter.getOutputPortForType(String.class)).start(); + StageTester.test(filter).and().send(inputObjects).to(filter.getInputPort()).and().receive(receivedStrings).from(filter.getOutputPortForType(String.class)).start(); - assertThat(result, is(not(empty()))); - assertThat(result, contains("1", "2", "3")); + assertThat(receivedStrings, is(not(empty()))); + assertThat(receivedStrings, contains("1", "2", "3")); } @Test @SuppressWarnings("unchecked") public void filteringForMultipleTypesShouldWork() { final MultipleInstanceOfFilter<Number> filter = new MultipleInstanceOfFilter<Number>(); - final List<Number> input = new ArrayList<Number>(Arrays.asList(1, 1.5f, 2, 2.5f, 3, 3.5f)); + final List<Number> inputObjects = new ArrayList<Number>(Arrays.asList(1, 1.5f, 2, 2.5f, 3, 3.5f)); final List<Integer> integers = new ArrayList<Integer>(); final List<Float> floats = new ArrayList<Float>(); - StageTester.test(filter).and().send(input).to(filter.getInputPort()).and().receive(integers).from(filter.getOutputPortForType(Integer.class)).and() + StageTester.test(filter).and().send(inputObjects).to(filter.getInputPort()).and().receive(integers).from(filter.getOutputPortForType(Integer.class)).and() .receive(floats).from(filter.getOutputPortForType(Float.class)).start(); assertThat(integers, contains(1, 2, 3)); diff --git a/src/test/java/teetime/stage/basic/distributor/DistributorTest.java b/src/test/java/teetime/stage/basic/distributor/DistributorTest.java index 9f40fe64b7bd57b0466e1f70f37ea3d91bbdb337..3d637d253fe1c64e390a113bc0a7e963e1d5aaad 100644 --- a/src/test/java/teetime/stage/basic/distributor/DistributorTest.java +++ b/src/test/java/teetime/stage/basic/distributor/DistributorTest.java @@ -32,7 +32,7 @@ import org.junit.rules.ExpectedException; /** * @author Nils Christian Ehmke - * + * * @since 1.0 */ public class DistributorTest { @@ -41,58 +41,83 @@ public class DistributorTest { public ExpectedException expectedException = ExpectedException.none(); private Distributor<Integer> distributor; - private List<Integer> fstList; - private List<Integer> sndList; + private List<Integer> firstIntegers; + private List<Integer> secondIntegers; @Before public void initializeDistributor() throws Exception { this.distributor = new Distributor<Integer>(); - this.fstList = new ArrayList<Integer>(); - this.sndList = new ArrayList<Integer>(); + this.firstIntegers = new ArrayList<Integer>(); + this.secondIntegers = new ArrayList<Integer>(); } @Test public void roundRobinShouldWork() { distributor.setStrategy(new RoundRobinStrategy()); - test(distributor).and().send(1, 2, 3, 4, 5).to(distributor.getInputPort()).and().receive(fstList).from(distributor.getNewOutputPort()).and() - .receive(sndList).from(distributor.getNewOutputPort()).start(); + test(distributor).and().send(1, 2, 3, 4, 5).to(distributor.getInputPort()).and().receive(firstIntegers).from(distributor.getNewOutputPort()).and() + .receive(secondIntegers).from(distributor.getNewOutputPort()).start(); - assertThat(this.fstList, contains(1, 3, 5)); - assertThat(this.sndList, contains(2, 4)); + assertThat(this.firstIntegers, contains(1, 3, 5)); + assertThat(this.secondIntegers, contains(2, 4)); } @Test public void singleElementRoundRobinShouldWork() { distributor.setStrategy(new RoundRobinStrategy()); - test(distributor).and().send(1).to(distributor.getInputPort()).and().receive(fstList).from(distributor.getNewOutputPort()).and().receive(sndList) + test(distributor).and().send(1).to(distributor.getInputPort()).and().receive(firstIntegers).from(distributor.getNewOutputPort()).and() + .receive(secondIntegers) + .from(distributor.getNewOutputPort()).start(); + + assertThat(this.firstIntegers, contains(1)); + assertThat(this.secondIntegers, is(empty())); + } + + @Test + public void roundRobin2ShouldWork() { + distributor.setStrategy(new RoundRobinStrategy2()); + + test(distributor).and().send(1, 2, 3, 4, 5).to(distributor.getInputPort()).and().receive(firstIntegers).from(distributor.getNewOutputPort()).and() + .receive(secondIntegers).from(distributor.getNewOutputPort()).start(); + + assertThat(this.firstIntegers, contains(1, 3, 5)); + assertThat(this.secondIntegers, contains(2, 4)); + } + + @Test + public void singleElementRoundRobin2ShouldWork() { + distributor.setStrategy(new RoundRobinStrategy2()); + + test(distributor).and().send(1).to(distributor.getInputPort()).and().receive(firstIntegers).from(distributor.getNewOutputPort()).and() + .receive(secondIntegers) .from(distributor.getNewOutputPort()).start(); - assertThat(this.fstList, contains(1)); - assertThat(this.sndList, is(empty())); + assertThat(this.firstIntegers, contains(1)); + assertThat(this.secondIntegers, is(empty())); } @Test public void copyByReferenceShouldWork() { distributor.setStrategy(new CopyByReferenceStrategy()); - test(distributor).and().send(1, 2, 3, 4, 5).to(distributor.getInputPort()).and().receive(fstList).from(distributor.getNewOutputPort()).and() - .receive(sndList).from(distributor.getNewOutputPort()).start(); + test(distributor).and().send(1, 2, 3, 4, 5).to(distributor.getInputPort()).and().receive(firstIntegers).from(distributor.getNewOutputPort()).and() + .receive(secondIntegers).from(distributor.getNewOutputPort()).start(); - assertThat(this.fstList, contains(1, 2, 3, 4, 5)); - assertThat(this.sndList, contains(1, 2, 3, 4, 5)); + assertThat(this.firstIntegers, contains(1, 2, 3, 4, 5)); + assertThat(this.secondIntegers, contains(1, 2, 3, 4, 5)); } @Test public void singleElementCopyByReferenceShouldWork() { distributor.setStrategy(new CopyByReferenceStrategy()); - test(distributor).and().send(1).to(distributor.getInputPort()).and().receive(fstList).from(distributor.getNewOutputPort()).and().receive(sndList) + test(distributor).and().send(1).to(distributor.getInputPort()).and().receive(firstIntegers).from(distributor.getNewOutputPort()).and() + .receive(secondIntegers) .from(distributor.getNewOutputPort()).start(); - assertThat(this.fstList, contains(1)); - assertThat(this.sndList, contains(1)); + assertThat(this.firstIntegers, contains(1)); + assertThat(this.secondIntegers, contains(1)); } @Test diff --git a/src/test/java/teetime/stage/io/File2SeqOfWordsTest.java b/src/test/java/teetime/stage/io/File2SeqOfWordsTest.java new file mode 100644 index 0000000000000000000000000000000000000000..66cdd8837505468be5d54b6e347903b6420c31cb --- /dev/null +++ b/src/test/java/teetime/stage/io/File2SeqOfWordsTest.java @@ -0,0 +1,25 @@ +package teetime.stage.io; + +import static org.junit.Assert.assertEquals; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +import teetime.framework.test.StageTester; + +public class File2SeqOfWordsTest { + + @Test + public void testExecute() throws Exception { + File2SeqOfWords stage = new File2SeqOfWords(14); + List<String> outputList = new ArrayList<String>(); + StageTester.test(stage).send(Arrays.asList(new File("./src/test/resources/data/input.txt"))).to(stage.getInputPort()).and().receive(outputList) + .from(stage.getOutputPort()).start(); + assertEquals(outputList.get(0), "Lorem ipsum"); + } + +} diff --git a/src/test/java/teetime/stage/io/PrinterTest.java b/src/test/java/teetime/stage/io/PrinterTest.java new file mode 100644 index 0000000000000000000000000000000000000000..362b1caaaf5adbf93db203681d988168ad8bdc36 --- /dev/null +++ b/src/test/java/teetime/stage/io/PrinterTest.java @@ -0,0 +1,35 @@ +package teetime.stage.io; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertThat; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.Arrays; + +import org.junit.Test; + +import teetime.framework.test.StageTester; +import teetime.stage.basic.merger.Merger; + +public class PrinterTest { + + @Test + public void testDefaultUsage() { + Printer<Merger<Object>> printer = new Printer<Merger<Object>>(); + Merger<Object> testStage = new Merger<Object>(); + + final StringBuilder sb = new StringBuilder(128); + sb.append(printer.getId()); + sb.append('(').append(testStage.getClass().getSimpleName()).append(") ").append(testStage.toString()); + + PrintStream systemOut = System.out; + final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outContent)); + + StageTester.test(printer).send(Arrays.asList(testStage)).to(printer.getInputPort()).start(); + assertThat(outContent.toString(), containsString(sb.toString())); + + System.setOut(systemOut); + } +} diff --git a/src/test/java/teetime/util/classpath/FileSearcherTest.java b/src/test/java/teetime/util/classpath/FileSearcherTest.java index b79e6fa7ebd11dc07118f41d8d71144d2eb7e111..05eedee1ace93401af3a3d155bb35e79b2d09bb8 100644 --- a/src/test/java/teetime/util/classpath/FileSearcherTest.java +++ b/src/test/java/teetime/util/classpath/FileSearcherTest.java @@ -30,20 +30,20 @@ public class FileSearcherTest { @Test public void fileInClasspath() throws IOException { - final List<URL> list = FileSearcher.loadResources("pipe-factories.conf"); - Assert.assertEquals(false, list.isEmpty()); + final List<URL> urls = FileSearcher.loadResources("pipe-factories.conf"); + Assert.assertEquals(false, urls.isEmpty()); } @Test public void multipleFiles() throws IOException { - final List<URL> list = FileSearcher.loadResources("LICENSE.txt"); - Assert.assertEquals(true, list.size() > 1); + final List<URL> urls = FileSearcher.loadResources("LICENSE.txt"); + Assert.assertEquals(true, urls.size() > 1); } @Test public void missingFile() throws IOException { - final List<URL> list = FileSearcher.loadResources("filethatdoesnotexistinanyproject.nope"); - Assert.assertEquals(true, list.isEmpty()); + final List<URL> urls = FileSearcher.loadResources("filethatdoesnotexistinanyproject.nope"); + Assert.assertEquals(true, urls.isEmpty()); } } diff --git a/src/test/java/teetime/util/test/framework/PerformanceTest.java b/src/test/java/teetime/util/test/framework/PerformanceTest.java deleted file mode 100644 index 813ffc693400e71e5e3b12039380c31d87258e32..0000000000000000000000000000000000000000 --- a/src/test/java/teetime/util/test/framework/PerformanceTest.java +++ /dev/null @@ -1,87 +0,0 @@ -/** - * Copyright (C) 2015 Christian Wulf, Nelson Tavares de Sousa (http://teetime.sourceforge.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.test.framework; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; - -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.rules.TestRule; -import org.junit.rules.TestWatcher; -import org.junit.runner.Description; - -import teetime.util.StopWatch; -import teetime.util.TimestampObject; -import teetime.util.test.eval.PerformanceResult; -import teetime.util.test.eval.StatisticsUtil; - -public abstract class PerformanceTest { - - protected static final PerformanceCheckProfileRepository PERFORMANCE_CHECK_PROFILE_REPOSITORY = PerformanceCheckProfileRepository.INSTANCE; - protected static final int NUM_OBJECTS_TO_CREATE = 1000000; - protected static final int NUM_NOOP_FILTERS = 800; - - public static final MeasurementRepository measurementRepository = new MeasurementRepository(); - - protected Description description; - - protected StopWatch stopWatch; - protected List<TimestampObject> timestampObjects; - - static { - System.setProperty("logback.configurationFile", "src/test/resources/logback.groovy"); - } - - @Rule - public final TestRule watcher = new TestWatcher() { - @Override - protected void starting(final Description description) { - PerformanceTest.this.description = description; - // System.out.println("getDisplayName(): " + description.getDisplayName()); - } - }; - - @Before - public void before() { - this.stopWatch = new StopWatch(); - this.timestampObjects = new ArrayList<TimestampObject>(NUM_OBJECTS_TO_CREATE); - } - - @After - public void after() { - String testMethodIdentifier = MeasurementRepository.buildTestMethodIdentifier(description.getTestClass(), description.getMethodName()); - PerformanceResult performanceResult = StatisticsUtil.computeStatistics(this.stopWatch.getDurationInNs(), this.timestampObjects); - measurementRepository.performanceResults.put(testMethodIdentifier, performanceResult); - - addToRepository(performanceResult); - - System.out.println("Duration: " + TimeUnit.NANOSECONDS.toMillis(performanceResult.overallDurationInNs) + " ms"); - System.out.println("avg duration: " + TimeUnit.NANOSECONDS.toMicros(performanceResult.avgDurInNs) + " µs"); - System.out.println(StatisticsUtil.getQuantilesString(performanceResult.quantiles)); - System.out.println("confidenceWidth: " + performanceResult.confidenceWidthInNs + " ns"); - System.out.println("[" + TimeUnit.NANOSECONDS.toMicros(performanceResult.avgDurInNs - performanceResult.confidenceWidthInNs) + " µs, " - + TimeUnit.NANOSECONDS.toMicros(performanceResult.avgDurInNs + performanceResult.confidenceWidthInNs) + " µs]"); - } - - @Deprecated - private void addToRepository(final PerformanceResult performanceResult) { - measurementRepository.performanceResults.put(this.description.getDisplayName(), performanceResult); - } - -}