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