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