Coverage Summary for Class: Suppliers (com.google.common.base)

Class Method, % Line, %
Suppliers 0% (0/7) 0% (0/12)
Suppliers$ExpiringMemoizingSupplier 0% (0/3) 0% (0/17)
Suppliers$MemoizingSupplier 0% (0/3) 0% (0/13)
Suppliers$NonSerializableMemoizingSupplier 0% (0/3) 0% (0/15)
Suppliers$SupplierComposition 0% (0/5) 0% (0/10)
Suppliers$SupplierFunctionImpl 0% (0/3) 0% (0/4)
Suppliers$SupplierOfInstance 0% (0/5) 0% (0/9)
Suppliers$ThreadSafeSupplier 0% (0/3) 0% (0/6)
Total 0% (0/32) 0% (0/86)


1 /* 2  * Copyright (C) 2007 The Guava Authors 3  * 4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5  * in compliance with the License. You may obtain a copy of the License at 6  * 7  * http://www.apache.org/licenses/LICENSE-2.0 8  * 9  * Unless required by applicable law or agreed to in writing, software distributed under the License 10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11  * or implied. See the License for the specific language governing permissions and limitations under 12  * the License. 13  */ 14  15 package com.google.common.base; 16  17 import static com.google.common.base.Preconditions.checkArgument; 18 import static com.google.common.base.Preconditions.checkNotNull; 19  20 import com.google.common.annotations.GwtCompatible; 21 import com.google.common.annotations.VisibleForTesting; 22 import java.io.Serializable; 23 import java.util.concurrent.TimeUnit; 24 import org.checkerframework.checker.nullness.qual.Nullable; 25  26 /** 27  * Useful suppliers. 28  * 29  * <p>All methods return serializable suppliers as long as they're given serializable parameters. 30  * 31  * @author Laurence Gonsalves 32  * @author Harry Heymann 33  * @since 2.0 34  */ 35 @GwtCompatible 36 public final class Suppliers { 37  private Suppliers() {} 38  39  /** 40  * Returns a new supplier which is the composition of the provided function and supplier. In other 41  * words, the new supplier's value will be computed by retrieving the value from {@code supplier}, 42  * and then applying {@code function} to that value. Note that the resulting supplier will not 43  * call {@code supplier} or invoke {@code function} until it is called. 44  */ 45  public static <F, T> Supplier<T> compose(Function<? super F, T> function, Supplier<F> supplier) { 46  return new SupplierComposition<>(function, supplier); 47  } 48  49  private static class SupplierComposition<F, T> implements Supplier<T>, Serializable { 50  final Function<? super F, T> function; 51  final Supplier<F> supplier; 52  53  SupplierComposition(Function<? super F, T> function, Supplier<F> supplier) { 54  this.function = checkNotNull(function); 55  this.supplier = checkNotNull(supplier); 56  } 57  58  @Override 59  public T get() { 60  return function.apply(supplier.get()); 61  } 62  63  @Override 64  public boolean equals(@Nullable Object obj) { 65  if (obj instanceof SupplierComposition) { 66  SupplierComposition<?, ?> that = (SupplierComposition<?, ?>) obj; 67  return function.equals(that.function) && supplier.equals(that.supplier); 68  } 69  return false; 70  } 71  72  @Override 73  public int hashCode() { 74  return Objects.hashCode(function, supplier); 75  } 76  77  @Override 78  public String toString() { 79  return "Suppliers.compose(" + function + ", " + supplier + ")"; 80  } 81  82  private static final long serialVersionUID = 0; 83  } 84  85  /** 86  * Returns a supplier which caches the instance retrieved during the first call to {@code get()} 87  * and returns that value on subsequent calls to {@code get()}. See: <a 88  * href="http://en.wikipedia.org/wiki/Memoization">memoization</a> 89  * 90  * <p>The returned supplier is thread-safe. The delegate's {@code get()} method will be invoked at 91  * most once unless the underlying {@code get()} throws an exception. The supplier's serialized 92  * form does not contain the cached value, which will be recalculated when {@code get()} is called 93  * on the reserialized instance. 94  * 95  * <p>When the underlying delegate throws an exception then this memoizing supplier will keep 96  * delegating calls until it returns valid data. 97  * 98  * <p>If {@code delegate} is an instance created by an earlier call to {@code memoize}, it is 99  * 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  transient @Nullable 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  @Nullable 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  transient volatile @Nullable 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(@Nullable T instance) { 268  return new SupplierOfInstance<T>(instance); 269  } 270  271  private static class SupplierOfInstance<T> implements Supplier<T>, Serializable { 272  final @Nullable T instance; 273  274  SupplierOfInstance(@Nullable 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(@Nullable 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 }