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}