001/* 002 * Copyright (C) 2007 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 005 * in compliance with the License. You may obtain a copy of the License at 006 * 007 * http://www.apache.org/licenses/LICENSE-2.0 008 * 009 * Unless required by applicable law or agreed to in writing, software distributed under the License 010 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 011 * or implied. See the License for the specific language governing permissions and limitations under 012 * the License. 013 */ 014 015package com.google.common.base; 016 017import static com.google.common.base.Internal.toNanosSaturated; 018import static com.google.common.base.NullnessCasts.uncheckedCastNullableTToT; 019import static com.google.common.base.Preconditions.checkArgument; 020import static com.google.common.base.Preconditions.checkNotNull; 021 022import com.google.common.annotations.GwtCompatible; 023import com.google.common.annotations.GwtIncompatible; 024import com.google.common.annotations.J2ktIncompatible; 025import com.google.common.annotations.VisibleForTesting; 026import java.io.Serializable; 027import java.time.Duration; 028import java.util.concurrent.TimeUnit; 029import javax.annotation.CheckForNull; 030import org.checkerframework.checker.nullness.qual.Nullable; 031 032/** 033 * Useful suppliers. 034 * 035 * <p>All methods return serializable suppliers as long as they're given serializable parameters. 036 * 037 * @author Laurence Gonsalves 038 * @author Harry Heymann 039 * @since 2.0 040 */ 041@GwtCompatible(emulated = true) 042@ElementTypesAreNonnullByDefault 043public final class Suppliers { 044 private Suppliers() {} 045 046 /** 047 * Returns a new supplier which is the composition of the provided function and supplier. In other 048 * words, the new supplier's value will be computed by retrieving the value from {@code supplier}, 049 * and then applying {@code function} to that value. Note that the resulting supplier will not 050 * call {@code supplier} or invoke {@code function} until it is called. 051 */ 052 public static <F extends @Nullable Object, T extends @Nullable Object> Supplier<T> compose( 053 Function<? super F, T> function, Supplier<F> supplier) { 054 return new SupplierComposition<>(function, supplier); 055 } 056 057 private static class SupplierComposition<F extends @Nullable Object, T extends @Nullable Object> 058 implements Supplier<T>, Serializable { 059 final Function<? super F, T> function; 060 final Supplier<F> supplier; 061 062 SupplierComposition(Function<? super F, T> function, Supplier<F> supplier) { 063 this.function = checkNotNull(function); 064 this.supplier = checkNotNull(supplier); 065 } 066 067 @Override 068 @ParametricNullness 069 public T get() { 070 return function.apply(supplier.get()); 071 } 072 073 @Override 074 public boolean equals(@CheckForNull Object obj) { 075 if (obj instanceof SupplierComposition) { 076 SupplierComposition<?, ?> that = (SupplierComposition<?, ?>) obj; 077 return function.equals(that.function) && supplier.equals(that.supplier); 078 } 079 return false; 080 } 081 082 @Override 083 public int hashCode() { 084 return Objects.hashCode(function, supplier); 085 } 086 087 @Override 088 public String toString() { 089 return "Suppliers.compose(" + function + ", " + supplier + ")"; 090 } 091 092 private static final long serialVersionUID = 0; 093 } 094 095 /** 096 * Returns a supplier which caches the instance retrieved during the first call to {@code get()} 097 * and returns that value on subsequent calls to {@code get()}. See: <a 098 * href="http://en.wikipedia.org/wiki/Memoization">memoization</a> 099 * 100 * <p>The returned supplier is thread-safe. The delegate's {@code get()} method will be invoked at 101 * most once unless the underlying {@code get()} throws an exception. The supplier's serialized 102 * form does not contain the cached value, which will be recalculated when {@code get()} is called 103 * on the deserialized instance. 104 * 105 * <p>When the underlying delegate throws an exception then this memoizing supplier will keep 106 * delegating calls until it returns valid data. 107 * 108 * <p>If {@code delegate} is an instance created by an earlier call to {@code memoize}, it is 109 * returned directly. 110 */ 111 public static <T extends @Nullable Object> Supplier<T> memoize(Supplier<T> delegate) { 112 if (delegate instanceof NonSerializableMemoizingSupplier 113 || delegate instanceof MemoizingSupplier) { 114 return delegate; 115 } 116 return delegate instanceof Serializable 117 ? new MemoizingSupplier<T>(delegate) 118 : new NonSerializableMemoizingSupplier<T>(delegate); 119 } 120 121 @VisibleForTesting 122 static class MemoizingSupplier<T extends @Nullable Object> implements Supplier<T>, Serializable { 123 private final Object lock = 124 new Integer(1); // something serializable 125 126 final Supplier<T> delegate; 127 transient volatile boolean initialized; 128 // "value" does not need to be volatile; visibility piggy-backs 129 // on volatile read of "initialized". 130 @CheckForNull transient T value; 131 132 MemoizingSupplier(Supplier<T> delegate) { 133 this.delegate = checkNotNull(delegate); 134 } 135 136 @Override 137 @ParametricNullness 138 public T get() { 139 // A 2-field variant of Double Checked Locking. 140 if (!initialized) { 141 synchronized (lock) { 142 if (!initialized) { 143 T t = delegate.get(); 144 value = t; 145 initialized = true; 146 return t; 147 } 148 } 149 } 150 // This is safe because we checked `initialized`. 151 return uncheckedCastNullableTToT(value); 152 } 153 154 @Override 155 public String toString() { 156 return "Suppliers.memoize(" 157 + (initialized ? "<supplier that returned " + value + ">" : delegate) 158 + ")"; 159 } 160 161 private static final long serialVersionUID = 0; 162 } 163 164 @VisibleForTesting 165 static class NonSerializableMemoizingSupplier<T extends @Nullable Object> implements Supplier<T> { 166 private final Object lock = new Object(); 167 168 @SuppressWarnings("UnnecessaryLambda") // Must be a fixed singleton object 169 private static final Supplier<Void> SUCCESSFULLY_COMPUTED = 170 () -> { 171 throw new IllegalStateException(); // Should never get called. 172 }; 173 174 private volatile Supplier<T> delegate; 175 // "value" does not need to be volatile; visibility piggy-backs on volatile read of "delegate". 176 @CheckForNull private T value; 177 178 NonSerializableMemoizingSupplier(Supplier<T> delegate) { 179 this.delegate = checkNotNull(delegate); 180 } 181 182 @Override 183 @ParametricNullness 184 @SuppressWarnings("unchecked") // Cast from Supplier<Void> to Supplier<T> is always valid 185 public T get() { 186 // Because Supplier is read-heavy, we use the "double-checked locking" pattern. 187 if (delegate != SUCCESSFULLY_COMPUTED) { 188 synchronized (lock) { 189 if (delegate != SUCCESSFULLY_COMPUTED) { 190 T t = delegate.get(); 191 value = t; 192 delegate = (Supplier<T>) SUCCESSFULLY_COMPUTED; 193 return t; 194 } 195 } 196 } 197 // This is safe because we checked `delegate`. 198 return uncheckedCastNullableTToT(value); 199 } 200 201 @Override 202 public String toString() { 203 Supplier<T> delegate = this.delegate; 204 return "Suppliers.memoize(" 205 + (delegate == SUCCESSFULLY_COMPUTED 206 ? "<supplier that returned " + value + ">" 207 : delegate) 208 + ")"; 209 } 210 } 211 212 /** 213 * Returns a supplier that caches the instance supplied by the delegate and removes the cached 214 * value after the specified time has passed. Subsequent calls to {@code get()} return the cached 215 * value if the expiration time has not passed. After the expiration time, a new value is 216 * retrieved, cached, and returned. See: <a 217 * href="http://en.wikipedia.org/wiki/Memoization">memoization</a> 218 * 219 * <p>The returned supplier is thread-safe. The supplier's serialized form does not contain the 220 * cached value, which will be recalculated when {@code get()} is called on the reserialized 221 * instance. The actual memoization does not happen when the underlying delegate throws an 222 * exception. 223 * 224 * <p>When the underlying delegate throws an exception then this memoizing supplier will keep 225 * delegating calls until it returns valid data. 226 * 227 * @param duration the length of time after a value is created that it should stop being returned 228 * by subsequent {@code get()} calls 229 * @param unit the unit that {@code duration} is expressed in 230 * @throws IllegalArgumentException if {@code duration} is not positive 231 * @since 2.0 232 */ 233 @SuppressWarnings("GoodTime") // Prefer the Duration overload 234 public static <T extends @Nullable Object> Supplier<T> memoizeWithExpiration( 235 Supplier<T> delegate, long duration, TimeUnit unit) { 236 checkNotNull(delegate); 237 checkArgument(duration > 0, "duration (%s %s) must be > 0", duration, unit); 238 return new ExpiringMemoizingSupplier<>(delegate, unit.toNanos(duration)); 239 } 240 241 /** 242 * Returns a supplier that caches the instance supplied by the delegate and removes the cached 243 * value after the specified time has passed. Subsequent calls to {@code get()} return the cached 244 * value if the expiration time has not passed. After the expiration time, a new value is 245 * retrieved, cached, and returned. See: <a 246 * href="http://en.wikipedia.org/wiki/Memoization">memoization</a> 247 * 248 * <p>The returned supplier is thread-safe. The supplier's serialized form does not contain the 249 * cached value, which will be recalculated when {@code get()} is called on the reserialized 250 * instance. The actual memoization does not happen when the underlying delegate throws an 251 * exception. 252 * 253 * <p>When the underlying delegate throws an exception then this memoizing supplier will keep 254 * delegating calls until it returns valid data. 255 * 256 * @param duration the length of time after a value is created that it should stop being returned 257 * by subsequent {@code get()} calls 258 * @throws IllegalArgumentException if {@code duration} is not positive 259 * @since 33.1.0 260 */ 261 @J2ktIncompatible 262 @GwtIncompatible // java.time.Duration 263 @SuppressWarnings("Java7ApiChecker") // no more dangerous that wherever the user got the Duration 264 @IgnoreJRERequirement 265 public static <T extends @Nullable Object> Supplier<T> memoizeWithExpiration( 266 Supplier<T> delegate, Duration duration) { 267 checkNotNull(delegate); 268 // The alternative of `duration.compareTo(Duration.ZERO) > 0` causes J2ObjC trouble. 269 checkArgument( 270 !duration.isNegative() && !duration.isZero(), "duration (%s) must be > 0", duration); 271 return new ExpiringMemoizingSupplier<>(delegate, toNanosSaturated(duration)); 272 } 273 274 @VisibleForTesting 275 @SuppressWarnings("GoodTime") // lots of violations 276 static class ExpiringMemoizingSupplier<T extends @Nullable Object> 277 implements Supplier<T>, Serializable { 278 private final Object lock = 279 new Integer(1); // something serializable 280 281 final Supplier<T> delegate; 282 final long durationNanos; 283 @CheckForNull transient volatile T value; 284 // The special value 0 means "not yet initialized". 285 transient volatile long expirationNanos; 286 287 ExpiringMemoizingSupplier(Supplier<T> delegate, long durationNanos) { 288 this.delegate = delegate; 289 this.durationNanos = durationNanos; 290 } 291 292 @Override 293 @ParametricNullness 294 public T get() { 295 // Another variant of Double Checked Locking. 296 // 297 // We use two volatile reads. We could reduce this to one by 298 // putting our fields into a holder class, but (at least on x86) 299 // the extra memory consumption and indirection are more 300 // expensive than the extra volatile reads. 301 long nanos = expirationNanos; 302 long now = System.nanoTime(); 303 if (nanos == 0 || now - nanos >= 0) { 304 synchronized (lock) { 305 if (nanos == expirationNanos) { // recheck for lost race 306 T t = delegate.get(); 307 value = t; 308 nanos = now + durationNanos; 309 // In the very unlikely event that nanos is 0, set it to 1; 310 // no one will notice 1 ns of tardiness. 311 expirationNanos = (nanos == 0) ? 1 : nanos; 312 return t; 313 } 314 } 315 } 316 // This is safe because we checked `expirationNanos`. 317 return uncheckedCastNullableTToT(value); 318 } 319 320 @Override 321 public String toString() { 322 // This is a little strange if the unit the user provided was not NANOS, 323 // but we don't want to store the unit just for toString 324 return "Suppliers.memoizeWithExpiration(" + delegate + ", " + durationNanos + ", NANOS)"; 325 } 326 327 private static final long serialVersionUID = 0; 328 } 329 330 /** Returns a supplier that always supplies {@code instance}. */ 331 public static <T extends @Nullable Object> Supplier<T> ofInstance( 332 @ParametricNullness T instance) { 333 return new SupplierOfInstance<>(instance); 334 } 335 336 private static class SupplierOfInstance<T extends @Nullable Object> 337 implements Supplier<T>, Serializable { 338 @ParametricNullness final T instance; 339 340 SupplierOfInstance(@ParametricNullness T instance) { 341 this.instance = instance; 342 } 343 344 @Override 345 @ParametricNullness 346 public T get() { 347 return instance; 348 } 349 350 @Override 351 public boolean equals(@CheckForNull Object obj) { 352 if (obj instanceof SupplierOfInstance) { 353 SupplierOfInstance<?> that = (SupplierOfInstance<?>) obj; 354 return Objects.equal(instance, that.instance); 355 } 356 return false; 357 } 358 359 @Override 360 public int hashCode() { 361 return Objects.hashCode(instance); 362 } 363 364 @Override 365 public String toString() { 366 return "Suppliers.ofInstance(" + instance + ")"; 367 } 368 369 private static final long serialVersionUID = 0; 370 } 371 372 /** 373 * Returns a supplier whose {@code get()} method synchronizes on {@code delegate} before calling 374 * it, making it thread-safe. 375 */ 376 @J2ktIncompatible 377 public static <T extends @Nullable Object> Supplier<T> synchronizedSupplier( 378 Supplier<T> delegate) { 379 return new ThreadSafeSupplier<>(delegate); 380 } 381 382 @J2ktIncompatible 383 private static class ThreadSafeSupplier<T extends @Nullable Object> 384 implements Supplier<T>, Serializable { 385 final Supplier<T> delegate; 386 387 ThreadSafeSupplier(Supplier<T> delegate) { 388 this.delegate = checkNotNull(delegate); 389 } 390 391 @Override 392 @ParametricNullness 393 public T get() { 394 synchronized (delegate) { 395 return delegate.get(); 396 } 397 } 398 399 @Override 400 public String toString() { 401 return "Suppliers.synchronizedSupplier(" + delegate + ")"; 402 } 403 404 private static final long serialVersionUID = 0; 405 } 406 407 /** 408 * Returns a function that accepts a supplier and returns the result of invoking {@link 409 * Supplier#get} on that supplier. 410 * 411 * <p><b>Java 8+ users:</b> use the method reference {@code Supplier::get} instead. 412 * 413 * @since 8.0 414 */ 415 public static <T extends @Nullable Object> Function<Supplier<T>, T> supplierFunction() { 416 @SuppressWarnings("unchecked") // implementation is "fully variant" 417 SupplierFunction<T> sf = (SupplierFunction<T>) SupplierFunctionImpl.INSTANCE; 418 return sf; 419 } 420 421 private interface SupplierFunction<T extends @Nullable Object> extends Function<Supplier<T>, T> {} 422 423 private enum SupplierFunctionImpl implements SupplierFunction<@Nullable Object> { 424 INSTANCE; 425 426 // Note: This makes T a "pass-through type" 427 @Override 428 @CheckForNull 429 public Object apply(Supplier<@Nullable Object> input) { 430 return input.get(); 431 } 432 433 @Override 434 public String toString() { 435 return "Suppliers.supplierFunction()"; 436 } 437 } 438}