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