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}