moved some classes to this project

parent 6ee82b5d
......@@ -15,7 +15,7 @@
*/
package teetime.stage.trace.traceReconstruction;
import teetime.util.concurrent.hashmap.ValueFactory;
import teetime.util.ValueFactory;
public final class EventBasedTraceFactory implements ValueFactory<EventBasedTrace> {
......
......@@ -19,9 +19,9 @@ import java.util.concurrent.TimeUnit;
import teetime.framework.AbstractConsumerStage;
import teetime.framework.OutputPort;
import teetime.util.ConcurrentHashMapWithDefault;
import teetime.util.ISendTraceBuffer;
import teetime.util.TraceReconstructor;
import teetime.util.concurrent.hashmap.ConcurrentHashMapWithDefault;
import kieker.common.record.flow.IFlowRecord;
......
/**
* 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;
public abstract class AbstractProfiledPerformanceAssertion {
public abstract String getCorrespondingPerformanceProfile();
public abstract void check();
}
/**
* 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.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);
}
}
/**
* 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.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;
}
}
/**
* 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;
/**
* @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;
}
}
/**
* 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.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;
}
}
/**
* 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 java.util.Map;
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 + ")";
}
}
/**
* 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.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);
}
}
/**
* 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.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();
}
}
/**
* 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.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;
/**
* @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;
}
}
}
}
......@@ -16,7 +16,6 @@
package teetime.util;
import teetime.stage.trace.traceReconstruction.EventBasedTrace;
import teetime.util.concurrent.hashmap.ConcurrentHashMapWithDefault;
import kieker.common.record.flow.IFlowRecord;
import kieker.common.record.flow.trace.AbstractTraceEvent;
......
/**
* 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;
/**
* @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();
}
......@@ -21,9 +21,9 @@ import java.util.concurrent.Callable;
import org.junit.Test;
import teetime.util.StatisticsUtil;
import teetime.util.StopWatch;
import teetime.util.TimestampObject;
import teetime.util.test.eval.StatisticsUtil;
import util.test.PerformanceTest;
import kieker.analysis.examples.ThroughputTimestampAnalysis;
......
......@@ -34,8 +34,8 @@ import org.junit.runners.MethodSorters;
import teetime.framework.Analysis;
import teetime.util.ListUtil;
import teetime.util.StatisticsUtil;
import teetime.util.StopWatch;
import teetime.util.test.eval.StatisticsUtil;
/**
* @author Christian Wulf
......
......@@ -32,8 +32,8 @@ import org.junit.Test;
import teetime.framework.Analysis;
import teetime.util.ListUtil;
import teetime.util.StatisticsUtil;
import teetime.util.StopWatch;
import teetime.util.test.eval.StatisticsUtil;
/**
* @author Christian Wulf
......
......@@ -33,8 +33,8 @@ import org.junit.Test;
import teetime.framework.Analysis;
import teetime.stage.trace.traceReconstruction.EventBasedTrace;
import teetime.util.StatisticsUtil;
import teetime.util.StopWatch;
import teetime.util.test.eval.StatisticsUtil;
/**
* @author Christian Wulf
......
......@@ -25,8 +25,8 @@ import org.junit.Before;
import org.junit.Test;
import teetime.framework.Analysis;
import teetime.util.StatisticsUtil;
import teetime.util.StopWatch;
import teetime.util.test.eval.StatisticsUtil;
/**
* @author Christian Wulf
......
......@@ -32,8 +32,8 @@ import org.junit.Test;
import teetime.framework.Analysis;
import teetime.stage.trace.traceReconstruction.EventBasedTrace;
import teetime.util.StatisticsUtil;
import teetime.util.StopWatch;
import teetime.util.test.eval.StatisticsUtil;
/**
* @author Christian Wulf
......
......@@ -30,8 +30,8 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import teetime.util.StatisticsUtil;
import teetime.util.StopWatch;
import teetime.util.test.eval.StatisticsUtil;
import kieker.analysis.plugin.filter.flow.TraceEventRecords;
......
......@@ -30,7 +30,7 @@ import teetime.stage.io.network.TcpReaderStage;
import teetime.stage.trace.traceReconstruction.EventBasedTrace;
import teetime.stage.trace.traceReconstruction.EventBasedTraceFactory;
import teetime.stage.trace.traceReconstruction.TraceReconstructionFilter;
import teetime.util.concurrent.hashmap.ConcurrentHashMapWithDefault;
import teetime.util.ConcurrentHashMapWithDefault;
import kieker.common.record.IMonitoringRecord;
import kieker.common.record.flow.IFlowRecord;
......
......@@ -37,7 +37,7 @@ import teetime.stage.string.buffer.handler.StringHandler;
import teetime.stage.trace.traceReconstruction.EventBasedTrace;
import teetime.stage.trace.traceReconstruction.EventBasedTraceFactory;
import teetime.stage.trace.traceReconstruction.TraceReconstructionFilter;
import teetime.util.concurrent.hashmap.ConcurrentHashMapWithDefault;
import teetime.util.ConcurrentHashMapWithDefault;
import kieker.common.record.IMonitoringRecord;
import kieker.common.record.flow.IFlowRecord;
......