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