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}