package org.cache2k.benchmark.jmh;
/*
* #%L
* Benchmarks: JMH suite.
* %%
* Copyright (C) 2013 - 2017 headissue GmbH, Munich
* %%
* 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.
* #L%
*/
import org.openjdk.jmh.infra.BenchmarkParams;
import org.openjdk.jmh.infra.IterationParams;
import org.openjdk.jmh.profile.InternalProfiler;
import org.openjdk.jmh.results.AggregationPolicy;
import org.openjdk.jmh.results.IterationResult;
import org.openjdk.jmh.results.Result;
import org.openjdk.jmh.results.ScalarResult;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
/**
* Record misc secondary result metrics.
*
* @author Jens Wilke
*/
public class MiscResultRecorderProfiler implements InternalProfiler {
public static final String SECONDARY_RESULT_PREFIX = "+misc.";
static final Map<String, CounterResult> counters = new ConcurrentHashMap<>();
static final Map<String, Result<?>> results = new ConcurrentHashMap<>();
/**
* Insert the counter value as secondary result. If a value is already inserted the
* counter value is added to the existing one. This can be used to collect and sum up
* results from different threads.
*/
public static void addCounterResult(String key, long _counter, String _unit, AggregationPolicy _aggregationPolicy) {
CounterResult r = counters.computeIfAbsent(key, any -> new CounterResult());
r.aggregationPolicy = _aggregationPolicy;
r.unit = _unit;
r.counter.addAndGet(_counter);
r.key = key;
}
public static long getCounterResult(String key) {
return counters.getOrDefault(key, new CounterResult()).counter.get();
}
/**
* Insert the counter value as secondary result. An existing counter value is replaced.
*/
public static void setResult(String key, double _result, String _unit, AggregationPolicy _aggregationPolicy) {
setResult(new ScalarResult(SECONDARY_RESULT_PREFIX + key, _result, _unit, _aggregationPolicy));
}
/**
* Add result to the JMH result data. If called multiple times with the same label only the last one will be added.
*/
public static void setResult(Result r) {
results.put(r.getLabel(), r);
}
@Override
public void beforeIteration(final BenchmarkParams benchmarkParams, final IterationParams iterationParams) {
counters.clear();
}
@Override
public Collection<? extends Result> afterIteration(final BenchmarkParams benchmarkParams, final IterationParams iterationParams, final IterationResult result) {
List<Result<?>> all = new ArrayList<>();
counters.values().stream()
.map(e ->
new ScalarResult(SECONDARY_RESULT_PREFIX + e.key, (double) e.counter.get(), e.unit, e.aggregationPolicy))
.sequential().forEach(e -> all.add(e));
all.addAll(results.values());
return all;
}
@Override
public String getDescription() {
return "Adds additional results gathered by the benchmark as secondary results.";
}
static class CounterResult {
String key;
String unit;
AggregationPolicy aggregationPolicy;
AtomicLong counter = new AtomicLong();
}
}