/* * Copyright 2013 MovingBlocks * * 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 org.terasology.benchmark; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import java.util.Iterator; import java.util.List; /** * BenchmarkResult records the results and the errors of the execution of one particular benchmark. * It also maintains a list of columns which are very useful for pretty printing the results. * */ public abstract class BenchmarkResult { private final List<Column<?>> columns = Lists.newLinkedList(); private final Class<?> benchmarkClass; private final String title; private final int[] repetitions; private final long[] starttime; private final long[] runtime; private boolean aborted; private final List<BenchmarkError> errors = Lists.newLinkedList(); public enum Alignment { LEFT { @Override public String pad(String value, int size) { StringBuilder builder = new StringBuilder(); builder.append(value == null ? "" : value); while (builder.length() < size) { builder.append(" "); } return builder.toString(); } }, RIGHT { @Override public String pad(String value, int size) { String result = (value == null ? "" : value); while (result.length() < size) { result = " " + result; } return result; } }; public abstract String pad(String value, int size); } public BenchmarkResult(Benchmark benchmark) { Preconditions.checkNotNull(benchmark, "Parameter 'benchmark' must not be null"); this.benchmarkClass = benchmark.getClass(); this.title = benchmark.getTitle(); this.repetitions = Preconditions.checkNotNull(benchmark.getRepetitions()); Preconditions.checkArgument(repetitions.length > 0, "The length of the parameter 'repetitions' has to be greater than zero"); int reps = repetitions.length; this.starttime = new long[reps]; this.runtime = new long[reps]; } public final Iterator<Column<?>> getColumnsIterator() { return columns.iterator(); } public final void addColumn(Column<?> column) { columns.add(Preconditions.checkNotNull(column)); } public final int getNumColumns() { return columns.size(); } public final Class<?> getBenchmarkClass() { return benchmarkClass; } public final String getTitle() { return title; } public final int getRepetitions() { return repetitions.length; } public final int getRepetitions(int rep) { return repetitions[rep]; } public final long getStartTime(int rep) { return starttime[rep]; } public final void setStartTime(int rep, long value) { starttime[rep] = value; } public final long getRunTime(int rep) { return runtime[rep]; } public final void setRunTime(int rep, long value) { runtime[rep] = value; } public final boolean isAborted() { return aborted; } public final Iterator<BenchmarkError> getErrorsIterator() { return errors.iterator(); } public final int getNumErrors() { return errors.size(); } public final void addError(BenchmarkError.Type type, Exception error) { this.aborted = this.aborted || Preconditions.checkNotNull(type).abort; errors.add(new BenchmarkError(type, error)); } public abstract static class Column<T extends BenchmarkResult> { public final T owner; public final Alignment alignment; public final String name; private final int reps; private final String[] cache; private boolean hasMaxWidth; private int maxWidth; public Column(T owner, Alignment alignment, String name) { this.owner = Preconditions.checkNotNull(owner); this.alignment = Preconditions.checkNotNull(alignment); this.name = Preconditions.checkNotNull(name); this.reps = owner.getRepetitions(); this.cache = new String[reps]; } protected abstract String getValueInternal(int rep); public final String getValue(int rep) { Preconditions.checkElementIndex(rep, reps, "Parameter 'rep'"); if (cache[rep] == null) { String v = Preconditions.checkNotNull(getValueInternal(rep), "BenchmarkResult::Column::getValueInternal() must never return null (rep=" + rep + ")"); cache[rep] = v; return v; } return cache[rep]; } public final int computeMaxWidth() { if (!hasMaxWidth) { int max = name.length(); for (int i = 0; i < reps; i++) { String v = getValue(i); if (v.length() > max) { max = v.length(); } } hasMaxWidth = true; maxWidth = max; } return maxWidth; } } }