Java tutorial
/* * Copyright (C) 2012 Google Inc. * * 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 com.google.caliper.worker.instrument; import com.google.caliper.bridge.ExperimentSpec; import com.google.caliper.core.Running.Benchmark; import com.google.caliper.core.Running.BenchmarkClass; import com.google.caliper.core.Running.BenchmarkMethod; import com.google.caliper.model.BenchmarkSpec; import com.google.caliper.model.InstrumentType; import com.google.caliper.util.InvalidCommandException; import com.google.caliper.util.Util; import com.google.common.base.Function; import com.google.common.base.Ticker; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSortedMap; import com.google.common.collect.Maps; import com.google.common.primitives.Primitives; import dagger.Binds; import dagger.Module; import dagger.Provides; import dagger.Reusable; import dagger.multibindings.IntoMap; import java.lang.reflect.Method; import java.util.Map; import javax.inject.Provider; /** * Binds classes necessary for the worker instruments. Also manages the injection of {@link * com.google.caliper.Param parameters} from the {@link ExperimentSpec} into the benchmark. * * <p>TODO(gak): Ensure that each worker only has bindings for the objects it needs and not the * objects required by different workers. (i.e. don't bind a Ticker if the worker is an allocation * worker). */ @Module public abstract class WorkerInstrumentModule { private WorkerInstrumentModule() { } @Provides static BenchmarkSpec provideBenchmarkSpec(ExperimentSpec experiment) { return experiment.benchmarkSpec(); } @Provides @Benchmark static Object provideBenchmarkInstance(BenchmarkCreator creator) { return creator.createBenchmarkInstance(); } @Provides @Reusable @BenchmarkMethod static Method provideBenchmarkMethod(ExperimentSpec experiment, BenchmarkSpec benchmarkSpec, @BenchmarkClass Class<?> benchmarkClass) { Method method = findBenchmarkMethod(benchmarkClass, benchmarkSpec.methodName(), experiment.methodParameterClasses()); method.setAccessible(true); return method; } @Provides @BenchmarkMethod static String provideBenchmarkMethodName(@BenchmarkMethod Method benchmarkMethod) { return benchmarkMethod.getName(); } @Provides @Benchmark static ImmutableSortedMap<String, String> provideUserParameters(BenchmarkSpec spec) { return spec.parameters(); } @Provides static InstrumentType provideInstrumentType(ExperimentSpec experiment) { return experiment.instrumentType(); } @Provides @WorkerInstrument.Options static Map<String, String> provideWorkerInstrumentOptions(ExperimentSpec experiment) { return experiment.workerInstrumentOptions(); } @Provides static WorkerInstrument provideWorkerInstrument(InstrumentType instrumentType, Map<InstrumentType, Provider<WorkerInstrument>> availableWorkerInstruments) { Provider<WorkerInstrument> workerInstrumentProvider = availableWorkerInstruments.get(instrumentType); if (workerInstrumentProvider == null) { throw new InvalidCommandException("%s is not a supported instrument type (%s).", instrumentType, availableWorkerInstruments); } return workerInstrumentProvider.get(); } @Binds @IntoMap @InstrumentTypeKey(InstrumentType.ARBITRARY_MEASUREMENT) abstract WorkerInstrument bindArbitraryMeasurementWorkerInstrument(ArbitraryMeasurementWorkerInstrument impl); @Binds @IntoMap @InstrumentTypeKey(InstrumentType.RUNTIME_MACRO) abstract WorkerInstrument bindMacrobenchmarkWorkerInstrument(MacrobenchmarkWorkerInstrument impl); @Binds @IntoMap @InstrumentTypeKey(InstrumentType.RUNTIME_MICRO) abstract WorkerInstrument bindRuntimeWorkerInstrumentMicro(RuntimeWorkerInstrument.Micro impl); @Binds @IntoMap @InstrumentTypeKey(InstrumentType.RUNTIME_PICO) abstract WorkerInstrument bindRuntimeWorkerInstrumentPico(RuntimeWorkerInstrument.Pico impl); @Provides static Ticker provideTicker() { return Ticker.systemTicker(); } private static Method findBenchmarkMethod(Class<?> benchmark, String methodName, ImmutableList<String> methodParameterClasses) { Class<?>[] params = new Class<?>[methodParameterClasses.size()]; for (int i = 0; i < methodParameterClasses.size(); i++) { try { String typeName = methodParameterClasses.get(i); Class<?> primitiveType = PRIMITIVE_TYPES.get(typeName); if (primitiveType != null) { params[i] = primitiveType; } else { params[i] = Util.loadClass(typeName); } } catch (ClassNotFoundException e) { throw new RuntimeException(e); } } try { return benchmark.getDeclaredMethod(methodName, params); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } catch (SecurityException e) { // assertion error? throw new RuntimeException(e); } } private static final ImmutableMap<String, Class<?>> PRIMITIVE_TYPES = Maps .uniqueIndex(Primitives.allPrimitiveTypes(), new Function<Class<?>, String>() { @Override public String apply(Class<?> input) { return input.getName(); } }); }