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 javax.annotation.Nullable; 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<F, T>(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(@Nullable 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. The supplier's serialized form does not contain the cached value, which will be 091 * recalculated when {@code get()} is called on the reserialized instance. 092 * 093 * <p>If {@code delegate} is an instance created by an earlier call to {@code memoize}, it is 094 * returned directly. 095 */ 096 public static <T> Supplier<T> memoize(Supplier<T> delegate) { 097 if (delegate instanceof NonSerializableMemoizingSupplier 098 || delegate instanceof MemoizingSupplier) { 099 return delegate; 100 } 101 return delegate instanceof Serializable 102 ? new MemoizingSupplier<T>(delegate) 103 : new NonSerializableMemoizingSupplier<T>(delegate); 104 } 105 106 @VisibleForTesting 107 static class MemoizingSupplier<T> implements Supplier<T>, Serializable { 108 final Supplier<T> delegate; 109 transient volatile boolean initialized; 110 // "value" does not need to be volatile; visibility piggy-backs 111 // on volatile read of "initialized". 112 transient T value; 113 114 MemoizingSupplier(Supplier<T> delegate) { 115 this.delegate = Preconditions.checkNotNull(delegate); 116 } 117 118 @Override 119 public T get() { 120 // A 2-field variant of Double Checked Locking. 121 if (!initialized) { 122 synchronized (this) { 123 if (!initialized) { 124 T t = delegate.get(); 125 value = t; 126 initialized = true; 127 return t; 128 } 129 } 130 } 131 return value; 132 } 133 134 @Override 135 public String toString() { 136 return "Suppliers.memoize(" + delegate + ")"; 137 } 138 139 private static final long serialVersionUID = 0; 140 } 141 142 @VisibleForTesting 143 static class NonSerializableMemoizingSupplier<T> implements Supplier<T> { 144 volatile Supplier<T> delegate; 145 volatile boolean initialized; 146 // "value" does not need to be volatile; visibility piggy-backs 147 // on volatile read of "initialized". 148 T value; 149 150 NonSerializableMemoizingSupplier(Supplier<T> delegate) { 151 this.delegate = Preconditions.checkNotNull(delegate); 152 } 153 154 @Override 155 public T get() { 156 // A 2-field variant of Double Checked Locking. 157 if (!initialized) { 158 synchronized (this) { 159 if (!initialized) { 160 T t = delegate.get(); 161 value = t; 162 initialized = true; 163 // Release the delegate to GC. 164 delegate = null; 165 return t; 166 } 167 } 168 } 169 return value; 170 } 171 172 @Override 173 public String toString() { 174 return "Suppliers.memoize(" + delegate + ")"; 175 } 176 } 177 178 /** 179 * Returns a supplier that caches the instance supplied by the delegate and removes the cached 180 * value after the specified time has passed. Subsequent calls to {@code get()} return the cached 181 * value if the expiration time has not passed. After the expiration time, a new value is 182 * retrieved, cached, and returned. See: 183 * <a href="http://en.wikipedia.org/wiki/Memoization">memoization</a> 184 * 185 * <p>The returned supplier is thread-safe. The supplier's serialized form does not contain the 186 * cached value, which will be recalculated when {@code 187 * get()} is called on the reserialized instance. 188 * 189 * @param duration the length of time after a value is created that it should stop being returned 190 * by subsequent {@code get()} calls 191 * @param unit the unit that {@code duration} is expressed in 192 * @throws IllegalArgumentException if {@code duration} is not positive 193 * @since 2.0 194 */ 195 public static <T> Supplier<T> memoizeWithExpiration( 196 Supplier<T> delegate, long duration, TimeUnit unit) { 197 return new ExpiringMemoizingSupplier<T>(delegate, duration, unit); 198 } 199 200 @VisibleForTesting 201 static class ExpiringMemoizingSupplier<T> implements Supplier<T>, Serializable { 202 final Supplier<T> delegate; 203 final long durationNanos; 204 transient volatile T value; 205 // The special value 0 means "not yet initialized". 206 transient volatile long expirationNanos; 207 208 ExpiringMemoizingSupplier(Supplier<T> delegate, long duration, TimeUnit unit) { 209 this.delegate = Preconditions.checkNotNull(delegate); 210 this.durationNanos = unit.toNanos(duration); 211 Preconditions.checkArgument(duration > 0); 212 } 213 214 @Override 215 public T get() { 216 // Another variant of Double Checked Locking. 217 // 218 // We use two volatile reads. We could reduce this to one by 219 // putting our fields into a holder class, but (at least on x86) 220 // the extra memory consumption and indirection are more 221 // expensive than the extra volatile reads. 222 long nanos = expirationNanos; 223 long now = Platform.systemNanoTime(); 224 if (nanos == 0 || now - nanos >= 0) { 225 synchronized (this) { 226 if (nanos == expirationNanos) { // recheck for lost race 227 T t = delegate.get(); 228 value = t; 229 nanos = now + durationNanos; 230 // In the very unlikely event that nanos is 0, set it to 1; 231 // no one will notice 1 ns of tardiness. 232 expirationNanos = (nanos == 0) ? 1 : nanos; 233 return t; 234 } 235 } 236 } 237 return value; 238 } 239 240 @Override 241 public String toString() { 242 // This is a little strange if the unit the user provided was not NANOS, 243 // but we don't want to store the unit just for toString 244 return "Suppliers.memoizeWithExpiration(" + delegate + ", " + durationNanos + ", NANOS)"; 245 } 246 247 private static final long serialVersionUID = 0; 248 } 249 250 /** 251 * Returns a supplier that always supplies {@code instance}. 252 */ 253 public static <T> Supplier<T> ofInstance(@Nullable T instance) { 254 return new SupplierOfInstance<T>(instance); 255 } 256 257 private static class SupplierOfInstance<T> implements Supplier<T>, Serializable { 258 final T instance; 259 260 SupplierOfInstance(@Nullable T instance) { 261 this.instance = instance; 262 } 263 264 @Override 265 public T get() { 266 return instance; 267 } 268 269 @Override 270 public boolean equals(@Nullable Object obj) { 271 if (obj instanceof SupplierOfInstance) { 272 SupplierOfInstance<?> that = (SupplierOfInstance<?>) obj; 273 return Objects.equal(instance, that.instance); 274 } 275 return false; 276 } 277 278 @Override 279 public int hashCode() { 280 return Objects.hashCode(instance); 281 } 282 283 @Override 284 public String toString() { 285 return "Suppliers.ofInstance(" + instance + ")"; 286 } 287 288 private static final long serialVersionUID = 0; 289 } 290 291 /** 292 * Returns a supplier whose {@code get()} method synchronizes on {@code delegate} before calling 293 * it, making it thread-safe. 294 */ 295 public static <T> Supplier<T> synchronizedSupplier(Supplier<T> delegate) { 296 return new ThreadSafeSupplier<T>(Preconditions.checkNotNull(delegate)); 297 } 298 299 private static class ThreadSafeSupplier<T> implements Supplier<T>, Serializable { 300 final Supplier<T> delegate; 301 302 ThreadSafeSupplier(Supplier<T> delegate) { 303 this.delegate = delegate; 304 } 305 306 @Override 307 public T get() { 308 synchronized (delegate) { 309 return delegate.get(); 310 } 311 } 312 313 @Override 314 public String toString() { 315 return "Suppliers.synchronizedSupplier(" + delegate + ")"; 316 } 317 318 private static final long serialVersionUID = 0; 319 } 320 321 /** 322 * Returns a function that accepts a supplier and returns the result of invoking {@link 323 * Supplier#get} on that supplier. 324 * 325 * <p><b>Java 8 users:</b> use the method reference {@code Supplier::get} instead. 326 * 327 * @since 8.0 328 */ 329 public static <T> Function<Supplier<T>, T> supplierFunction() { 330 @SuppressWarnings("unchecked") // implementation is "fully variant" 331 SupplierFunction<T> sf = (SupplierFunction<T>) SupplierFunctionImpl.INSTANCE; 332 return sf; 333 } 334 335 private interface SupplierFunction<T> extends Function<Supplier<T>, T> {} 336 337 private enum SupplierFunctionImpl implements SupplierFunction<Object> { 338 INSTANCE; 339 340 // Note: This makes T a "pass-through type" 341 @Override 342 public Object apply(Supplier<Object> input) { 343 return input.get(); 344 } 345 346 @Override 347 public String toString() { 348 return "Suppliers.supplierFunction()"; 349 } 350 } 351}