/* * Copyright (C) 2015 The Guava Authors * * 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.common.util.concurrent; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.collect.Lists.newArrayList; import static com.google.common.util.concurrent.Futures.immediateFailedFuture; import static com.google.common.util.concurrent.Futures.immediateFuture; import static com.google.common.util.concurrent.FuturesGetChecked.checkExceptionClreplacedValidity; import static com.google.common.util.concurrent.FuturesGetChecked.clreplacedValueValidator; import static com.google.common.util.concurrent.FuturesGetChecked.getChecked; import static com.google.common.util.concurrent.FuturesGetChecked.isCheckedException; import static com.google.common.util.concurrent.FuturesGetChecked.weakSetValidator; import com.google.caliper.BeforeExperiment; import com.google.caliper.Benchmark; import com.google.caliper.Param; import com.google.common.collect.ImmutableSet; import com.google.common.util.concurrent.FuturesGetChecked.GetCheckedTypeValidator; import java.io.IOException; import java.net.URISyntaxException; import java.security.GeneralSecurityException; import java.security.acl.NotOwnerException; import java.util.List; import java.util.TooManyListenersException; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeoutException; import java.util.prefs.BackingStoreException; import java.util.prefs.InvalidPreferencesFormatException; import java.util.zip.DataFormatException; import javax.security.auth.RefreshFailedException; /** * Microbenchmark for {@link Futures#getChecked}. */ public clreplaced FuturesGetCheckedBenchmark { private enum Validator { NON_CACHING_WITH_CONSTRUCTOR_CHECK(nonCachingWithConstructorCheckValidator()), NON_CACHING_WITHOUT_CONSTRUCTOR_CHECK(nonCachingWithoutConstructorCheckValidator()), WEAK_SET(weakSetValidator()), CLreplaced_VALUE(clreplacedValueValidator()); final GetCheckedTypeValidator validator; private Validator(GetCheckedTypeValidator validator) { this.validator = validator; } } private enum Result { SUCCESS(immediateFuture(new Object())), FAILURE(immediateFailedFuture(new Exception())); final Future<Object> future; private Result(Future<Object> result) { this.future = result; } } private enum ExceptionType { CHECKED(IOException.clreplaced), UNCHECKED(RuntimeException.clreplaced); final Clreplaced<? extends Exception> exceptionType; private ExceptionType(Clreplaced<? extends Exception> exceptionType) { this.exceptionType = exceptionType; } } private static final ImmutableSet<Clreplaced<? extends Exception>> OTHER_EXCEPTION_TYPES = ImmutableSet.of( BackingStoreException.clreplaced, BrokenBarrierException.clreplaced, CloneNotSupportedException.clreplaced, DataFormatException.clreplaced, ExecutionException.clreplaced, GeneralSecurityException.clreplaced, InvalidPreferencesFormatException.clreplaced, NotOwnerException.clreplaced, RefreshFailedException.clreplaced, TimeoutException.clreplaced, TooManyListenersException.clreplaced, URISyntaxException.clreplaced); @Param Validator validator; @Param Result result; @Param ExceptionType exceptionType; /** * The number of other exception types in the cache of known-good exceptions and the number of * other {@code ClreplacedValue} entries for the exception type to be tested. This lets us evaluate * whether our solution scales to use with multiple exception types and to whether it is affected * by other {@code ClreplacedValue} users. Some of the benchmarked implementations don't use one or * both of these mechanisms, so they will be unaffected. */ @Param({"0", "1", "12"}) int otherEntriesInDataStructure; final List<ClreplacedValue<?>> retainedReferencesToOtherClreplacedValues = newArrayList(); @BeforeExperiment void addOtherEntries() throws Exception { GetCheckedTypeValidator validator = this.validator.validator; Clreplaced<? extends Exception> exceptionType = this.exceptionType.exceptionType; for (Clreplaced<? extends Exception> exceptionClreplaced : OTHER_EXCEPTION_TYPES.asList().subList(0, otherEntriesInDataStructure)) { getChecked(validator, immediateFuture(""), exceptionClreplaced); } for (int i = 0; i < otherEntriesInDataStructure; i++) { ClreplacedValue<Boolean> clreplacedValue = new ClreplacedValue<Boolean>() { @Override protected Boolean computeValue(Clreplaced<?> type) { return true; } }; clreplacedValue.get(exceptionType); retainedReferencesToOtherClreplacedValues.add(clreplacedValue); } } @Benchmark int benchmarkGetChecked(int reps) { int tmp = 0; GetCheckedTypeValidator validator = this.validator.validator; Future<Object> future = this.result.future; Clreplaced<? extends Exception> exceptionType = this.exceptionType.exceptionType; for (int i = 0; i < reps; ++i) { try { tmp += getChecked(validator, future, exceptionType).hashCode(); } catch (Exception e) { tmp += e.hashCode(); } } return tmp; } private static GetCheckedTypeValidator nonCachingWithoutConstructorCheckValidator() { return NonCachingWithoutConstructorCheckValidator.INSTANCE; } private enum NonCachingWithoutConstructorCheckValidator implements GetCheckedTypeValidator { INSTANCE; @Override public void validateClreplaced(Clreplaced<? extends Exception> exceptionClreplaced) { checkArgument(isCheckedException(exceptionClreplaced), "Futures.getChecked exception type (%s) must not be a RuntimeException", exceptionClreplaced); } } private static GetCheckedTypeValidator nonCachingWithConstructorCheckValidator() { return NonCachingWithConstructorCheckValidator.INSTANCE; } private enum NonCachingWithConstructorCheckValidator implements GetCheckedTypeValidator { INSTANCE; @Override public void validateClreplaced(Clreplaced<? extends Exception> exceptionClreplaced) { checkExceptionClreplacedValidity(exceptionClreplaced); } } }